Exemple #1
0
        /// <summary>
        /// Loads the component data for the currently selected mod.
        /// </summary>
        public void Load()
        {
            // TODO: Replace with a more robust building mechanism (and maybe more partial modding support?)
            CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary <string, string> {
                { "CompilerVersion", "v3.5" }
            });
            CompilerParameters pars = new CompilerParameters();

            // Uncomment the following line to enforce code security
            // pars.Evidence = new Evidence(new object[] { new Zone(SecurityZone.Internet) }, null);
            pars.GenerateExecutable      = false;
            pars.GenerateInMemory        = true;
            pars.IncludeDebugInformation = true;

            // NOTE: Maybe the referenced assemblies and usings for inline methods should be defined in a xml?
            pars.ReferencedAssemblies.Add("System.dll");
            pars.ReferencedAssemblies.Add("System.Core.dll");
            pars.ReferencedAssemblies.Add("System.Drawing.dll");
            pars.ReferencedAssemblies.Add("System.Xml.dll");
            pars.ReferencedAssemblies.Add("SdlDotNet.dll");
            pars.ReferencedAssemblies.Add("Teraluwide.Blackbird.Core.dll");
            pars.ReferencedAssemblies.Add(Assembly.GetEntryAssembly().Location);

            string inlineCode
                = "using System; using System.Linq; using System.Drawing; using System.Text; using Teraluwide.Blackbird.Core.Gui; using Teraluwide.Blackbird.Core.Gui.Controls; public partial class Core { " + inlineMethods.ToString() + " }";

            if (Game.Debug)
            {
                System.IO.File.WriteAllText("inlineSources.cs", inlineCode.ToString());
            }

            Stopwatch sw = Stopwatch.StartNew();

            // NOTE: If we expect to have huge scripts, it may be necessary to use an alternate way to compile them; At present time, this implementation is sufficient.
            CompilerResults res = codeProvider.CompileAssemblyFromSource(pars, VirtualPathProvider.FindFiles(VirtualPathProvider.EnsureModVirtualPath("scripts", Game.ModName), "*.cs").Select(i => VirtualPathProvider.GetFile(i).ReadToEnd()).Concat(new string[] { inlineCode }).ToArray());

            sw.Stop();
            Console.WriteLine("Scripts compiled in {0:#,###,##0} ms.", sw.ElapsedMilliseconds);

            // NOTE: Maybe there should be a better way to filter out warnings.
            if (res.Errors.Count > 0 && res.Errors.OfType <CompilerError>().Any(i => !i.IsWarning))
            {
                System.IO.File.WriteAllLines("error.log", res.Errors.OfType <CompilerError>().Select(i => i.ToString()).ToArray());

                // TODO: Handle compiler errors.
                if (!Debugger.IsAttached)
                {
                    Debugger.Launch();
                }

                Debugger.Break();
            }
            else
            {
                Assembly assembly = res.CompiledAssembly;

                Type coreType = assembly.GetType("Core");
                core = Activator.CreateInstance(coreType, Game);

                // Notify the late method binders.
                foreach (var binder in methodBinders)
                {
                    // TODO: Add some error handling - missing methods, wrong definitions etc.
                    MethodInfo mi = coreType.GetMethod(binder.MethodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                    binder.BindMethod(Delegate.CreateDelegate(binder.DelegateType, core, mi, true));
                }
            }
        }