static void GeneratePolymorphicRootSupport()
        {
            foreach (var polymorphicRootNode in polymorphicRootNodes)
            {
                var node  = polymorphicRootNode.Key;
                var types = polymorphicRootNode.Value
                            .Where(t => t.IsValidType())
                            .Where(t => t.IsAbstract == false);
                var nodeClass = GenClassSink(node);
                var enumName  = node.PolymorphicRootTypeEnumName();

                var module = nodeClass.module;
                module.content("");
                if (!string.IsNullOrEmpty(nodeClass.namespaceName))
                {
                    module.content($"namespace {nodeClass.namespaceName} {{");
                    module.indent++;
                }

                EnumTable.PrintEnum(module, enumName, types.Select(t => t.UniqueName(false)),
                                    type => finalTypeEnum[baseClassMap[node]][type]);
                if (!string.IsNullOrEmpty(nodeClass.namespaceName))
                {
                    module.indent--;
                    module.content($"}}");
                }

                module.content("");
            }

            GeneratePolymorphicCreatorFuncs();
        }
Пример #2
0
        public static EnumTable Load(string fileName)
        {
            try
            {
                var table = new EnumTable();
                using (TextReader reader = File.OpenText(fileName))
                {
                    string line = null;
                    while ((line = reader.ReadLine()) != null)
                    {
                        var record = line.Split(' ');
                        table.records.Add(record[0], int.Parse(record[1]));
                    }
                }

                return(table);
            }
            catch (Exception e)
            {
                Debug.Log("loading type table exception");
                Debug.Log(e);
            }

            return(new EnumTable());
        }
        static void GeneratePolimorphismSupport()
        {
            foreach (var polymorphTask in polymorphicMap)
            {
                var baseClass = polymorphTask.Key;
                var children  = polymorphTask.Value;
                var sink      = GenClassSink(baseClass);

                var typesToGenPolymorphMethods = new List <Type> {
                    baseClass
                }.Concat(children).ToList();
                var typesThatCanBeConstructed = typesToGenPolymorphMethods.Where(t => t.IsValidType()).ToList();

                var fileName = baseClass.TypeTableFileName();

                var typeTable  = EnumTable.Load(fileName);
                var validTypes = typesThatCanBeConstructed.Where(t => t.IsAbstract == false && t.IsValidType())
                                 .ToList();
                typeTable.UpdateWithNewTypes(validTypes.Select(t => t.UniqueName(false)));
                finalTypeEnum[baseClass] = typeTable.records;

                var finalTypeIndexedList = new List <Type>();
                foreach (var type in validTypes)
                {
                    var index = typeTable.records[type.UniqueName(false)];
                    finalTypeIndexedList.EnsureSizeWithNulls(index + 1);
                    finalTypeIndexedList[index] = type;
                }

                EnumTable.PrintEnum(sink, TypeEnumName, typesThatCanBeConstructed.Where(t => t.IsValidType())
                                    .Where(t => t.IsAbstract == false).Select(t => t.UniqueName(false)),
                                    type => typeTable.records[type]);

                GenClassIdFuncs(baseClass, typesToGenPolymorphMethods, sink);

                if (baseClass.NeedsPooledPolymorphConstruction())
                {
                    GenPolymorphicRootSetup(baseClass, sink, finalTypeIndexedList, true);
                    GenPolymorphMaps(baseClass, typesThatCanBeConstructed, typesToGenPolymorphMethods, sink, true);
                }

                if (baseClass.NeedsClassicPolymorphConstruction() ||
                    (!baseClass.HasPool() && (baseClass.ReadGenFlags()
                                              & (GenTaskFlags.UpdateFrom | GenTaskFlags.Serialization)) != 0))
                {
                    GenPolymorphicRootSetup(baseClass, sink, finalTypeIndexedList, false);
                    GenPolymorphMaps(baseClass, typesThatCanBeConstructed, typesToGenPolymorphMethods, sink, false);
                }
            }
        }
Пример #4
0
 public static void Save(string fileName, EnumTable table)
 {
     try
     {
         //File.Create(fileName).WriteByte(1);
         var list = table.records.ToList();
         list.Sort((p1, p2) => p1.Value.CompareTo(p2.Value));
         using (TextWriter writer = File.CreateText(fileName))
         {
             foreach (var record in list)
             {
                 writer.WriteLine($"{record.Key} {record.Value}");
             }
         }
     }
     catch (Exception e)
     {
         Debug.LogError("saving type table exception");
         Debug.LogError(e);
     }
 }
