working on generalized compiler interfacing (nodebuilders work again, now through a generalized compiler interface)

This commit is contained in:
codeimp 2008-11-14 10:44:03 +00:00
parent ed50a992ad
commit fdb004d7c3
9 changed files with 104 additions and 110 deletions

View file

@ -20,24 +20,19 @@ compilers
// The "compiler" setting must refer to an existing compiler (such as defined above), but it
// does not have to be a compiler defined in the same configuration file.
// Parameter placeholders:
// %F is the WAD file where the nodebuilder must read from
// %T is the WAD file to which the nodebuilde writes its output (optional)
// When %T is not specified, the nodebuilder should output to %F
nodebuilders
{
zennode_normal
{
title = "ZenNode - Normal";
compiler = "zennode";
parameters = "%F -o %F";
parameters = "%FI -o %FI";
}
zennode_fast
{
title = "ZenNode - Fast (no reject)";
compiler = "zennode";
parameters = "-n3 -nq -rz %F -o %F";
parameters = "-n3 -nq -rz %FI -o %FI";
}
}

View file

@ -19,24 +19,19 @@ compilers
// The "compiler" setting must refer to an existing compiler (such as defined above), but it
// does not have to be a compiler defined in the same configuration file.
// Parameter placeholders:
// %F is the WAD file where the nodebuilder must read from
// %T is the WAD file to which the nodebuilde writes its output (optional)
// When %T is not specified, the nodebuilder should output to %F
nodebuilders
{
glbsp_normal
{
title = "glBSP - Normal";
compiler = "glbsp";
parameters = "%F -o %T";
parameters = "%FI -o %FO";
}
glbsp_fast
{
title = "glBSP - Fast (no reject)";
compiler = "glbsp";
parameters = "-normal -noreject -v5 -factor 1 %F -o %T";
parameters = "-normal -noreject -v5 -factor 1 %FI -o %FO";
}
}

View file

@ -14,7 +14,7 @@ If this interface detects a file named "acs.err" created by the compiler, it wil
parse this file and treat the contents as compiler errors. In this case, the output
file contents are not copied into the wad file.
With this interface you can use the following command-line parameters:
With this interface supports the following placeholders in command-line parameters:
%FI indicates the input path and filename.
@ -26,6 +26,8 @@ With this interface you can use the following command-line parameters:
%PT indicates the temporary directory path where the compiler is located.
These placeholders are case-sensitive!
-------------------------------------------------------------------------------------
NodesCompiler
@ -37,7 +39,7 @@ With this interface you can use the following command-line parameters:
%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.
When %FO is not specified, the nodebuilder should output to %FI
These placeholders are case-sensitive!
-------------------------------------------------------------------------------------

View file

@ -1,6 +1,7 @@
This describes the placeholders that can be used in the command-line parameter for
testing settings (for launching the sourceport).
testing settings (for launching the sourceport). These placeholders are not
case-sensitive.
-------------------------------------------------------------------------------------

View file

