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")))); } }