static void GenClassIdFuncs(Type baseClass, List <Type> typesToGenPolymorphMethods, SharpClassBuilder sink) { foreach (var type in typesToGenPolymorphMethods) { if (type.ReadGenCustomFlags() == type.ReadGenFlags()) { continue; } var tSink = GenClassSink(type); tSink.inheritance("IPolymorphable"); if (type.IsAbstract) { if (type == baseClass) { tSink.content( $"public virtual {PolymorphClassIdType} {PolymorphClassIdFunc}(){{throw new NotImplementedException();}}"); } } else { var mType = type == baseClass ? MethodType.Virtual : MethodType.Override; var classIdGetter = tSink.Method(PolymorphClassIdFunc, type, mType, PolymorphClassIdType, ""); classIdGetter.doNotCallBaseMethod = true; if (type.IsGenericTypeDecl()) { PrintGenericSwitch(type, classIdGetter, (t, s) => s.content( $"return ({PolymorphClassIdType}){TypeEnumName}.{t.UniqueName(false)};")); classIdGetter.content("return 0;"); } else { classIdGetter.content( $"return ({PolymorphClassIdType}){TypeEnumName}.{type.UniqueName(false)};"); } } if (UseClassIdCaching) { sink.content($"[GenIgnore] public {PolymorphClassIdTypeName} {PolymorphClassIdCached};"); var cachedGetter = sink.Method(PolymorphClassIdGetterName, baseClass, MethodType.Instance, PolymorphClassIdType, ""); cachedGetter.content( $"return {PolymorphClassIdCached} == 0 ? {PolymorphClassIdCached} = {PolymorphClassIdFunc}() : {PolymorphClassIdCached};"); } } }
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($"}}"); }