Пример #5
0
        // You shall not dare to try to unfuck this.
        public static void Gen(bool stubs)
        {
            if (EditorApplication.isCompiling)
            {
                Debug.LogError("Application is compiling codegen run is not recomended");
                return;
            }

            EditorUtility.DisplayProgressBar("Running codegen", "creating tasks", 0);

            var genDir = new DirectoryInfo(GenPath);

            var typesEnumerable =
                from assembly in AppDomain.CurrentDomain.GetAssemblies()
                from t in assembly.GetTypes()
                select t;

            allTypesInAssemblies.AddRange(typesEnumerable.ToList());

            typeGenRequested.Clear();
            tasks.Clear();
            genericInstances.Clear();
            polymorphicMap.Clear();
            baseClassMap.Clear();
            extensionsSignaturesGenerated.Clear();
            classes.Clear();
            parents.Clear();
            hasErrors = false;

            stubMode = stubs;
            context  = new GeneratorContext(new GenInfo {
                sharpGenPath = GenPath
            }, stubMode);
            clientOnlyContext = new GeneratorContext(new GenInfo {
                sharpGenPath = GenPathClient
            }, stubMode);

            foreach (var type in allTypesInAssemblies)
            {
                foreach (var methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    if (methodInfo.HasAttribute <CodeGenExtension>())
                    {
                        methodInfo.Invoke(null, null);
                    }
                }

                if (type.ReadGenFlags() != GenTaskFlags.None)
                {
                    RequestGen(type, type.ReadGenFlags(), true);
                }
            }

            extensionSink = context.createSharpClass("SerializationExtensions", isStatic: true, isPartial: true);
            extensionSink.usingSink("System.IO");
            extensionSink.usingSink("ZergRush.Alive");

            extensionClientSink = clientOnlyContext.createSharpClass("SerializationExtensions", isStatic: true, isPartial: true);
            extensionClientSink.usingSink("System.IO");
            extensionClientSink.usingSink("ZergRush.Alive");


            while (tasks.Count > 0)
            {
                var task = tasks.Pop();
                var type = task.type;

                if (type.HasAttribute <DoNotGen>())
                {
                    continue;
                }

                var classSink = GenClassSink(task.type);

                classSink.indent++;

                Action <GenTaskFlags, Action <string> > checkFlag = (flag, gen) =>
                {
                    if ((task.flags & flag) != 0)
                    {
                        bool isCustom          = false;
                        bool needGenBase       = false;
                        var  genTaskCustomImpl = type.GetCustomImplAttr();
                        if (genTaskCustomImpl != null)
                        {
                            if ((genTaskCustomImpl.flags & flag) != 0)
                            {
                                isCustom    = true;
                                needGenBase = genTaskCustomImpl.genBaseMethods;
                            }
                        }

                        if (isCustom && needGenBase == false)
                        {
                            return;
                        }
                        string funcPrefix = isCustom ? "Base" : "";
                        gen(funcPrefix);
                    }
                };

                checkFlag(GenTaskFlags.UpdateFrom, funcPrefix => GenUpdateFrom(type, false, funcPrefix));
                checkFlag(GenTaskFlags.PooledUpdateFrom, funcPrefix => GenUpdateFrom(type, true, funcPrefix));
                checkFlag(GenTaskFlags.Deserialize, funcPrefix => GenerateDeserialize(type, false, funcPrefix));
                checkFlag(GenTaskFlags.PooledDeserialize, funcPrefix => GenerateDeserialize(type, true, funcPrefix));
                checkFlag(GenTaskFlags.Serialize, funcPrefix => GenerateSerialize(type, funcPrefix));
                checkFlag(GenTaskFlags.Hash, funcPrefix => GenHashing(type, funcPrefix));
                checkFlag(GenTaskFlags.UIDGen, funcPrefix => GenUIDFunc(type, funcPrefix));
                checkFlag(GenTaskFlags.CollectConfigs, funcPrefix => GenCollectConfigs(type, funcPrefix));
                checkFlag(GenTaskFlags.LifeSupport, funcPrefix => GenerateLivable(type, funcPrefix));
                checkFlag(GenTaskFlags.OwnershipHierarchy, funcPrefix => GenerateHierarchyAndId(type, funcPrefix));
                checkFlag(GenTaskFlags.OwnershipHierarchy, funcPrefix => GenerateConstructionFromRoot(type));
                checkFlag(GenTaskFlags.DefaultConstructor, funcPrefix => GenerateConstructor(type));
                checkFlag(GenTaskFlags.CompareChech, funcPrefix => GenerateComparisonFunc(type, funcPrefix));
                checkFlag(GenTaskFlags.JsonSerialization, funcPrefix => GenerateJsonSerialization(type, funcPrefix));
                checkFlag(GenTaskFlags.Pooled, funcPrefix => GeneratePoolSupportMethods(type));
                //checkFlag(GenTaskFlags.PrintHash, funcPrefix => GeneratePrintHash(type, funcPrefix));

                classSink.indent--;
            }

            GenerateFieldWrappers();
            GeneratePolimorphismSupport();
            GeneratePolymorphicRootSupport();
            // Do not change anythign if there is any errors
            if (hasErrors)
            {
                EditorUtility.ClearProgressBar();
                return;
            }

            EditorUtility.DisplayProgressBar("Running codegen", "writing cs files", 0.5f);

            foreach (FileInfo file in genDir.GetFiles())
            {
                // Skip metafiles for clean commit messages.
                if (file.Name.EndsWith("meta") || file.Name.EndsWith("txt"))
                {
                    continue;
                }
                file.Delete();
            }

            foreach (var typeEnumTable in finalTypeEnum)
            {
                EnumTable.Save(typeEnumTable.Key.TypeTableFileName(), new EnumTable {
                    records = typeEnumTable.Value
                });
            }

            context.Commit();
            clientOnlyContext.Commit();
            AssetDatabase.Refresh();

            EditorUtility.ClearProgressBar();
        }