Ejemplo n.º 1
0
        // Public methods
        ///////////////////////////

        public static Action Create(Ecs.Internals ecs, MethodInfo systemInfo)
        {
            var systemName = $"{systemInfo.DeclaringType}.{systemInfo.Name}";
            var arguments  = systemInfo.GetParameters()
                             .Select(p => GetArgumentData(ecs, p))
                             .ToArray();

            if (arguments.Length == 0)
            {
                return(() => systemInfo.Invoke(null, null));
            }
            var resources = arguments
                            .Where(a => a.isResource)
                            .ToArray();
            var components = arguments
                             .Where(a => !a.isResource)
                             .ToArray();
            var src = default(string);

            if (components.Length > 0)
            {
                src = ForEachSource(ecs, arguments, resources, components);
            }
            else
            {
                src = ResourceOnlySource(ecs, resources);
            }
            var asmGen = new AssemblyGenerator();

            asmGen.ReferenceAssemblyByName("System");
            asmGen.ReferenceAssemblyByName("System.Collections");
            asmGen.ReferenceAssemblyByName("System.Reflection");
            asmGen.ReferenceAssemblyContainingType(typeof(Ecs));
            src = asmGen.Format(src);
            var startTime = TimeNow();

            var(assembly, errors) = asmGen.Generate(src);
            if (errors != null)
            {
                var sb = new System.Text.StringBuilder();
                sb.Append($"encountered error(s) compiling system runner for {systemName}");
                foreach (var error in errors)
                {
                    sb.Append($"\n  {error.Replace("\n", "\n  ")}");
                }
                var srcLines = src.Split("\n");
                for (var i = 0; i < srcLines.Length; i++)
                {
                    sb.Append($"\n{i+1}\t{srcLines[i]}");
                }
                throw new Exception(sb.ToString());
            }
            var runner   = assembly.GetType("Runner");
            var duration = TimeNow() - startTime;

            Console.WriteLine($"generated system runner for {systemName} in {duration}ms:\n  {src.Replace("\n", "\n  ")}");
            runner.GetMethod("Initialize").Invoke(null, new object[] { ecs, systemInfo });
            return((Action)runner.GetMethod("Run").CreateDelegate(typeof(Action)));
        }
Ejemplo n.º 2
0
        static (Action, bool) Compile(string fileName)
        {
            var startTime = Time.Now();
            var source    = File.ReadAllText(fileName);
            var asmGen    = new AssemblyGenerator();

            asmGen.ReferenceAssemblyByName("System.Collections");
            asmGen.ReferenceAssemblyByName("System.Linq");
            asmGen.ReferenceAssemblyContainingType(typeof(Program));
            source = asmGen.Format(source);
            var(assembly, errors) = asmGen.Generate(source);
            if (errors != null)
            {
                Log.Error($"compilation error:\n{String.Join("\n", errors)}");
                return(null, false);
            }
            var scriptType = assembly.GetType("Script");
            var mainMethod = scriptType.GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Static);
            var run        = (Action)mainMethod.CreateDelegate(typeof(Action));
            var duration   = Time.Now() - startTime;

            Log.Info($"compiled script {fileName} in {duration:F2}s");
            return(run, true);
        }