예제 #1
0
        public void ConversionAction()
        {
            int i = 0;

            while (i++ < 1)
            {
                var translator = new CSTranslator();
                var globalRes  = Content.Content.Get().WorldObjectGlobals.Get("global").Resource;

                var iff = globalRes.MainIff;
                iff.Filename = "global.iff";
                translator.Context.GlobalRes = globalRes;
                var globalText = translator.TranslateIff(iff);
                using (var file = System.IO.File.Open(Path.Combine(DestPath, "Global.cs"), System.IO.FileMode.Create))
                {
                    using (var writer = new System.IO.StreamWriter(file))
                    {
                        writer.Write(globalText);
                    }
                }

                if (Abort)
                {
                    break;
                }

                var globalContext = (CSTranslationContext)translator.Context;

                var compiledSG   = new Dictionary <GameGlobalResource, CSTranslationContext>();
                var objs         = Content.Content.Get().WorldObjects.Entries.Where(x => User || (x.Value.Source != GameObjectSource.User)).ToList();
                var fileComplete = new HashSet <string>();
                var objPct       = 0;
                foreach (var obj in objs)
                {
                    var r = obj.Value;
                    if (!fileComplete.Contains(r.FileName))
                    {
                        Invoke(new Action(() => {
                            AOTProgress.Value = 10 + (objPct * 90) / objs.Count;
                        }));
                        fileComplete.Add(r.FileName);
                        var objRes = r.Get();

                        CSTranslationContext sg = null;
                        if (objRes.Resource.SemiGlobal != null)
                        {
                            if (!compiledSG.TryGetValue(objRes.Resource.SemiGlobal, out sg))
                            {
                                //compile semiglobals
                                translator = new CSTranslator();
                                var sgIff = objRes.Resource.SemiGlobal.MainIff;
                                translator.Context.ObjectRes     = objRes.Resource; //pass this in as occasionally *local* tuning constants are used in *semiglobal* functions.
                                translator.Context.GlobalRes     = globalRes;
                                translator.Context.SemiGlobalRes = objRes.Resource.SemiGlobal;
                                translator.Context.GlobalContext = globalContext;
                                Invoke(new Action(() => {
                                    AOTStatus.Text = $"Translating Semi-Global {sgIff.Filename}";
                                }));
                                var semiglobalText = translator.TranslateIff(sgIff);
                                using (var file = System.IO.File.Open(Path.Combine(DestPath, translator.Context.Filename + ".cs"), System.IO.FileMode.Create))
                                {
                                    using (var writer = new System.IO.StreamWriter(file))
                                    {
                                        writer.Write(semiglobalText);
                                    }
                                }
                                sg = (CSTranslationContext)translator.Context;
                                compiledSG[objRes.Resource.SemiGlobal] = sg;
                            }
                        }

                        translator = new CSTranslator();
                        var objIff = objRes.Resource.MainIff;
                        translator.Context.GlobalRes         = globalRes;
                        translator.Context.SemiGlobalRes     = objRes.Resource.SemiGlobal;
                        translator.Context.ObjectRes         = objRes.Resource;
                        translator.Context.GlobalContext     = globalContext;
                        translator.Context.SemiGlobalContext = sg;
                        Invoke(new Action(() => {
                            AOTStatus.Text = $"Translating {objIff.Filename}";
                        }));
                        var objText = translator.TranslateIff(objIff);
                        using (var file = System.IO.File.Open(Path.Combine(DestPath, translator.Context.Filename + ".cs"), System.IO.FileMode.Create))
                        {
                            using (var writer = new System.IO.StreamWriter(file))
                            {
                                writer.Write(objText);
                            }
                        }
                    }
                    objPct++;
                }

                if (!Abort)
                {
                    Invoke(new Action(() => {
                        AOTStatus.Text    = $"Completed! {objs.Count} objects converted.";
                        AOTProgress.Value = 100;
                    }));
                }
            }
            if (Abort)
            {
                Invoke(new Action(() => {
                    AOTStatus.Text = "Aborted.";
                }));
            }

            Invoke(new Action(() => {
                AOTToggle.Text    = "Begin";
                AOTToggle.Enabled = true;
            }));
            Abort            = false;
            ConversionThread = null;
        }
        public async Task <SimAnticsModule> CompileModule()
        {
            var translator = new CSTranslator();
            var objIff     = File.MainIff;
            var refs       = GetReferences().ToList();

            if (!IsGlobal)
            {
                var global = await Context.GetGlobal();

                translator.Context.GlobalRes    = global.File;
                translator.Context.GlobalModule = global.Module;
                refs.Add(MetadataReference.CreateFromFile(global.FilePath + ".dll"));
            }
            else
            {
                translator.Context.GlobalRes = File;
            }

            var sg = File.SemiGlobal;

            if (sg != null)
            {
                var sgModule = await Context.GetSemiglobal(sg);

                translator.Context.SemiGlobalRes    = sg;
                translator.Context.SemiGlobalModule = sgModule.Module;
                refs.Add(MetadataReference.CreateFromFile(sgModule.FilePath + ".dll"));
            }

            translator.Context.ObjectRes = File;

            // create the cs source
            Console.WriteLine($"Translating {objIff.Filename}");
            var objText = translator.TranslateIff(objIff);

            // compile it into an assembly with roslyn
            var options = new CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary,
                                                       optimizationLevel: Context.Debug ? OptimizationLevel.Debug : OptimizationLevel.Release,
                                                       moduleName: translator.Context.NamespaceName,
                                                       platform: Platform.AnyCpu,
                                                       warningLevel: 0);

            if (Context.Debug)
            {
                using (var files = System.IO.File.Open(FilePath + ".cs", System.IO.FileMode.Create))
                {
                    using (var writer = new System.IO.StreamWriter(files))
                    {
                        writer.Write(objText);
                    }
                }
            }
            var file = CSharpSyntaxTree.ParseText(objText, new CSharpParseOptions(), Path.GetFullPath(FilePath + ".cs"), Encoding.UTF8);

            var compiler = CSharpCompilation.Create(translator.Context.NamespaceName, options: options, references: refs, syntaxTrees: new List <SyntaxTree>()
            {
                file
            });
            // save the assembly to disk for later use
            var emitResult = compiler.Emit(FilePath + ".dll", Context.Debug ? (FilePath + ".pdb") : null, Context.Debug ? (FilePath + ".xml") : null);

            // load the assembly
            if (!emitResult.Success)
            {
                return(null);
            }
            try
            {
                var assembly = Assembly.LoadFile(Path.GetFullPath(FilePath + ".dll"));
                return(FindModuleInAssembly(assembly));
            }
            catch (Exception e)
            {
                return(null);
            }
        }