/// <summary> /// 默认生成该物体及组件和子物体及组件的字段,属性,初始化。 /// </summary> /// <param name="gameObject"></param> protected virtual void genGameObject(GameObject gameObject) { string fieldName; if (gameObject == listOrigin) { fieldName = FIELD_NAME_ORIGIN; } else { fieldName = genFieldName4GO(gameObject); } //字段 addTypeUsing(typeof(GameObject)); var field = genField(typeof(GameObject), fieldName); //常量 var constField = genField("const string", "PATH" + field.Name.ToUpper(), false); constField.InitExpression = Codo.String(rootGameObject.transform.getChildPath(gameObject.transform)); //属性 string propName = field.Name; while (propName.StartsWith("_")) { propName = propName.Substring(1, propName.Length - 1); } propName = propName.headToLower(); genProp4GO(gameObject, propName, field.Name); //初始化 addTypeUsing(typeof(TransformHelper)); _initMethod.Statements.append(Codo.This.getField(field.Name).assign(Codo.This.getProp(NAME_OF_TRANSFORM) .getMethod(NAME_OF_FIND).invoke(Codo.getField("PATH" + field.Name.ToUpper())) .getProp(NAME_OF_GAMEOBJECT))); }
/// <summary> /// 生成动画参数对应的常量 /// </summary> /// <param name="animator"></param> /// <param name="field"></param> /// <param name="prop"></param> private void onGenAnimator(Animator animator, CodeMemberField field, CodeMemberProperty prop) { AnimatorController controller = animator.runtimeAnimatorController as AnimatorController; foreach (var parameter in controller.parameters) { string fieldName = "ANIM_PARAM_"; string animatorName = prop.Name; if (animatorName.EndsWith("Animator", StringComparison.OrdinalIgnoreCase)) { animatorName = animatorName.Substring(0, animatorName.Length - 8); } if (animatorName.StartsWith("_")) { animatorName = animatorName.Substring(1, animatorName.Length - 1); } if (!(animatorName.StartsWith("as") && char.IsUpper(animatorName[2]))) { fieldName += animatorName.ToUpper() + "_"; } fieldName += parameter.name.ToUpper(); CodeMemberField Const = genField("const string", fieldName, false); Const.InitExpression = Codo.String(parameter.name); } }
public override void onGen(AutoCompoGenerator generator, Animator component, bool isRootComponent, AutoBindFieldInfo info, CodeMemberField field) { AnimatorController controller = component.runtimeAnimatorController as AnimatorController; foreach (var parameter in controller.parameters) { string fieldName = "ANIM_PARAM_"; string animatorName = generator.genPropName4Field(field.Name); if (animatorName.EndsWith("Animator", StringComparison.OrdinalIgnoreCase)) { animatorName = animatorName.Substring(0, animatorName.Length - 8); } if (animatorName.StartsWith("_")) { animatorName = animatorName.Substring(1, animatorName.Length - 1); } if (!(animatorName.StartsWith("as") && char.IsUpper(animatorName[2]))) { fieldName += animatorName.ToUpper() + "_"; } fieldName += parameter.name.ToUpper(); CodeMemberField Const = generator.genField("const string", fieldName, false); Const.InitExpression = Codo.String(parameter.name); } }
/// <summary> /// /// </summary> /// <param name="component"></param> /// <param name="propName"></param> /// <param name="fieldName">要封装的字段名,供属性引用</param> protected CodeMemberProperty genProp4Compo(Component component, string propName, string fieldName) { CodeMemberProperty prop = genProp(MemberAttributes.Public | MemberAttributes.Final, propName, component.GetType()); prop.HasGet = true; CodeConditionStatement If = Codo.If(Codo.getField(fieldName).op(CodeBinaryOperatorType.IdentityEquality, Codo.Null)); If.TrueStatements.append(Codo.getField(fieldName).assign(Codo.getProp(NAME_OF_TRANSFORM) .getMethod(NAME_OF_FIND).invoke(Codo.getField("PATH" + fieldName.ToUpper())) .getMethod(NAME_OF_GETCOMPO, Codo.type(component.GetType().Name)).invoke())); prop.GetStatements.Add(If); prop.GetStatements.Add(Codo.Return(Codo.getField(fieldName))); return(prop); }
protected virtual void onGenButton(Button button, bool isRootComponent, CodeMemberField field, CodeMemberProperty prop) { CodeAttributeDeclaration autoCompo = field.CustomAttributes.OfType <CodeAttributeDeclaration>() .FirstOrDefault(a => a.AttributeType.BaseType == typeof(AutoCompoAttribute).Name); //是按钮 if (controllerType == CTRL_TYPE_BUTTON && button == buttonMain) { autoCompo.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression("mainButton"))); } string name = prop.Name; name = name.headToUpper(); //事件 CodeMemberEvent Event; if ((controllerType == CTRL_TYPE_BUTTON && button == buttonMain) || isRootComponent) { Event = genEvent(typeof(Action).Name, "onClick", Codo.type(_type.Name)); } else { Event = genEvent(typeof(Action).Name, "on" + name + "Click", Codo.type(_type.Name)); } //回调函数 CodeMemberMethod callbackMethod; if ((controllerType == CTRL_TYPE_BUTTON && button == buttonMain) || isRootComponent) { callbackMethod = genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), "clickCallback"); callbackMethod.Statements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression(Codo.getEvent(Event.Name), CodeBinaryOperatorType.IdentityInequality, Codo.Null), Codo.getEvent(Event.Name).invoke(Codo.This).statement())); } else { callbackMethod = genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), name + "ClickCallback"); callbackMethod.Statements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression(Codo.getEvent(Event.Name), CodeBinaryOperatorType.IdentityInequality, Codo.Null), Codo.getEvent(Event.Name).invoke(Codo.This).statement())); } //注册 _initMethod.Statements.Add(Codo.getField(field.Name).getProp(NAME_OF_ONCLICK) .getMethod(NAME_OF_ADDLISTENER).invoke(Codo.getMethod(callbackMethod.Name)).statement()); //注销 _clearMethod.Statements.Add(Codo.getField(field.Name).getProp(NAME_OF_ONCLICK) .getMethod(NAME_OF_REMOVELISTENER).invoke(Codo.getMethod(callbackMethod.Name)).statement()); }
protected CodeMemberProperty genProp4GO(GameObject gameObject, string propName, string fieldName) { CodeMemberProperty prop = genProp(MemberAttributes.Public | MemberAttributes.Final, propName, typeof(GameObject)); prop.HasGet = true; addTypeUsing(typeof(GameObject)); CodeConditionStatement If = Codo.If(Codo.This.getField(fieldName).op(CodeBinaryOperatorType.IdentityEquality, Codo.Null)); If.TrueStatements.append(Codo.This.getField(fieldName).assign(Codo.This.getProp(NAME_OF_TRANSFORM) .getMethod(NAME_OF_FIND).invoke(Codo.getField("PATH" + fieldName.ToUpper())) .getProp(NAME_OF_GAMEOBJECT))); prop.GetStatements.Add(If); prop.GetStatements.Add(new CodeMethodReturnStatement( new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName))); return(prop); }
protected CodeAttributeDeclaration addAttribute2Field(CodeMemberField field, Object obj, bool withPath, params string[] tags) { CodeAttributeDeclaration autoCompo; if (withPath) { autoCompo = field.CustomAttributes.add(typeof(AutoCompoAttribute).Name, Codo.Int(objFieldDict[obj].instanceId), Codo.String(objFieldDict[obj].path)); } else { autoCompo = field.CustomAttributes.add(typeof(AutoCompoAttribute).Name, Codo.Int(objFieldDict[obj].instanceId)); } foreach (var tag in tags) { autoCompo.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(tag))); } return(autoCompo); }
public override void onGen(AutoCompoGenerator generator, Button component, bool isRootComponent, AutoBindFieldInfo info, CodeMemberField field) { string name = field.Name.Substring(2, field.Name.Length - 2); name = name.headToUpper(); //事件 CodeMemberEvent Event; if (isRootComponent) { Event = generator.genEvent(typeof(Action).Name, "onClick", Codo.type(generator.type.Name)); } else { Event = generator.genEvent(typeof(Action).Name, "on" + name + "Click", Codo.type(generator.type.Name)); } //回调函数 CodeMemberMethod callbackMethod; if (isRootComponent) { callbackMethod = generator.genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), "clickCallback"); callbackMethod.Statements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression(Codo.getEvent(Event.Name), CodeBinaryOperatorType.IdentityInequality, Codo.Null), Codo.getEvent(Event.Name).invoke(Codo.This).statement())); } else { callbackMethod = generator.genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), name + "ClickCallback"); callbackMethod.Statements.Add(new CodeConditionStatement( new CodeBinaryOperatorExpression(Codo.getEvent(Event.Name), CodeBinaryOperatorType.IdentityInequality, Codo.Null), Codo.getEvent(Event.Name).invoke(Codo.This).statement())); } //注册 generator.initMethod.Statements.Add(Codo.getField(field.Name).getProp(AutoCompoGenerator.NAME_OF_ONCLICK) .getMethod(AutoCompoGenerator.NAME_OF_ADDLISTENER).invoke(Codo.getMethod(callbackMethod.Name)).statement()); //注销 generator.clearMethod.Statements.Add(Codo.getField(field.Name).getProp(AutoCompoGenerator.NAME_OF_ONCLICK) .getMethod(AutoCompoGenerator.NAME_OF_REMOVELISTENER).invoke(Codo.getMethod(callbackMethod.Name)).statement()); }
/// <summary> /// 默认生成字段,属性,以及初始化语句(一个常量用于自动查找)。 /// </summary> /// <param name="component"></param> protected virtual void genCompo(Component component, AutoBindFieldInfo fieldInfo) { //字段 var field = genField4Compo(component, genFieldName4Compo(component)); //常量 var constField = genField("const string", "PATH" + field.Name.ToUpper(), false); constField.InitExpression = Codo.String(fieldInfo.path); //属性 var prop = genProp4Compo(component, genPropName4Field(field.Name), field.Name); //初始化 addTypeUsing(typeof(TransformHelper)); _initMethod.Statements.append(Codo.getField(field.Name).assign(Codo.getProp(NAME_OF_TRANSFORM) .getMethod(NAME_OF_FIND).invoke(Codo.getField("PATH" + field.Name.ToUpper())) .getMethod(NAME_OF_GETCOMPO, Codo.type(component.GetType().Name)).invoke())); //特殊组件处理 foreach (var pair in _compoGenDict) { if (pair.Key == component.GetType() || component.GetType().IsSubclassOf(pair.Key)) { pair.Value.onGen(this, component, component.gameObject == rootGameObject, fieldInfo, field); return; } } if (component is Button) { onGenButton(component as Button, component.gameObject == rootGameObject, field, prop); } else if (component is Animator) { onGenAnimator(component as Animator, field, prop); } else if (component is RectTransform && fieldInfo.getValueOrDefault <bool>("isList")) { onGenList(component as RectTransform, field, fieldInfo); } }
public CodeCompileUnit genCtrlUnit(string namespaceName, string typeName, Type mainCtrlType, Type compoType, KeyValuePair <string, Type>[] childCtrlInfos) { CodeCompileUnit unit = new CodeCompileUnit(); //命名空间 CodeNamespace nameSpace = new CodeNamespace(namespaceName); unit.Namespaces.Add(nameSpace); //类型 CodeTypeDeclaration type = new CodeTypeDeclaration(); nameSpace.Types.Add(type); type.Attributes = MemberAttributes.Final; type.IsPartial = true; type.IsClass = true; type.Name = typeName; nameSpace.addTypeUsing(typeof(IController <>)); nameSpace.addTypeUsing(mainCtrlType); type.BaseTypes.Add(Codo.type("IController", Codo.type(mainCtrlType.Name))); //成员 //无参构造器 CodeConstructor constructor = new CodeConstructor(); type.Members.Add(constructor); constructor.Attributes = MemberAttributes.Public; //有参构造器 constructor = new CodeConstructor(); type.Members.Add(constructor); constructor.Attributes = MemberAttributes.Public; nameSpace.addTypeUsing(typeof(IAppManager)); constructor.Parameters.Add(Codo.parameter(typeof(IAppManager).Name, "app")); constructor.Parameters.Add(Codo.parameter(mainCtrlType.Name, "main")); constructor.Parameters.Add(Codo.parameter(compoType.Name, "compo")); constructor.Statements .append(Codo.This.getField("app").assign(Codo.arg("app"))) .append(Codo.This.getField("main").assign(Codo.arg("main"))) .append(Codo.getField("_compo").assign(Codo.arg("compo"))); CodeMemberField mainField = new CodeMemberField(); type.Members.Add(mainField); mainField.Attributes = MemberAttributes.Private | MemberAttributes.Final; mainField.Type = Codo.type(mainCtrlType.Name); mainField.Name = "_main"; CodeMemberProperty mainProp = new CodeMemberProperty(); type.Members.Add(mainProp); mainProp.Attributes = MemberAttributes.Public | MemberAttributes.Final; mainProp.Type = Codo.type(mainCtrlType.Name); mainProp.Name = "main"; mainProp.HasGet = true; mainProp.GetStatements.append(Codo.Return(Codo.getField(mainField.Name))); CodeMemberField appField = new CodeMemberField(); type.Members.Add(appField); appField.Attributes = MemberAttributes.Private | MemberAttributes.Final; appField.Type = Codo.type(typeof(IAppManager).Name); appField.Name = "_app"; CodeMemberProperty appProp = new CodeMemberProperty(); type.Members.Add(appProp); appProp.Attributes = MemberAttributes.Public | MemberAttributes.Final; appProp.Type = Codo.type(typeof(IAppManager).Name); appProp.Name = "app"; appProp.HasGet = true; appProp.GetStatements.append(Codo.Return(Codo.getField(appField.Name))); CodeMemberField compoField = new CodeMemberField(); type.Members.Add(compoField); compoField.Attributes = MemberAttributes.Private | MemberAttributes.Final; compoField.Type = Codo.type(compoType.Name); compoField.Name = "_compo"; //子控制器 foreach (var childCtrlInfo in childCtrlInfos) { string childCtrlPath = childCtrlInfo.Key; Type childCtrlType = childCtrlInfo.Value; CodeMemberField ctrlField = new CodeMemberField(); type.Members.Add(ctrlField); ctrlField.Attributes = MemberAttributes.Private | MemberAttributes.Final; nameSpace.addTypeUsing(childCtrlType); ctrlField.Type = Codo.type(childCtrlType.Name); ctrlField.Name = "_" + childCtrlType.Name.headToLower(); CodeMemberField pathField = new CodeMemberField(); type.Members.Add(pathField); pathField.Attributes = MemberAttributes.Public | MemberAttributes.Final; pathField.Type = Codo.type("const string"); pathField.Name = "PATH_" + childCtrlType.Name.ToUpper(); pathField.InitExpression = Codo.String(childCtrlPath); CodeMemberProperty ctrlProp = new CodeMemberProperty(); type.Members.Add(ctrlProp); ctrlProp.Attributes = MemberAttributes.Public | MemberAttributes.Final; ctrlProp.Type = Codo.type(childCtrlType.Name); ctrlProp.Name = childCtrlType.Name.headToLower(); ctrlProp.HasGet = true; ctrlProp.GetStatements .append(Codo.If(Codo.getField(ctrlField.Name).op(CodeBinaryOperatorType.ValueEquality, Codo.Null)) .appendTrue(Codo.getField(ctrlField.Name).assign(Codo.New(childCtrlType.Name, Codo.getProp("app"), Codo.getProp("main"), Codo.getField("_compo").getProp("transform").getMethod("Find").invoke(Codo.getField(pathField.Name)).getMethod("GetComponent", Codo.type(childCtrlType.Name)).invoke())))) .append(Codo.Return(Codo.getField(ctrlField.Name))); } return(unit); }
/// <summary> /// 默认生成init和clear方法。 /// </summary> protected virtual void genMembers() { _initMethod = genMethod(MemberAttributes.Public | MemberAttributes.Final, typeof(void), getInitMethodName()); _clearMethod = genMethod(MemberAttributes.Public | MemberAttributes.Final, typeof(void), getClearMethodName()); if (controllerType == CTRL_TYPE_LIST || controllerType == CTRL_TYPE_BUTTON_LIST) { //ItemPool类型 CodeTypeDeclaration itemPoolType = new CodeTypeDeclaration(); _type.Members.Add(itemPoolType); itemPoolType.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute).Name)); itemPoolType.Attributes = MemberAttributes.Public | MemberAttributes.Final; itemPoolType.IsClass = true; itemPoolType.Name = "ItemPool"; //itemPoolType.BaseTypes.Add(new CodeTypeReference(typeof(ComponentPool<>).Name, new CodeTypeReference(listItemTypeName))); //构造器 CodeConstructor itemPoolTypeConstructor = new CodeConstructor(); itemPoolType.Members.Add(itemPoolTypeConstructor); itemPoolTypeConstructor.Attributes = MemberAttributes.Public | MemberAttributes.Final; itemPoolTypeConstructor.Parameters .append(typeof(Transform).Name, "root") .append(listItemTypeName, "origin"); itemPoolTypeConstructor.BaseConstructorArgs .appendArg("root") .appendArg("origin"); //ItemPool字段 CodeMemberField itemPool = genField(itemPoolType.Name, FIELD_NAME_ITEM_POOL, false); itemPool.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializeField).Name)); //onItemClick事件 CodeMemberEvent onItemClick = null; if (controllerType == CTRL_TYPE_BUTTON_LIST) { onItemClick = genEvent(typeof(Action).Name, "onItemClick", Codo.type(listItemTypeName)); } //itemClickCallback方法 CodeMemberMethod itemClickCallback = null; if (controllerType == CTRL_TYPE_BUTTON_LIST) { itemClickCallback = genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), "itemClickCallback"); itemClickCallback.Parameters.append(listItemTypeName, "item"); itemClickCallback.Statements.append(new CodeConditionStatement( Codo.op(Codo.This.getEvent(onItemClick.Name), CodeBinaryOperatorType.IdentityInequality, Codo.Null), Codo.This.getEvent(onItemClick.Name).invoke(Codo.arg("item")).statement())); } //onItemCreate方法 if (controllerType == CTRL_TYPE_BUTTON_LIST) { genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), "onItemCreate") .appendParam(listItemTypeName, "item") .appendStatement(Codo.arg("item").getMethod("autoReg").invoke()) .appendStatement(Codo.arg("item").getEvent("onClick").attach(Codo.This.getMethod(itemClickCallback.Name))); } else { genPartialMethod("void", "onItemCreate", Codo.parameter(listItemTypeName, "item")); } //onItemRemove方法 if (controllerType == CTRL_TYPE_BUTTON_LIST) { genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), "onItemRemove") .appendParam(listItemTypeName, "item") .appendStatement(Codo.arg("item").getMethod("autoUnreg").invoke()) .appendStatement(Codo.arg("item").getEvent("onClick").remove(Codo.This.getMethod(itemClickCallback.Name))); } else { genPartialMethod("void", "onItemRemove", Codo.parameter(listItemTypeName, "item")); } //initPool方法 var initPool = genMethod(MemberAttributes.Private | MemberAttributes.Final, typeof(void), METHOD_NAME_LIST_INIT_POOL); _initMethod.Statements.Add(Codo.This.getMethod(initPool.Name).invoke().statement()); const string VAR_NAME_ITEM = "item"; initPool.Statements.append(Codo.decVar(listItemTypeName, VAR_NAME_ITEM, string.IsNullOrEmpty(listItemTypeName) ?//有无指定脚本类型? Codo.This.getField(FIELD_NAME_ORIGIN) as CodeExpression : Codo.This.getField(FIELD_NAME_ORIGIN).getMethod(NAME_OF_ADDCOMPO, Codo.type(listItemTypeName)).invoke())); initPool.Statements.Add(Codo.This.getField(FIELD_NAME_ORIGIN).getProp(NAME_OF_GAMEOBJECT).getMethod(NAME_OF_SET_ACTIVE).invoke(Codo.False)); initPool.Statements.Add(Codo.assign(Codo.This.getField(itemPool.Name), Codo.New(itemPoolType.Name, Codo.This.getProp("transform"), Codo.Var(VAR_NAME_ITEM)))); initPool.Statements.Add(Codo.This.getField(itemPool.Name).getEvent("onCreate").attach(Codo.This.getMethod("onItemCreate"))); initPool.Statements.Add(Codo.This.getField(itemPool.Name).getEvent("onRemove").attach(Codo.This.getMethod("onItemRemove"))); //setCount方法 CodeMemberMethod setCount = genMethod(MemberAttributes.Public | MemberAttributes.Final, typeof(void), "setCount"); setCount.Parameters.append(typeof(int), "count"); setCount.Statements.Add(Codo.This.getField(itemPool.Name).getMethod("setCount").invoke(Codo.arg("count"))); //indexer CodeMemberProperty indexer = genIndexer(Codo.type(listItemTypeName)); indexer.Parameters.append(typeof(int), "index"); indexer.HasGet = true; indexer.GetStatements.Add(Codo.Return(Codo.This.getField(itemPool.Name).index(Codo.arg("index")))); //indexOf方法 CodeMemberMethod indexOf = genMethod(MemberAttributes.Public | MemberAttributes.Final, typeof(int), "indexOf"); indexOf.Parameters.append(listItemTypeName, "item"); indexOf.Statements.append(Codo.Return(Codo.This.getField(itemPool.Name).getMethod("indexOf").invoke(Codo.arg("item")))); } }