static void GenPolymorphicRootSetup(Type baseClass, SharpClassBuilder sink,
                                            List <Type> typeIndexer, bool pooled)
        {
            string poolTypeArgIfAny = pooled ? $"{baseClass.PoolTypeName()} ," : "";

            if (pooled)
            {
                sink.usingSink("ZergRush.Alive");
            }

            // Array with constructors
            var constructorsArrayName = $"polymorph{(pooled ? "Pulled" : "")}Constructors";

            sink.content(
                $"static Func<{poolTypeArgIfAny}{baseClass.RealName()}> [] {constructorsArrayName} =" +
                $" new Func<{poolTypeArgIfAny}{baseClass.RealName()}> [] {{");
            sink.indent++;
            if (stubMode == false)
            {
                for (var i = 0; i < typeIndexer.Count; i++)
                {
                    var type = typeIndexer[i];
                    sink.content(
                        $"{(pooled ? "pool" : "()")} => {(type != null ? NewInstExpr(type, pooled) : "null")}, // {i}");
                }
            }

            sink.indent--;
            sink.content($"}};");

            // Create function
            sink.content(
                $"public static {baseClass.RealName()} {PolymorphInstanceFuncNamePooled(pooled)}(" +
                $"{PolymorphClassIdType} typeId{baseClass.OptPoolSecondArgDecl(pooled)}) {{");
            sink.content($"\treturn {constructorsArrayName}[typeId]({(pooled ? "pool" : "")});");
            sink.content($"}}");
        }
示例#2
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();
        }