@ -31,7 +31,7 @@ using CodeImp.DoomBuilder.IO;
namespace CodeImp.DoomBuilder.Compilers
{
internal sealed class AccCompiler : Compiler
public sealed class AccCompiler : Compiler
{
#region ================== Constants

View file

@ -70,12 +70,15 @@ namespace CodeImp.DoomBuilder.Compilers
// Initialize
this.info = info;
this.errors = new List<CompilerError>();
General.WriteLogLine("Creating compiler '" + info.Name + "' on interface '" + this.GetType().Name + "'...");
// Create temporary directory
tempdir = Directory.CreateDirectory(General.MakeTempDirname());
workingdir = tempdir.FullName;
// Copy required files to the temp directory
General.WriteLogLine("Copying required files for compiler...");
CopyRequiredFiles();
}
@ -85,6 +88,7 @@ namespace CodeImp.DoomBuilder.Compilers
if(!isdisposed)
{
// Remove temporary directory
General.WriteLogLine("Removing temporary compiler files...");
tempdir.Delete(true);
// Disposed

View file

@ -25,12 +25,13 @@ using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using CodeImp.DoomBuilder.Config;
using System.Windows.Forms;
#endregion
namespace CodeImp.DoomBuilder.Compilers
{
internal sealed class NodesCompiler : Compiler
public sealed class NodesCompiler : Compiler
{
#region ================== Constants
@ -80,6 +81,47 @@ namespace CodeImp.DoomBuilder.Compilers
// This runs the compiler with a file as input.
public override bool CompileFile(string filename)
{
ProcessStartInfo processinfo;
Process process;
TimeSpan deltatime;
// Create parameters
string args = this.parameters;
args = args.Replace("%FI", filename);
args = args.Replace("%FO", outputfile);
// Setup process info
processinfo = new ProcessStartInfo();
processinfo.Arguments = args;
processinfo.FileName = Path.Combine(this.tempdir.FullName, info.ProgramFile);
processinfo.CreateNoWindow = false;
processinfo.ErrorDialog = false;
processinfo.UseShellExecute = true;
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
processinfo.WorkingDirectory = this.tempdir.FullName;
// Output info
General.WriteLogLine("Running compiler...");
General.WriteLogLine("Program: " + processinfo.FileName);
General.WriteLogLine("Arguments: " + processinfo.Arguments);
try
{
// Start the compiler
process = Process.Start(processinfo);
}
catch(Exception e)
{
// Unable to start the compiler
General.ShowErrorMessage("Unable to start the compiler (" + info.Name + "). " + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
}
// Wait for compiler to complete
process.WaitForExit();
deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks);
General.WriteLogLine("Compiler process has finished.");
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
return true;
}

View file

@ -26,6 +26,7 @@ using CodeImp.DoomBuilder.Data;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Compilers;
#endregion
@ -74,7 +75,7 @@ namespace CodeImp.DoomBuilder.Config
this.parameters = cfg.ReadSetting("nodebuilders." + name + ".parameters", "");
// Check for special output filename
this.specialoutputfile = this.parameters.Contains("%T");
this.specialoutputfile = this.parameters.Contains("%FO");
// Find compiler
foreach(CompilerInfo c in General.Compilers)
@ -87,7 +88,7 @@ namespace CodeImp.DoomBuilder.Config
break;
}
}
// No compiler found?
if(this.compiler == null) throw new Exception("No such compiler defined: '" + compilername + "'");
}
@ -102,7 +103,7 @@ namespace CodeImp.DoomBuilder.Config
// Compare
return name.CompareTo(other.name);
}
// String representation
public override string ToString()
{
@ -110,66 +111,20 @@ namespace CodeImp.DoomBuilder.Config
}
// This runs the nodebuilder
public bool Run(string targetpath, string inputfile, string outputfile)
public NodesCompiler CreateCompiler()
{
ProcessStartInfo processinfo;
Process process;
TimeSpan deltatime;
string args;
try
Compiler c = compiler.Create();
if(c is NodesCompiler)
{
// Copy required files
General.WriteLogLine("Copying required files for compiler '" + compiler.Name + "'...");
//compiler.CopyRequiredFiles(targetpath);
NodesCompiler ns = (c as NodesCompiler);
ns.Parameters = parameters;
return ns;
}
catch(Exception e)
else
{
// Unable to copy files
General.ShowErrorMessage("Unable to copy the required files for the compiler (" + compiler.Name + "). " + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
// Nodebuilders must use a NodesCompiler!
throw new ArgumentException("Cannot create compiler interface '" + compiler.ProgramInterface + "' for nodebuilder '" + name + "'. Nodebuilders must use a NodesCompiler compiler interface!");
}
// Make arguments
args = parameters;
args = args.Replace("%F", inputfile);
args = args.Replace("%H", outputfile);
// Setup process info
processinfo = new ProcessStartInfo();
processinfo.Arguments = args;
processinfo.FileName = Path.Combine(targetpath, compiler.ProgramFile);
processinfo.CreateNoWindow = false;
processinfo.ErrorDialog = false;
processinfo.UseShellExecute = true;
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
processinfo.WorkingDirectory = targetpath;
// Output info
General.WriteLogLine("Running nodebuilder compiler '" + compiler.Name + "' with configuration '" + name + "'...");
General.WriteLogLine("Program: " + processinfo.FileName);
General.WriteLogLine("Arguments: " + processinfo.Arguments);
try
{
// Start the nodebuilder
process = Process.Start(processinfo);
}
catch(Exception e)
{
// Unable to start the nodebuilder
General.ShowErrorMessage("Unable to start the nodebuilder compiler (" + compiler.Name + ") . " + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
return false;
}
// Wait for nodebuilder to complete
process.WaitForExit();
deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks);
General.WriteLogLine("Nodebuilder compiler has finished.");
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
// Success!
return true;
}
#endregion

View file

@ -540,7 +540,8 @@ namespace CodeImp.DoomBuilder
{
NodebuilderInfo nodebuilder;
string tempfile1, tempfile2;
bool lumpnodebuild, lumpallowempty, lumpscomplete;
bool lumpnodebuild, lumpallowempty;
bool lumpscomplete = false;
WAD buildwad;
int srcindex;
@ -554,24 +555,19 @@ namespace CodeImp.DoomBuilder
}
else
{
// Make a temporary file for the nodebuilder
tempfile1 = General.MakeTempFilename(temppath);
General.WriteLogLine("Creating temporary build file: " + tempfile1);
buildwad = new WAD(tempfile1);
// Copy lumps to buildwad
General.WriteLogLine("Copying map lumps to temporary build file...");
CopyLumpsByType(tempwad, TEMP_MAP_HEADER, buildwad, BUILD_MAP_HEADER, true, false, false, true);
// Close buildwad
buildwad.Dispose();
// Create the compiler interface that will run the nodebuilder
// This automatically creates a temporary directory for us
NodesCompiler compiler = nodebuilder.CreateCompiler();
// Make temporary filename
tempfile1 = General.MakeTempFilename(compiler.Location);
// Does the nodebuilder require an output file?
if(nodebuilder.HasSpecialOutputFile)
{
// Make a temporary output file for the nodebuilder
tempfile2 = General.MakeTempFilename(temppath);
General.WriteLogLine("Creating temporary output file: " + tempfile2);
tempfile2 = General.MakeTempFilename(compiler.Location);
General.WriteLogLine("Temporary output file: " + tempfile2);
}
else
{
@ -579,12 +575,24 @@ namespace CodeImp.DoomBuilder
tempfile2 = tempfile1;
}
// Make the temporary WAD file
General.WriteLogLine("Creating temporary build file: " + tempfile1);
buildwad = new WAD(tempfile1);
// Copy lumps to buildwad
General.WriteLogLine("Copying map lumps to temporary build file...");
CopyLumpsByType(tempwad, TEMP_MAP_HEADER, buildwad, BUILD_MAP_HEADER, true, false, false, true);
// Close buildwad
buildwad.Dispose();
// Run the nodebuilder
if(nodebuilder.Run(temppath, Path.GetFileName(tempfile1), Path.GetFileName(tempfile2)))
compiler.OutputFile = Path.GetFileName(tempfile2);
if(compiler.CompileFile(Path.GetFileName(tempfile1)))
{
// Open the output file
buildwad = new WAD(tempfile2);
// Find the map header in source
srcindex = buildwad.FindLumpIndex(BUILD_MAP_HEADER);
if(srcindex > -1)
@ -634,21 +642,13 @@ namespace CodeImp.DoomBuilder
// Done with the build wad
buildwad.Dispose();
// Remove temp files
General.WriteLogLine("Removing temporary files...");
if(File.Exists(tempfile1)) File.Delete(tempfile1);
if(File.Exists(tempfile2)) File.Delete(tempfile2);
return lumpscomplete;
}
else
{
// Remove temp files
General.WriteLogLine("Removing temporary files...");
if(File.Exists(tempfile1)) File.Delete(tempfile1);
if(File.Exists(tempfile2)) File.Delete(tempfile2);
return false;
}
// Clean up
compiler.Dispose();
// Return result
return lumpscomplete;
}
}