public object Retrieve() { if (_typeGen.IsCompleted) { return(_object); } else { _typeGen.Complete(); var type = _typeGen.GetCompletedType(); return(_object = Activator.CreateInstance(type)); } }
protected override object ReallyDoEvaluate(Irony.Interpreter.ScriptThread thread) { var rs = thread.rs(); var ag = rs.AG; using (ag.Namespace("Shakespeare.Program")) { TypeGen scriptClass = ag.Public.Class("Script", typeof(Shakespeare.Support.Dramaturge)); { rs.Script = scriptClass; var console = typeof(Console); CodeGen ctor = scriptClass.Public.Constructor(); ctor.InvokeBase(Static.Property(console, "In"), Static.Property(console, "Out")); { } CodeGen action = scriptClass.Public.Void("Action"); { rs.Action = action; action.At(Span); AstNode1.Evaluate(thread); var cdl = AstNode2 as CharacterDeclarationListNode; foreach (var ch in cdl.Characters) { ch.Evaluate(thread); } AstNode3.Evaluate(thread); } } scriptClass.Complete(); TypeGen MyClass = ag.Public.Class("Program"); CodeGen Main = MyClass.Public.Static.Void("Main").Parameter <string[]>("args"); { var script = Main.Local(Exp.New(scriptClass.GetCompletedType())); Main.Invoke(script, "Action"); } } ag.Save(); return(ag.GetAssembly().GetName().Name); }
/// <summary> /// Iterate over all loaded mods and emit new types /// </summary> protected void Awake() { // Generate overloaded PQSMod types AssemblyGen assembly = new AssemblyGen(Guid.NewGuid().ToString(), new CompilerOptions { OutputPath = Path.GetTempFileName() }); List <Type> modTypes = GetModTypes(); foreach (Type modType in modTypes) { if (typeof(PQSMod).IsAssignableFrom(modType)) { // Get the ModLoader type we want to extend Type loaderType = modTypes.FirstOrDefault(t => t.BaseType != null && t.BaseType.FullName != null && t.BaseType.FullName.StartsWith("Kopernicus.Configuration.ModLoader.ModLoader") && t.BaseType.GetGenericArguments()[0] == modType); if (loaderType == null) { continue; } // Generate the Mod Type TypeGen modGen = assembly.Public.Class($"{modType.Name}Regional", modType); { FieldGen multiplierMap = modGen.Public.Field(typeof(MapSO), "multiplierMap"); FieldGen splitChannels = modGen.Public.Field(typeof(Boolean), "splitChannels"); FieldGen multiplier = modGen.Private.Field(typeof(Color), "multiplier"); FieldGen preBuildColor = modGen.Private.Field(typeof(Color), "preBuildColor"); FieldGen preBuildHeight = modGen.Private.Field(typeof(Double), "preBuildHeight"); // OnVertexBuildHeight CodeGen onVertexBuild = modGen.Public.Override.Method(typeof(void), "OnVertexBuild") .Parameter(typeof(PQS.VertexBuildData), "data"); { ContextualOperand data = onVertexBuild.Arg("data"); onVertexBuild.Assign(multiplier, onVertexBuild.Local(multiplierMap.Invoke( "GetPixelColor", new TypeMapper(), data.Field("u"), data.Field("v")))); onVertexBuild.If(!splitChannels); { onVertexBuild.Assign(multiplier.Field("a", new TypeMapper()), multiplier.Field("r", new TypeMapper())); } onVertexBuild.End(); onVertexBuild.Assign(preBuildColor, data.Field("vertColor")); onVertexBuild.Assign(preBuildHeight, data.Field("vertHeight")); onVertexBuild.Invoke(onVertexBuild.Base(), "OnVertexBuild", data); onVertexBuild.Assign(data.Field("vertColor"), assembly.StaticFactory.Invoke(typeof(Color), "Lerp", preBuildColor, data.Field("vertColor"), multiplier.Field("a", new TypeMapper()))); onVertexBuild.Assign(data.Field("vertHeight"), assembly.StaticFactory.Invoke(typeof(UtilMath), "Lerp", preBuildHeight, data.Field("vertHeight"), multiplier.Field("r", new TypeMapper()))); } // OnVertexBuildHeight CodeGen onVertexBuildHeight = modGen.Public.Override.Method(typeof(void), "OnVertexBuildHeight") .Parameter(typeof(PQS.VertexBuildData), "data"); { ContextualOperand data = onVertexBuildHeight.Arg("data"); onVertexBuildHeight.Assign(multiplier, onVertexBuildHeight.Local(multiplierMap.Invoke( "GetPixelColor", new TypeMapper(), data.Field("u"), data.Field("v")))); onVertexBuildHeight.If(!splitChannels); { onVertexBuildHeight.Assign(multiplier.Field("a", new TypeMapper()), multiplier.Field("r", new TypeMapper())); } onVertexBuildHeight.End(); onVertexBuildHeight.Assign(preBuildColor, data.Field("vertColor")); onVertexBuildHeight.Assign(preBuildHeight, data.Field("vertHeight")); onVertexBuildHeight.Invoke(onVertexBuildHeight.Base(), "OnVertexBuildHeight", data); onVertexBuildHeight.Assign(data.Field("vertColor"), assembly.StaticFactory.Invoke(typeof(Color), "Lerp", preBuildColor, data.Field("vertColor"), multiplier.Field("a", new TypeMapper()))); onVertexBuildHeight.Assign(data.Field("vertHeight"), assembly.StaticFactory.Invoke(typeof(UtilMath), "Lerp", preBuildHeight, data.Field("vertHeight"), multiplier.Field("r", new TypeMapper()))); } } // Generate the Loader Type modGen.Complete(); Type modLoader = typeof(ModLoader <>).MakeGenericType(modGen.GetCompletedType()); TypeGen loaderGen = assembly.Public.Class($"{modType.Name.Replace("PQSMod_", "").Replace("PQS", "")}Regional", modLoader).Attribute(typeof(RequireConfigType), Kopernicus.ConfigParser.Enumerations.ConfigType.Node); { PropertyGen multiplierMap = loaderGen.Public.Property(typeof(MapSOParserRGB <MapSO>), "multiplierMap") .Attribute(typeof(ParserTarget), "multiplierMap"); { CodeGen getter = multiplierMap.Getter(); { getter.Return(getter.Base().Property("Mod").Field("multiplierMap")); } CodeGen setter = multiplierMap.Setter(); { setter.Assign(setter.Base().Property("Mod").Field("multiplierMap"), setter.PropertyValue()); } } PropertyGen splitChannels = loaderGen.Public.Property(typeof(NumericParser <Boolean>), "splitChannels") .Attribute(typeof(ParserTarget), "splitChannels"); { CodeGen getter = splitChannels.Getter(); { getter.Return(getter.Base().Property("Mod").Field("splitChannels")); } CodeGen setter = splitChannels.Setter(); { setter.Assign(setter.Base().Property("Mod").Field("splitChannels"), setter.PropertyValue()); } } FieldGen loader = loaderGen.Public.Field(loaderType, "loader") .BeginAttribute(typeof(ParserTarget), "Mod").SetField("AllowMerge", true).End(); CodeGen create_PQS = loaderGen.Public.Override.Method(typeof(void), "Create") .Parameter(typeof(PQS), "pqsVersion"); { ContextualOperand pqsVersion = create_PQS.Arg("pqsVersion"); create_PQS.Invoke(create_PQS.Base(), "Create", pqsVersion); create_PQS.Assign(loader, assembly.ExpressionFactory.New(loaderType)); create_PQS.Invoke(loader, "Create", create_PQS.Base().Property("Mod"), pqsVersion); } CodeGen create_Mod_PQS = loaderGen.Public.Override.Method(typeof(void), "Create") .Parameter(modGen, "_mod") .Parameter(typeof(PQS), "pqsVersion"); { ContextualOperand _mod = create_Mod_PQS.Arg("_mod"); ContextualOperand pqsVersion = create_Mod_PQS.Arg("pqsVersion"); create_Mod_PQS.Invoke(create_Mod_PQS.Base(), "Create", _mod, pqsVersion); create_Mod_PQS.Assign(loader, assembly.ExpressionFactory.New(loaderType)); create_Mod_PQS.Invoke(loader, "Create", create_Mod_PQS.Base().Property("Mod"), pqsVersion); } } } } assembly.Save(); // Hacking into my own mod. Oh well. modTypes.AddRange(assembly.GetAssembly().GetTypes()); typeof(Parser).GetField("_modTypes", BindingFlags.NonPublic | BindingFlags.Static) ?.SetValue(null, modTypes); }