diff --git a/Build/Compilers/ZenNode.cfg b/Build/Compilers/ZenNode.cfg index 90aa4124..fc742d58 100644 --- a/Build/Compilers/ZenNode.cfg +++ b/Build/Compilers/ZenNode.cfg @@ -5,6 +5,7 @@ compilers // The setting named "program" defines what .exe to run zennode { + interface = "NodesCompiler"; program = "ZenNode.exe"; } } diff --git a/Build/Compilers/bsp-w32.cfg b/Build/Compilers/bsp-w32.cfg index 730bc4d2..8b51572e 100644 --- a/Build/Compilers/bsp-w32.cfg +++ b/Build/Compilers/bsp-w32.cfg @@ -5,6 +5,7 @@ compilers // The setting named "program" defines what .exe to run bspw32 { + interface = "NodesCompiler"; program = "bsp-w32.exe"; } } diff --git a/Build/Compilers/glBSP.cfg b/Build/Compilers/glBSP.cfg index 416d9d8b..82577161 100644 --- a/Build/Compilers/glBSP.cfg +++ b/Build/Compilers/glBSP.cfg @@ -5,6 +5,7 @@ compilers // The setting named "program" defines what .exe to run glbsp { + interface = "NodesCompiler"; program = "glBSP.exe"; } } diff --git a/Build/Compilers/zdbsp.cfg b/Build/Compilers/zdbsp.cfg index 0375e364..761dba45 100644 --- a/Build/Compilers/zdbsp.cfg +++ b/Build/Compilers/zdbsp.cfg @@ -5,6 +5,7 @@ compilers // The setting named "program" defines what .exe to run zdbsp { + interface = "NodesCompiler"; program = "zdbsp.exe"; } } diff --git a/Documents/compilerinterfaces.txt b/Documents/compilerinterfaces.txt index cff204ff..2e43ed43 100644 --- a/Documents/compilerinterfaces.txt +++ b/Documents/compilerinterfaces.txt @@ -27,3 +27,17 @@ With this interface you can use the following command-line parameters: %PT indicates the temporary directory path where the compiler is located. ------------------------------------------------------------------------------------- +NodesCompiler + +This compiler interface is made for nodebuilders. + +With this interface you can use the following command-line parameters: + +%FI indicates the input filename (no path included). + +%FO indicates the output filename (no path included). + +%PT indicates the temporary directory path where the compiler and input/output files +are located. This is also the working directory for the compiler. + +------------------------------------------------------------------------------------- diff --git a/Source/Builder.csproj b/Source/Builder.csproj index b05dbc6b..5150b68c 100644 --- a/Source/Builder.csproj +++ b/Source/Builder.csproj @@ -46,6 +46,7 @@ --> <ItemGroup> <Compile Include="Compilers\AccCompiler.cs" /> + <Compile Include="Compilers\NodesCompiler.cs" /> <Compile Include="Config\ArgumentInfo.cs" /> <Compile Include="Config\MapLumpInfo.cs" /> <Compile Include="Config\ScriptConfiguration.cs" /> diff --git a/Source/Compilers/AccCompiler.cs b/Source/Compilers/AccCompiler.cs index 35af10f9..8fc34489 100644 --- a/Source/Compilers/AccCompiler.cs +++ b/Source/Compilers/AccCompiler.cs @@ -23,12 +23,15 @@ using System.Globalization; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; +using System.IO; +using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.IO; #endregion namespace CodeImp.DoomBuilder.Compilers { - public sealed class AccCompiler : Compiler + internal sealed class AccCompiler : Compiler { #region ================== Constants @@ -38,26 +41,38 @@ namespace CodeImp.DoomBuilder.Compilers #endregion - #region ================== Properties - - #endregion - #region ================== Constructor // Constructor - public AccCompiler() + public AccCompiler(CompilerInfo info) : base(info) { } + + // Disposer + public override void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + + // Done + base.Dispose(); + } + } #endregion #region ================== Methods - /// <summary> - /// This runs the compiler. - /// </summary> - /// <returns>Returns false when failed to start.</returns> - public override bool Run() + // This runs the compiler with a file as input. + public override bool CompileFile(string filename) + { + return true; + } + + // This runs the compiler with lump data as input. + public override bool CompileLump(Stream lumpdata) { return true; } diff --git a/Source/Compilers/Compiler.cs b/Source/Compilers/Compiler.cs index ffd54c84..682b472b 100644 --- a/Source/Compilers/Compiler.cs +++ b/Source/Compilers/Compiler.cs @@ -24,63 +24,142 @@ using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.Reflection; +using System.IO; +using CodeImp.DoomBuilder.Config; +using CodeImp.DoomBuilder.IO; #endregion namespace CodeImp.DoomBuilder.Compilers { - public abstract class Compiler + public abstract class Compiler : IDisposable { #region ================== Variables + // Parameters + protected CompilerInfo info; + protected string parameters; + protected string workingdir; + + // Files + protected DirectoryInfo tempdir; + // Errors private List<CompilerError> errors; + // Disposing + protected bool isdisposed; + #endregion #region ================== Properties - + + public string Parameters { get { return parameters; } set { parameters = value; } } + public string WorkingDirectory { get { return workingdir; } set { workingdir = value; } } + public string Location { get { return tempdir.FullName; } } + public bool IsDisposed { get { return isdisposed; } } public CompilerError[] Errors { get { return errors.ToArray(); } } #endregion - #region ================== Constructor + #region ================== Constructor / Disposer // Constructor - public Compiler() + public Compiler(CompilerInfo info) { // Initialize + this.info = info; this.errors = new List<CompilerError>(); + + // Create temporary directory + tempdir = Directory.CreateDirectory(General.MakeTempDirname()); + workingdir = tempdir.FullName; + + // Copy required files to the temp directory + CopyRequiredFiles(); + } + + // Disposer + public virtual void Dispose() + { + if(!isdisposed) + { + // Remove temporary directory + tempdir.Delete(true); + + // Disposed + isdisposed = true; + } } #endregion #region ================== Methods + + // This copies all compiler files to a given destination + private void CopyRequiredFiles() + { + // Copy files + foreach(string f in info.Files) + { + string sourcefile = Path.Combine(General.CompilersPath, f); + string targetfile = Path.Combine(tempdir.FullName, f); + if(!File.Exists(sourcefile)) General.WriteLogLine("ERROR: The file '" + f + "' required by the '" + info.Name + "' compiler is missing!"); + File.Copy(sourcefile, targetfile, true); + } + } /// <summary> - /// This runs the compiler. + /// This runs the compiler with a file as input. /// </summary> /// <returns>Returns false when failed to start.</returns> - public abstract bool Run(); - - // This reports an error + public virtual bool CompileFile(string filename) { return false; } + + /// <summary> + /// This runs the compiler with lump data as input. + /// </summary> + /// <returns>Returns false when failed to start.</returns> + public virtual bool CompileLump(Stream lumpdata) { return false; } + + /// <summary> + /// Use this to report an error. + /// </summary> protected void ReportError(CompilerError err) { this.errors.Add(err); } // This creates a compiler by interface name - internal static Compiler Create(string name) + internal static Compiler Create(CompilerInfo info) { + Compiler result; + // Make list of assemblies to search in List<Assembly> asms = General.Plugins.GetPluginAssemblies(); asms.Add(General.ThisAssembly); + // Constructor arguments + object[] args = new object[1]; + args[0] = info; + try { - - // TODO - + // Go for all assemblies + foreach(Assembly a in asms) + { + // Find the class + Type[] types = a.GetExportedTypes(); + foreach(Type t in types) + { + if(t.IsSubclassOf(typeof(Compiler)) && (t.Name == info.ProgramInterface)) + { + // Create instance + result = (Compiler)a.CreateInstance(t.FullName, false, BindingFlags.Default, + null, args, CultureInfo.CurrentCulture, new object[0]); + return result; + } + } + } } // Catch errors catch(TargetInvocationException e) @@ -92,6 +171,9 @@ namespace CodeImp.DoomBuilder.Compilers Debug.WriteLine(e.InnerException.StackTrace); throw e.InnerException; } + + // No such compiler + return null; } #endregion diff --git a/Source/Compilers/NodesCompiler.cs b/Source/Compilers/NodesCompiler.cs new file mode 100644 index 00000000..28994b92 --- /dev/null +++ b/Source/Compilers/NodesCompiler.cs @@ -0,0 +1,88 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Runtime.InteropServices; +using System.Diagnostics; +using System.IO; +using CodeImp.DoomBuilder.Config; + +#endregion + +namespace CodeImp.DoomBuilder.Compilers +{ + internal sealed class NodesCompiler : Compiler + { + #region ================== Constants + + #endregion + + #region ================== Variables + + // Output file + private string outputfile; + + #endregion + + #region ================== Properties + + public string OutputFile { get { return outputfile; } set { outputfile = value; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + public NodesCompiler(CompilerInfo info) : base(info) + { + // Initialize + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Disposer + public override void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + + // Done + base.Dispose(); + } + } + + #endregion + + #region ================== Methods + + // This runs the compiler with a file as input. + public override bool CompileFile(string filename) + { + return true; + } + + #endregion + } +} diff --git a/Source/Config/CompilerInfo.cs b/Source/Config/CompilerInfo.cs index 015f0645..c4cc7abf 100644 --- a/Source/Config/CompilerInfo.cs +++ b/Source/Config/CompilerInfo.cs @@ -25,12 +25,13 @@ using CodeImp.DoomBuilder.IO; using CodeImp.DoomBuilder.Data; using System.IO; using System.Diagnostics; +using CodeImp.DoomBuilder.Compilers; #endregion namespace CodeImp.DoomBuilder.Config { - internal class CompilerInfo + public sealed class CompilerInfo { #region ================== Constants @@ -57,7 +58,7 @@ namespace CodeImp.DoomBuilder.Config #region ================== Constructor / Disposer // Constructor - public CompilerInfo(string filename, string name, Configuration cfg) + internal CompilerInfo(string filename, string name, Configuration cfg) { IDictionary cfgfiles; @@ -84,17 +85,10 @@ namespace CodeImp.DoomBuilder.Config #region ================== Methods - // This copies all compiler files to a given destination - public void CopyRequiredFiles(string targetpath) + // This creates the actual compiler interface + internal Compiler Create() { - // Copy files - foreach(string f in files) - { - string sourcefile = Path.Combine(General.CompilersPath, f); - string targetfile = Path.Combine(targetpath, f); - if(!File.Exists(sourcefile)) General.WriteLogLine("WARNING: The file '" + f + "' required by the '" + name + "' compiler is missing!"); - File.Copy(sourcefile, targetfile, true); - } + return Compiler.Create(this); } #endregion diff --git a/Source/Config/NodebuilderInfo.cs b/Source/Config/NodebuilderInfo.cs index c8094b46..7cbe11f8 100644 --- a/Source/Config/NodebuilderInfo.cs +++ b/Source/Config/NodebuilderInfo.cs @@ -121,7 +121,7 @@ namespace CodeImp.DoomBuilder.Config { // Copy required files General.WriteLogLine("Copying required files for compiler '" + compiler.Name + "'..."); - compiler.CopyRequiredFiles(targetpath); + //compiler.CopyRequiredFiles(targetpath); } catch(Exception e) { diff --git a/Source/Controls/ScriptEditorPanel.Designer.cs b/Source/Controls/ScriptEditorPanel.Designer.cs index fecdd55e..bb8a6140 100644 --- a/Source/Controls/ScriptEditorPanel.Designer.cs +++ b/Source/Controls/ScriptEditorPanel.Designer.cs @@ -223,6 +223,7 @@ namespace CodeImp.DoomBuilder.Controls this.buttoncompile.Name = "buttoncompile"; this.buttoncompile.Size = new System.Drawing.Size(23, 22); this.buttoncompile.Text = "Compile Script"; + this.buttoncompile.Click += new System.EventHandler(this.buttoncompile_Click); // // buttonclose // diff --git a/Source/Controls/ScriptEditorPanel.cs b/Source/Controls/ScriptEditorPanel.cs index b497efa8..27fa74c9 100644 --- a/Source/Controls/ScriptEditorPanel.cs +++ b/Source/Controls/ScriptEditorPanel.cs @@ -409,6 +409,15 @@ namespace CodeImp.DoomBuilder.Controls UpdateToolbar(); } + // Compile Script clicked + private void buttoncompile_Click(object sender, EventArgs e) + { + // First save all implicit scripts to the temporary wad file + ImplicitSave(); + + // TODO: Now compile this lump + } + // Undo clicked private void buttonundo_Click(object sender, EventArgs e) { diff --git a/Source/General/MapManager.cs b/Source/General/MapManager.cs index 529c8f18..839f94d1 100644 --- a/Source/General/MapManager.cs +++ b/Source/General/MapManager.cs @@ -34,6 +34,7 @@ using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Actions; using CodeImp.DoomBuilder.Config; using CodeImp.DoomBuilder.Plugins; +using CodeImp.DoomBuilder.Compilers; #endregion @@ -1040,7 +1041,7 @@ namespace CodeImp.DoomBuilder #endregion - #region ================== Script Editor + #region ================== Script Editing // Show the script editor [BeginAction("openscripteditor")] @@ -1114,6 +1115,30 @@ namespace CodeImp.DoomBuilder } } + // This compiles a script lump and returns any errors that may have occurred + internal CompilerError[] CompileLump(Lump scriptlump, bool showwarning) + { + DirectoryInfo tempdir; + CompilerError[] errors; + + // Determine the script configuration to use + ScriptConfiguration scriptconfig = config.MapLumps[scriptlump.Name].script; + + // Initialize compiler + Compiler compiler = scriptconfig.Compiler.Create(); + + // Run compiler + compiler.Parameters = scriptconfig.Parameters; + + errors = compiler.Errors; + + // Clean up + compiler.Dispose(); + + // Done + return errors; + } + #endregion #region ================== Methods