mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Internal: moved script compilation logic to appropriate DataReaders.
This commit is contained in:
parent
b67ecc63ce
commit
65861d1e03
13 changed files with 566 additions and 501 deletions
|
@ -17,12 +17,14 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.ZDoom.Scripting;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -37,9 +39,18 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
private AcsParserSE parser; //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public bool SourceIsMapScriptsLump; //mxd
|
||||
internal AcsParserSE Parser { get { return parser; } } //mxd
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
// Constructor
|
||||
|
@ -71,31 +82,80 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
int line = 0;
|
||||
string sourcedir = Path.GetDirectoryName(sourcefile);
|
||||
|
||||
// Preprocess the file
|
||||
parser = new AcsParserSE
|
||||
{
|
||||
OnInclude = delegate(AcsParserSE se, string includefile, AcsParserSE.IncludeType includetype)
|
||||
{
|
||||
TextResourceData data = General.Map.Data.GetTextResourceData(includefile);
|
||||
if(data == null)
|
||||
{
|
||||
// Fial
|
||||
ReportError(new CompilerError("Unable to find include file \"" + includefile + "\""));
|
||||
}
|
||||
else
|
||||
{
|
||||
se.Parse(data, true, includetype, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
string inputfilepath = Path.Combine(this.tempdir.FullName, inputfile);
|
||||
using(FileStream stream = File.OpenRead(inputfilepath))
|
||||
{
|
||||
DataLocation dl = new DataLocation(DataLocation.RESOURCE_DIRECTORY, Path.GetDirectoryName(inputfile), false, false, false);
|
||||
TextResourceData data = new TextResourceData(stream, dl, inputfile, false);
|
||||
if(!parser.Parse(data, info.Files, true, AcsParserSE.IncludeType.NONE, false))
|
||||
{
|
||||
// Check for errors
|
||||
if(parser.HasError) ReportError(new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. External lumps should be libraries
|
||||
if(!SourceIsMapScriptsLump && !parser.IsLibrary)
|
||||
{
|
||||
ReportError(new CompilerError("External ACS files can only be compiled as libraries!", sourcefile));
|
||||
return true;
|
||||
}
|
||||
|
||||
//mxd. SCRIPTS lump can't be library
|
||||
if(SourceIsMapScriptsLump && parser.IsLibrary)
|
||||
{
|
||||
ReportError(new CompilerError("SCRIPTS lump can't be compiled as library!", sourcefile));
|
||||
return true;
|
||||
}
|
||||
|
||||
//mxd. Update script names if we are compiling the map SCRIPTS lump
|
||||
if(SourceIsMapScriptsLump)
|
||||
{
|
||||
General.Map.UpdateScriptNames(parser);
|
||||
}
|
||||
|
||||
//xabis
|
||||
// Copy includes from the resources into the compiler's folder, preserving relative pathing and naming
|
||||
if(CopyIncludesToWorkingDirectory) //mxd
|
||||
HashSet<string> includes = parser.GetIncludes(); //mxd
|
||||
foreach(string include in includes)
|
||||
{
|
||||
foreach(string include in includes)
|
||||
// Grab the script text from the resources
|
||||
TextResourceData data = General.Map.Data.GetTextResourceData(include);
|
||||
if(data != null && data.Stream != null)
|
||||
{
|
||||
// Grab the script text from the resources
|
||||
TextResourceData data = General.Map.Data.GetTextResourceData(include);
|
||||
if(data != null && data.Stream != null)
|
||||
// Pull the pk3 or directory sub folder out if applicable
|
||||
FileInfo fi = new FileInfo(Path.Combine(this.tempdir.FullName, include));
|
||||
|
||||
// Do not allow files to be overwritten, either accidentally or maliciously
|
||||
if(!fi.Exists)
|
||||
{
|
||||
// Pull the pk3 or directory sub folder out if applicable
|
||||
FileInfo fi = new FileInfo(Path.Combine(this.tempdir.FullName, include));
|
||||
General.WriteLogLine("Copying script include: " + include);
|
||||
|
||||
// Do not allow files to be overwritten, either accidentally or maliciously
|
||||
if(!fi.Exists)
|
||||
{
|
||||
General.WriteLogLine("Copying script include: " + include);
|
||||
// Create the directory path as needed
|
||||
if(!string.IsNullOrEmpty(fi.DirectoryName)) Directory.CreateDirectory(fi.DirectoryName);
|
||||
|
||||
// Create the directory path as needed
|
||||
if(!string.IsNullOrEmpty(fi.DirectoryName)) Directory.CreateDirectory(fi.DirectoryName);
|
||||
|
||||
// Dump the script into the target file
|
||||
BinaryReader reader = new BinaryReader(data.Stream);
|
||||
File.WriteAllBytes(fi.FullName, reader.ReadBytes((int)data.Stream.Length));
|
||||
}
|
||||
// Dump the script into the target file
|
||||
BinaryReader reader = new BinaryReader(data.Stream);
|
||||
File.WriteAllBytes(fi.FullName, reader.ReadBytes((int)data.Stream.Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +172,6 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
// Setup process info
|
||||
ProcessStartInfo processinfo = new ProcessStartInfo();
|
||||
processinfo.Arguments = args;
|
||||
//processinfo.FileName = Path.Combine(this.tempdir.FullName, info.ProgramFile);
|
||||
processinfo.FileName = Path.Combine(info.Path, info.ProgramFile); //mxd
|
||||
processinfo.CreateNoWindow = false;
|
||||
processinfo.ErrorDialog = false;
|
||||
|
@ -228,5 +287,4 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -24,7 +24,6 @@ using System.Reflection;
|
|||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Compilers
|
||||
|
@ -40,7 +39,6 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
protected string sourcefile;
|
||||
protected string outputfile;
|
||||
protected string inputfile;
|
||||
protected HashSet<string> includes; //mxd
|
||||
|
||||
// Files
|
||||
protected readonly DirectoryInfo tempdir;
|
||||
|
@ -61,8 +59,6 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
public string InputFile { get { return inputfile; } set { inputfile = value; } }
|
||||
public string OutputFile { get { return outputfile; } set { outputfile = value; } }
|
||||
public string Location { get { return tempdir.FullName; } }
|
||||
public HashSet<string> Includes { get { return includes; } set { includes = value; } } //mxd
|
||||
public bool CopyIncludesToWorkingDirectory; //mxd
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public CompilerError[] Errors { get { return errors.ToArray(); } }
|
||||
|
||||
|
@ -76,7 +72,6 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
// Initialize
|
||||
this.info = info;
|
||||
this.errors = new List<CompilerError>();
|
||||
this.includes = new HashSet<string>(StringComparer.OrdinalIgnoreCase); //mxd
|
||||
|
||||
General.WriteLogLine("Creating compiler \"" + info.Name + "\" on interface \"" + this.GetType().Name + "\"...");
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
config = newconfig; //mxd
|
||||
editor.SetupStyles(newconfig); //mxd
|
||||
List<CompilerError> errors = UpdateNavigator(); //mxd
|
||||
if(panel.ActiveTab == this) panel.ShowErrors(errors); //mxd
|
||||
if(panel.ActiveTab == this) panel.ShowErrors(errors, true); //mxd
|
||||
}
|
||||
|
||||
// Call this to set the tab title
|
||||
|
@ -296,7 +296,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
}
|
||||
|
||||
if(parser.HasError)
|
||||
panel.ShowErrors(new List<CompilerError> { new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine) });
|
||||
panel.ShowErrors(new List<CompilerError> { new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine) }, true);
|
||||
|
||||
return ScriptType.UNKNOWN;
|
||||
}
|
||||
|
@ -436,7 +436,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
//mxd
|
||||
private void functionbar_DropDown(object sender, EventArgs e)
|
||||
{
|
||||
if(editor.IsChanged) panel.ShowErrors(UpdateNavigator());
|
||||
if(editor.IsChanged) panel.ShowErrors(UpdateNavigator(), true);
|
||||
}
|
||||
|
||||
//mxd
|
||||
|
|
|
@ -121,8 +121,15 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Is this a script lump?
|
||||
if(maplumpinfo.ScriptBuild) //mxd
|
||||
{
|
||||
ScriptConfiguration config = General.GetScriptConfiguration(ScriptType.ACS);
|
||||
if(config == null)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Unable to find script configuration for \"" + ScriptType.ACS + "\" script type. Using plain text configuration.");
|
||||
config = new ScriptConfiguration();
|
||||
}
|
||||
|
||||
// Load this!
|
||||
ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler]);
|
||||
ScriptLumpDocumentTab t = new ScriptLumpDocumentTab(this, maplumpinfo.Name, config);
|
||||
|
||||
//mxd. Apply stored settings?
|
||||
if(General.Map.Options.ScriptLumpSettings.ContainsKey(maplumpinfo.Name))
|
||||
|
@ -198,7 +205,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
if(activetab != null)
|
||||
{
|
||||
List<CompilerError> errors = (General.Map.Errors.Count > 0 ? General.Map.Errors : activetab.UpdateNavigator());
|
||||
if(errors.Count > 0) ShowErrors(errors);
|
||||
if(errors.Count > 0) ShowErrors(errors, false);
|
||||
else ClearErrors();
|
||||
}
|
||||
else
|
||||
|
@ -421,13 +428,35 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
// This shows the errors panel with the given errors
|
||||
// Also updates the scripts with markers for the given errors
|
||||
public void ShowErrors(IEnumerable<CompilerError> errors)
|
||||
public void ShowErrors(IEnumerable<CompilerError> errors, bool combine)
|
||||
{
|
||||
// Copy list
|
||||
if(errors != null)
|
||||
compilererrors = new List<CompilerError>(errors);
|
||||
if(combine) //mxd
|
||||
{
|
||||
if(compilererrors == null) compilererrors = new List<CompilerError>();
|
||||
if(errors != null)
|
||||
{
|
||||
// Combine 2 error lists...
|
||||
foreach(CompilerError err in errors)
|
||||
{
|
||||
bool alreadyadded = false;
|
||||
foreach(CompilerError compilererror in compilererrors)
|
||||
{
|
||||
if(compilererror.Equals(err))
|
||||
{
|
||||
alreadyadded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!alreadyadded) compilererrors.Add(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
compilererrors = new List<CompilerError>();
|
||||
{
|
||||
compilererrors = (errors != null ? new List<CompilerError>(errors) : new List<CompilerError>());
|
||||
}
|
||||
|
||||
// Fill list
|
||||
errorlist.BeginUpdate();
|
||||
|
@ -991,26 +1020,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
ScriptDocumentTab tab = e.TabPage as ScriptDocumentTab;
|
||||
if(tab != null)
|
||||
{
|
||||
List<CompilerError> errors = tab.UpdateNavigator();
|
||||
|
||||
// Combine 2 error lists...
|
||||
foreach(CompilerError navigatorerror in errors)
|
||||
{
|
||||
bool alreadyadded = false;
|
||||
foreach(CompilerError compilererror in compilererrors)
|
||||
{
|
||||
if(compilererror.Equals(navigatorerror))
|
||||
{
|
||||
alreadyadded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!alreadyadded) compilererrors.Add(navigatorerror);
|
||||
}
|
||||
|
||||
// Show all errors...
|
||||
ShowErrors(compilererrors);
|
||||
ShowErrors(tab.UpdateNavigator(), true);
|
||||
}
|
||||
|
||||
UpdateToolbar(true);
|
||||
|
|
|
@ -23,7 +23,6 @@ using System.Windows.Forms;
|
|||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.ZDoom.Scripting;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -69,214 +68,16 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// This compiles the script file
|
||||
public override void Compile()
|
||||
{
|
||||
//mxd. ACS requires special handling...
|
||||
if(config.ScriptType == ScriptType.ACS)
|
||||
{
|
||||
CompileACS();
|
||||
return;
|
||||
}
|
||||
|
||||
Compiler compiler;
|
||||
//mxd. Compile
|
||||
List<CompilerError> errors = new List<CompilerError>();
|
||||
|
||||
try
|
||||
if(DirectoryReader.CompileScriptLump(filepathname, config, errors))
|
||||
{
|
||||
// Initialize compiler
|
||||
compiler = config.Compiler.Create();
|
||||
//mxd. Update script navigator
|
||||
errors.AddRange(UpdateNavigator());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
panel.ShowErrors(errors); //mxd
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy the source file into the temporary directory
|
||||
string inputfile = Path.Combine(compiler.Location, Path.GetFileName(filepathname));
|
||||
File.Copy(filepathname, inputfile);
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = config.Parameters;
|
||||
compiler.InputFile = Path.GetFileName(inputfile);
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.SourceFile = filepathname;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerr = e;
|
||||
|
||||
// If the error's filename equals our temporary file,
|
||||
// replace it with the original source filename
|
||||
if(string.Compare(e.filename, inputfile, true) == 0)
|
||||
newerr.filename = filepathname;
|
||||
|
||||
errors.Add(newerr);
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose compiler
|
||||
compiler.Dispose();
|
||||
|
||||
//mxd. Update script navigator
|
||||
errors.AddRange(UpdateNavigator());
|
||||
|
||||
// Feed errors to panel
|
||||
panel.ShowErrors(errors);
|
||||
}
|
||||
|
||||
//mxd. ACS requires special handling...
|
||||
private void CompileACS()
|
||||
{
|
||||
Compiler compiler;
|
||||
List<CompilerError> errors = new List<CompilerError>();
|
||||
string inputfile = Path.GetFileName(filepathname);
|
||||
|
||||
// Which compiler to use?
|
||||
ScriptConfiguration scriptconfig;
|
||||
if(!string.IsNullOrEmpty(General.Map.Options.ScriptCompiler))
|
||||
{
|
||||
// Boilderplate
|
||||
if(!General.CompiledScriptConfigs.ContainsKey(General.Map.Options.ScriptCompiler))
|
||||
{
|
||||
General.ShowErrorMessage("Unable to compile \"" + inputfile + "\". Unable to find required script compiler configuration (\"" + General.Map.Options.ScriptCompiler + "\").", MessageBoxButtons.OK);
|
||||
return;
|
||||
}
|
||||
|
||||
scriptconfig = General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler];
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptconfig = config;
|
||||
}
|
||||
|
||||
// Initialize compiler
|
||||
try
|
||||
{
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
panel.ShowErrors(errors);
|
||||
return;
|
||||
}
|
||||
|
||||
// Preprocess the file
|
||||
AcsParserSE parser = new AcsParserSE
|
||||
{
|
||||
OnInclude = delegate(AcsParserSE se, string includefile, AcsParserSE.IncludeType includetype)
|
||||
{
|
||||
TextResourceData data = General.Map.Data.GetTextResourceData(includefile);
|
||||
if(data == null)
|
||||
{
|
||||
// Fial
|
||||
errors.Add(new CompilerError("Unable to find include file \"" + includefile + "\""));
|
||||
panel.ShowErrors(errors);
|
||||
}
|
||||
else
|
||||
{
|
||||
se.Parse(data, true, includetype, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
using(FileStream stream = File.OpenRead(filepathname))
|
||||
{
|
||||
TextResourceData data = new TextResourceData(stream, new DataLocation(), filepathname, false);
|
||||
if(!parser.Parse(data, scriptconfig.Compiler.Files, true, AcsParserSE.IncludeType.NONE, false))
|
||||
{
|
||||
// Check for errors
|
||||
if(parser.HasError)
|
||||
{
|
||||
errors.Add(new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine));
|
||||
panel.ShowErrors(errors);
|
||||
}
|
||||
|
||||
compiler.Dispose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//mxd. Only works for libraries
|
||||
if(!parser.IsLibrary)
|
||||
{
|
||||
errors.Add(new CompilerError("External ACS files can only be compiled as libraries!", filepathname));
|
||||
panel.ShowErrors(errors);
|
||||
compiler.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = config.Parameters;
|
||||
compiler.InputFile = inputfile;
|
||||
compiler.OutputFile = outputfile;
|
||||
compiler.SourceFile = filepathname;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(filepathname);
|
||||
compiler.Includes = parser.GetIncludes();
|
||||
compiler.CopyIncludesToWorkingDirectory = false;
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerr = e;
|
||||
|
||||
// If the error's filename equals our temporary file,
|
||||
// replace it with the original source filename
|
||||
if(string.Compare(e.filename, inputfile, true) == 0)
|
||||
newerr.filename = filepathname;
|
||||
|
||||
errors.Add(newerr);
|
||||
}
|
||||
|
||||
// No errors and output file exists?
|
||||
if(compiler.Errors.Length == 0)
|
||||
{
|
||||
// Output file exists?
|
||||
if(!File.Exists(outputfile))
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Output file \"" + outputfile + "\" doesn't exist."));
|
||||
panel.ShowErrors(errors);
|
||||
return;
|
||||
}
|
||||
|
||||
// Rename and copy to source file directory
|
||||
string targetfilename = Path.Combine(Path.GetDirectoryName(filepathname), parser.LibraryName + ".o");
|
||||
try
|
||||
{
|
||||
File.Copy(outputfile, targetfilename, true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to create library file \"" + targetfilename + "\". " + e.GetType().Name + ": " + e.Message));
|
||||
panel.ShowErrors(errors);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose compiler
|
||||
compiler.Dispose();
|
||||
|
||||
// Update script navigator
|
||||
errors.AddRange(UpdateNavigator());
|
||||
|
||||
// Feed errors to panel
|
||||
panel.ShowErrors(errors);
|
||||
panel.ShowErrors(errors, false);
|
||||
}
|
||||
|
||||
// This checks if a script error applies to this script
|
||||
|
@ -348,7 +149,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
this.filepathname = filepathname;
|
||||
editor.ClearUndoRedo();
|
||||
SetTitle(Path.GetFileName(filepathname));
|
||||
panel.ShowErrors(UpdateNavigator()); //mxd
|
||||
panel.ShowErrors(UpdateNavigator(), true); //mxd
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
|
||||
|
@ -84,25 +85,23 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
// Compile script
|
||||
public override void Compile()
|
||||
{
|
||||
//mxd. List of errors. UpdateScriptNames can return errors and also updates acs includes list
|
||||
List<CompilerError> errors = (config.ScriptType == ScriptType.ACS ? General.Map.UpdateScriptNames(false) : new List<CompilerError>());
|
||||
|
||||
//mxd. Errors already?..
|
||||
if(errors.Count > 0)
|
||||
//mxd. Boilerplate
|
||||
if(!General.Map.Config.MapLumps.ContainsKey(lumpname))
|
||||
{
|
||||
// Feed errors to panel
|
||||
panel.ShowErrors(errors);
|
||||
General.ShowErrorMessage("Unable to compile lump \"" + lumpname + "\". This lump is not defined in the current game configuration.", MessageBoxButtons.OK);
|
||||
return;
|
||||
}
|
||||
|
||||
// Compile
|
||||
General.Map.CompileLump((ismapheader ? MapManager.CONFIG_MAP_HEADER : lumpname), true);
|
||||
|
||||
//mxd. Update script navigator
|
||||
errors = UpdateNavigator();
|
||||
List<CompilerError> errors = new List<CompilerError>();
|
||||
if(General.Map.TemporaryMapFile.CompileLump((ismapheader ? MapManager.CONFIG_MAP_HEADER : lumpname), config, errors))
|
||||
{
|
||||
//mxd. Update script navigator
|
||||
errors.AddRange(UpdateNavigator());
|
||||
}
|
||||
|
||||
// Feed errors to panel
|
||||
panel.ShowErrors(General.Map.Errors.Count > 0 ? General.Map.Errors : errors);
|
||||
panel.ShowErrors(errors, false);
|
||||
}
|
||||
|
||||
// Implicit save
|
||||
|
|
|
@ -275,8 +275,8 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
#region ================== Compiling (mxd)
|
||||
|
||||
internal abstract bool CompileLump(string lumpname, out List<CompilerError> errors);
|
||||
internal abstract bool CompileLump(string lumpname, int lumpindex, out List<CompilerError> errors);
|
||||
internal abstract bool CompileLump(string lumpname, ScriptConfiguration scriptconfig, List<CompilerError> errors);
|
||||
internal abstract bool CompileLump(string lumpname, int lumpindex, ScriptConfiguration scriptconfig, List<CompilerError> errors);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
|
||||
#endregion
|
||||
|
@ -513,10 +514,111 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// This compiles a script lump and returns any errors that may have occurred
|
||||
// Returns true when our code worked properly (even when the compiler returned errors)
|
||||
internal override bool CompileLump(string filename, int unused, out List<CompilerError> errors) { return CompileLump(filename, out errors); }
|
||||
internal override bool CompileLump(string lumpname, out List<CompilerError> errors)
|
||||
internal override bool CompileLump(string filepathname, int unused, ScriptConfiguration scriptconfig, List<CompilerError> errors) { return CompileLump(filepathname, scriptconfig, errors); }
|
||||
internal override bool CompileLump(string filepathname, ScriptConfiguration scriptconfig, List<CompilerError> errors)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return CompileScriptLump(filepathname, scriptconfig, errors);
|
||||
}
|
||||
|
||||
internal static bool CompileScriptLump(string filepathname, ScriptConfiguration scriptconfig, List<CompilerError> errors)
|
||||
{
|
||||
// No compiling required
|
||||
if(scriptconfig.Compiler == null) return true;
|
||||
|
||||
// Initialize compiler
|
||||
Compiler compiler;
|
||||
try
|
||||
{
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the source file into the temporary directory
|
||||
string inputfile = Path.Combine(compiler.Location, Path.GetFileName(filepathname));
|
||||
File.Copy(filepathname, inputfile);
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = scriptconfig.Parameters;
|
||||
compiler.InputFile = inputfile;
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.SourceFile = filepathname;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerr = e;
|
||||
|
||||
// If the error's filename equals our temporary file, replace it with the original source filename
|
||||
if(String.Compare(e.filename, inputfile, true) == 0) newerr.filename = filepathname;
|
||||
|
||||
errors.Add(newerr);
|
||||
}
|
||||
|
||||
// No errors and output file exists?
|
||||
if(compiler.Errors.Length == 0)
|
||||
{
|
||||
// Output file exists?
|
||||
if(!File.Exists(outputfile))
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Output file \"" + outputfile + "\" doesn't exist."));
|
||||
return false;
|
||||
}
|
||||
|
||||
//mxd. Move and rename the result file
|
||||
string targetfilename;
|
||||
if(compiler is AccCompiler)
|
||||
{
|
||||
AccCompiler acccompiler = (AccCompiler)compiler;
|
||||
targetfilename = Path.Combine(Path.GetDirectoryName(filepathname), acccompiler.Parser.LibraryName + ".o");
|
||||
}
|
||||
else
|
||||
{
|
||||
//mxd. No can't do...
|
||||
if(String.IsNullOrEmpty(scriptconfig.ResultLump))
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to create target file: unable to determine target filename. Make sure \"ResultLump\" property is set in the \"" + scriptconfig + "\" script configuration."));
|
||||
return false;
|
||||
}
|
||||
|
||||
targetfilename = Path.Combine(Path.GetDirectoryName(filepathname), scriptconfig.ResultLump);
|
||||
}
|
||||
|
||||
// Rename and copy to source file directory
|
||||
try
|
||||
{
|
||||
File.Copy(outputfile, targetfilename, true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to create library file \"" + targetfilename + "\". " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
compiler.Dispose();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -20,6 +20,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using SharpCompress.Archive; //mxd
|
||||
using SharpCompress.Archive.Zip;
|
||||
|
@ -580,10 +581,114 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// This compiles a script lump and returns any errors that may have occurred
|
||||
// Returns true when our code worked properly (even when the compiler returned errors)
|
||||
internal override bool CompileLump(string filename, int unused, out List<CompilerError> errors) { return CompileLump(filename, out errors); }
|
||||
internal override bool CompileLump(string filename, out List<CompilerError> errors)
|
||||
internal override bool CompileLump(string filename, int unused, ScriptConfiguration scriptconfig, List<CompilerError> errors) { return CompileLump(filename, scriptconfig, errors); }
|
||||
internal override bool CompileLump(string filename, ScriptConfiguration scriptconfig, List<CompilerError> errors)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// No compiling required
|
||||
if(scriptconfig.Compiler == null) return true;
|
||||
|
||||
// Initialize compiler
|
||||
Compiler compiler;
|
||||
try
|
||||
{
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract the source file into the temporary directory
|
||||
string inputfile = Path.Combine(compiler.Location, Path.GetFileName(filename));
|
||||
using(MemoryStream stream = LoadFile(filename))
|
||||
{
|
||||
File.WriteAllBytes(inputfile, stream.ToArray());
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = scriptconfig.Parameters;
|
||||
compiler.InputFile = inputfile;
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.SourceFile = inputfile;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerr = e;
|
||||
|
||||
// If the error's filename equals our temporary file, // replace it with the original source filename
|
||||
if(String.Compare(e.filename, inputfile, true) == 0) newerr.filename = filename;
|
||||
|
||||
errors.Add(newerr);
|
||||
}
|
||||
|
||||
// No errors and output file exists?
|
||||
if(compiler.Errors.Length == 0)
|
||||
{
|
||||
// Output file exists?
|
||||
if(!File.Exists(outputfile))
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Output file \"" + outputfile + "\" doesn't exist."));
|
||||
return false;
|
||||
}
|
||||
|
||||
//mxd. Move and rename the result file
|
||||
string targetfilename;
|
||||
if(compiler is AccCompiler)
|
||||
{
|
||||
AccCompiler acccompiler = (AccCompiler)compiler;
|
||||
targetfilename = Path.Combine(Path.GetDirectoryName(filename), acccompiler.Parser.LibraryName + ".o");
|
||||
}
|
||||
else
|
||||
{
|
||||
//mxd. No can't do...
|
||||
if(String.IsNullOrEmpty(scriptconfig.ResultLump))
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to create target file: unable to determine target filename. Make sure \"ResultLump\" property is set in the \"" + scriptconfig + "\" script configuration."));
|
||||
return false;
|
||||
}
|
||||
|
||||
targetfilename = Path.Combine(Path.GetDirectoryName(filename), scriptconfig.ResultLump);
|
||||
}
|
||||
|
||||
// Rename and add to source archive
|
||||
try
|
||||
{
|
||||
byte[] buffer = File.ReadAllBytes(outputfile);
|
||||
using(MemoryStream stream = new MemoryStream(buffer.Length))
|
||||
{
|
||||
stream.Write(buffer, 0, buffer.Length);
|
||||
SaveFile(stream, targetfilename);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to create library file \"" + targetfilename + "\". " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
compiler.Dispose();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace CodeImp.DoomBuilder.Data.Scripting
|
|||
target.Items.Clear();
|
||||
|
||||
AcsParserSE parser = new AcsParserSE { AddArgumentsToScriptNames = true, IsMapScriptsLump = tab is ScriptLumpDocumentTab, IgnoreErrors = true };
|
||||
TextResourceData data = new TextResourceData(stream, new DataLocation(), (parser.IsMapScriptsLump ? "?SCRIPTS" : tab.Filename), false);
|
||||
DataLocation dl = new DataLocation(DataLocation.RESOURCE_DIRECTORY, Path.GetDirectoryName(tab.Filename), false, false, false);
|
||||
TextResourceData data = new TextResourceData(stream, dl, (parser.IsMapScriptsLump ? "?SCRIPTS" : tab.Filename), false);
|
||||
|
||||
if(parser.Parse(data, false))
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.GZBuilder.Data;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.ZDoom;
|
||||
|
@ -1191,30 +1192,139 @@ namespace CodeImp.DoomBuilder.Data
|
|||
|
||||
// This compiles a script lump and returns any errors that may have occurred
|
||||
// Returns true when our code worked properly (even when the compiler returned errors)
|
||||
internal override bool CompileLump(string lumpname, out List<CompilerError> errors)
|
||||
internal override bool CompileLump(string lumpname, ScriptConfiguration scriptconfig, List<CompilerError> errors)
|
||||
{
|
||||
int index = file.FindLumpIndex(lumpname);
|
||||
if(index == -1)
|
||||
{
|
||||
errors = new List<CompilerError>
|
||||
{
|
||||
new CompilerError
|
||||
{
|
||||
description = "Lump \"" + lumpname + "\" does not exist",
|
||||
filename = this.location.GetDisplayName()
|
||||
}
|
||||
};
|
||||
errors.Add(new CompilerError { description = "Lump \"" + lumpname + "\" does not exist", filename = this.location.GetDisplayName() });
|
||||
return false;
|
||||
}
|
||||
|
||||
return CompileLump(lumpname, index, out errors);
|
||||
return CompileLump(lumpname, index, scriptconfig, errors);
|
||||
}
|
||||
|
||||
// This compiles a script lump and returns any errors that may have occurred
|
||||
// Returns true when our code worked properly (even when the compiler returned errors)
|
||||
internal override bool CompileLump(string lumpname, int lumpindex, out List<CompilerError> errors)
|
||||
internal override bool CompileLump(string lumpname, int lumpindex, ScriptConfiguration scriptconfig, List<CompilerError> errors)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// No compiling required
|
||||
if(scriptconfig.Compiler == null) return true;
|
||||
|
||||
string inputfile;
|
||||
Compiler compiler;
|
||||
string reallumpname = lumpname;
|
||||
|
||||
// Find the lump
|
||||
if(lumpname == MapManager.CONFIG_MAP_HEADER) reallumpname = MapManager.TEMP_MAP_HEADER;
|
||||
Lump lump = file.FindLump(reallumpname);
|
||||
if(lump == null)
|
||||
throw new Exception("Unable to find lump \"" + reallumpname + "\" to compile in \"" + location.GetDisplayName() + "\".");
|
||||
|
||||
// Determine source file
|
||||
string sourcefile = (General.Map.FilePathName.Length > 0 ? General.Map.FilePathName : file.Filename);
|
||||
|
||||
// Initialize compiler
|
||||
try
|
||||
{
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write lump data to temp script file in compiler's temp directory
|
||||
inputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
lump.Stream.Seek(0, SeekOrigin.Begin);
|
||||
BinaryReader reader = new BinaryReader(lump.Stream);
|
||||
File.WriteAllBytes(inputfile, reader.ReadBytes((int)lump.Stream.Length));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to write script to working file. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = scriptconfig.Parameters;
|
||||
compiler.InputFile = Path.GetFileName(inputfile);
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.SourceFile = sourcefile;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
|
||||
//mxd. AccCompiler requires some additional settings...
|
||||
if(scriptconfig.ScriptType == ScriptType.ACS)
|
||||
{
|
||||
AccCompiler acccompiler = compiler as AccCompiler;
|
||||
if(acccompiler != null)
|
||||
{
|
||||
acccompiler.SourceIsMapScriptsLump = (this == General.Map.TemporaryMapFile && lumpname == "SCRIPTS");
|
||||
}
|
||||
}
|
||||
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Process errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerror = e;
|
||||
|
||||
// If the error's filename equals our temporary file, use the lump name instead and prefix it with ?
|
||||
if(string.Compare(e.filename, inputfile, true) == 0) newerror.filename = "?" + reallumpname;
|
||||
|
||||
errors.Add(newerror);
|
||||
}
|
||||
|
||||
// No errors?
|
||||
if(compiler.Errors.Length == 0)
|
||||
{
|
||||
// Output file exists?
|
||||
if(File.Exists(outputfile))
|
||||
{
|
||||
// Copy output file data into a lump?
|
||||
if(!string.IsNullOrEmpty(scriptconfig.ResultLump))
|
||||
{
|
||||
// Do that now then
|
||||
byte[] filedata;
|
||||
|
||||
try
|
||||
{
|
||||
filedata = File.ReadAllBytes(outputfile);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to read compiler output file. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store data
|
||||
SaveFile(new MemoryStream(filedata), scriptconfig.ResultLump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
compiler.Dispose();
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -2075,6 +2075,30 @@ namespace CodeImp.DoomBuilder
|
|||
GetShortPathName(longpath, shortname, maxlen);
|
||||
return shortname.ToString();
|
||||
}
|
||||
|
||||
//mxd
|
||||
internal static ScriptConfiguration GetScriptConfiguration(ScriptType type)
|
||||
{
|
||||
if(type == ScriptType.ACS)
|
||||
{
|
||||
// Return map-defined compiler
|
||||
string compiler = (!string.IsNullOrEmpty(Map.Options.ScriptCompiler) ? Map.Options.ScriptCompiler : Map.ConfigSettings.DefaultScriptCompiler);
|
||||
foreach(KeyValuePair<string, ScriptConfiguration> group in scriptconfigs)
|
||||
{
|
||||
if(group.Key == compiler) return group.Value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just pick the first one from the list
|
||||
foreach(ScriptConfiguration cfg in scriptconfigs.Values)
|
||||
{
|
||||
if(cfg.ScriptType == type) return cfg;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -88,7 +88,6 @@ namespace CodeImp.DoomBuilder
|
|||
//mxd
|
||||
private Dictionary<string, ScriptItem> namedscripts;
|
||||
private Dictionary<int, ScriptItem> numberedscripts;
|
||||
private readonly HashSet<string> scriptincludes;
|
||||
|
||||
// Disposing
|
||||
private bool isdisposed;
|
||||
|
@ -161,7 +160,6 @@ namespace CodeImp.DoomBuilder
|
|||
//mxd
|
||||
numberedscripts = new Dictionary<int, ScriptItem>();
|
||||
namedscripts = new Dictionary<string, ScriptItem>(StringComparer.OrdinalIgnoreCase);
|
||||
scriptincludes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
// Disposer
|
||||
|
@ -275,6 +273,19 @@ namespace CodeImp.DoomBuilder
|
|||
configinfo.ApplyDefaults(config);
|
||||
General.Editing.UpdateCurrentEditModes();
|
||||
|
||||
//mxd. Check if default script compiler is required
|
||||
if(string.IsNullOrEmpty(configinfo.DefaultScriptCompiler))
|
||||
{
|
||||
foreach(MapLumpInfo info in config.MapLumps.Values)
|
||||
{
|
||||
if(info.ScriptBuild)
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Error, "\"DefaultScriptCompiler\" property is not set in \"" + configinfo + "\" game configuration. The editor may fail to compile ACC scripts.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create map data
|
||||
map = new MapSet();
|
||||
|
||||
|
@ -425,8 +436,8 @@ namespace CodeImp.DoomBuilder
|
|||
map.Update();
|
||||
thingsfilter.Update();
|
||||
|
||||
//mxd. Update includes list and script names
|
||||
UpdateScriptNames(true);
|
||||
//mxd. Update script names
|
||||
UpdateScriptNames();
|
||||
|
||||
//mxd. Restore selection groups
|
||||
options.ReadSelectionGroups();
|
||||
|
@ -517,8 +528,8 @@ namespace CodeImp.DoomBuilder
|
|||
// Skybox may've been changed
|
||||
data.SetupSkybox();
|
||||
|
||||
// Update includes list and script names
|
||||
UpdateScriptNames(true);
|
||||
// Update script names
|
||||
UpdateScriptNames();
|
||||
|
||||
// Restore selection groups
|
||||
options.ReadSelectionGroups();
|
||||
|
@ -752,7 +763,7 @@ namespace CodeImp.DoomBuilder
|
|||
// Show script window if there are any errors and we are going to test the map
|
||||
// and always update the errors on the scripts window.
|
||||
if((errors.Count > 0) && (scriptwindow == null) && (purpose == SavePurpose.Testing)) ShowScriptEditor();
|
||||
if(scriptwindow != null) scriptwindow.Editor.ShowErrors(errors);
|
||||
if(scriptwindow != null) scriptwindow.Editor.ShowErrors(errors, false);
|
||||
|
||||
// Only write the map and rebuild nodes when the actual map has changed
|
||||
// (not when only scripts have changed)
|
||||
|
@ -1960,179 +1971,19 @@ namespace CodeImp.DoomBuilder
|
|||
if(lumpinfo.Script != null || lumpinfo.ScriptBuild)
|
||||
{
|
||||
// Compile it now
|
||||
success &= CompileLump(lumpinfo.Name, false);
|
||||
success &= tempwadreader.CompileLump(lumpinfo.Name, lumpinfo.Script, errors);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// This compiles a script lump and returns any errors that may have occurred
|
||||
// Returns true when our code worked properly (even when the compiler returned errors)
|
||||
internal bool CompileLump(string lumpname, bool clearerrors)
|
||||
//mxd. Update script numbers and names
|
||||
private void UpdateScriptNames()
|
||||
{
|
||||
//mxd. Boilerplate
|
||||
if(!config.MapLumps.ContainsKey(lumpname))
|
||||
{
|
||||
General.ShowErrorMessage("Unable to compile lump \"" + lumpname + "\". This lump is not defined in the current game configuration.", MessageBoxButtons.OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
string inputfile;
|
||||
Compiler compiler;
|
||||
string reallumpname = lumpname;
|
||||
|
||||
//mxd. Does lump require compiling?
|
||||
ScriptConfiguration scriptconfig;
|
||||
if(config.MapLumps[lumpname].ScriptBuild)
|
||||
{
|
||||
//mxd. More boilderplate
|
||||
if(!General.CompiledScriptConfigs.ContainsKey(General.Map.Options.ScriptCompiler))
|
||||
{
|
||||
General.ShowErrorMessage("Unable to compile lump \"" + lumpname + "\". Unable to find required script compiler configuration (\"" + General.Map.Options.ScriptCompiler + "\").", MessageBoxButtons.OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
scriptconfig = General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler];
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptconfig = config.MapLumps[lumpname].Script;
|
||||
}
|
||||
if(scriptconfig.Compiler == null) return true;
|
||||
|
||||
// Find the lump
|
||||
if(lumpname == CONFIG_MAP_HEADER) reallumpname = TEMP_MAP_HEADER;
|
||||
Lump lump = tempwadreader.WadFile.FindLump(reallumpname);
|
||||
if(lump == null) throw new Exception("No such lump in temporary wad file \"" + reallumpname + "\".");
|
||||
|
||||
// Determine source file
|
||||
string sourcefile = (filepathname.Length > 0 ? filepathname : tempwadreader.WadFile.Filename);
|
||||
|
||||
// New list of errors
|
||||
if(clearerrors) errors.Clear();
|
||||
|
||||
// Determine the script configuration to use
|
||||
try
|
||||
{
|
||||
// Initialize compiler
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write lump data to temp script file in compiler's temp directory
|
||||
inputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
lump.Stream.Seek(0, SeekOrigin.Begin);
|
||||
BinaryReader reader = new BinaryReader(lump.Stream);
|
||||
File.WriteAllBytes(inputfile, reader.ReadBytes((int)lump.Stream.Length));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to write script to working file. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
string outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = scriptconfig.Parameters;
|
||||
compiler.InputFile = Path.GetFileName(inputfile);
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.SourceFile = sourcefile;
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
|
||||
//mxd
|
||||
if(scriptconfig.ScriptType == ScriptType.ACS)
|
||||
{
|
||||
compiler.Includes = scriptincludes;
|
||||
compiler.CopyIncludesToWorkingDirectory = true;
|
||||
}
|
||||
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Process errors
|
||||
foreach(CompilerError e in compiler.Errors)
|
||||
{
|
||||
CompilerError newerror = e;
|
||||
|
||||
// If the error's filename equals our temporary file,
|
||||
// use the lump name instead and prefix it with ?
|
||||
if(string.Compare(e.filename, inputfile, true) == 0)
|
||||
newerror.filename = "?" + reallumpname;
|
||||
|
||||
errors.Add(newerror);
|
||||
}
|
||||
|
||||
// No errors?
|
||||
if(compiler.Errors.Length == 0)
|
||||
{
|
||||
// Output file exists?
|
||||
if(File.Exists(outputfile))
|
||||
{
|
||||
// Copy output file data into a lump?
|
||||
if(!string.IsNullOrEmpty(scriptconfig.ResultLump))
|
||||
{
|
||||
// Do that now then
|
||||
byte[] filedata;
|
||||
|
||||
try
|
||||
{
|
||||
filedata = File.ReadAllBytes(outputfile);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to read compiler output file. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store data
|
||||
MemoryStream stream = new MemoryStream(filedata);
|
||||
SetLumpData(scriptconfig.ResultLump, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
compiler.Dispose();
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Clear(); //mxd
|
||||
return false;
|
||||
}
|
||||
|
||||
// This clears all compiler errors
|
||||
/*internal void ClearCompilerErrors()
|
||||
{
|
||||
errors.Clear();
|
||||
}*/
|
||||
|
||||
//mxd. Update includes list and script names
|
||||
internal List<CompilerError> UpdateScriptNames(bool logerrors)
|
||||
{
|
||||
List<ScriptItem> namedscriptslist = new List<ScriptItem>();
|
||||
List<ScriptItem> numberedscriptslist = new List<ScriptItem>();
|
||||
List<string> scripincludeslist = new List<string>();
|
||||
List<CompilerError> compilererrors = new List<CompilerError>();
|
||||
General.Map.Data.TextResources[ScriptType.ACS] = new HashSet<TextResource>();
|
||||
|
||||
// Load the script lumps
|
||||
// Find SCRIPTS lump and parse it
|
||||
foreach(MapLumpInfo maplumpinfo in config.MapLumps.Values)
|
||||
{
|
||||
// Is this a script lump?
|
||||
|
@ -2147,9 +1998,9 @@ namespace CodeImp.DoomBuilder
|
|||
string error = "Unable to compile lump \"" + maplumpinfo.Name +
|
||||
"\". Unable to find required script compiler configuration (\"" +
|
||||
General.Map.Options.ScriptCompiler + "\").";
|
||||
compilererrors.Add(new CompilerError(error));
|
||||
if(logerrors) General.ErrorLogger.Add(ErrorType.Error, error);
|
||||
return compilererrors;
|
||||
|
||||
General.ErrorLogger.Add(ErrorType.Error, error);
|
||||
return;
|
||||
}
|
||||
|
||||
scriptconfig = General.CompiledScriptConfigs[General.Map.Options.ScriptCompiler];
|
||||
|
@ -2161,7 +2012,7 @@ namespace CodeImp.DoomBuilder
|
|||
|
||||
// Load the lump data
|
||||
MemoryStream stream = GetLumpData(maplumpinfo.Name);
|
||||
if(stream != null && stream.Length > 0 && scriptconfig != null && scriptconfig.Compiler != null)
|
||||
if(stream != null && stream.Length > 0 && scriptconfig != null && scriptconfig.Compiler != null && scriptconfig.ScriptType == ScriptType.ACS)
|
||||
{
|
||||
// Get script names
|
||||
AcsParserSE parser = new AcsParserSE
|
||||
|
@ -2188,52 +2039,60 @@ namespace CodeImp.DoomBuilder
|
|||
TextResourceData data = new TextResourceData(stream, location, "?SCRIPTS", false);
|
||||
if(parser.Parse(data, scriptconfig.Compiler.Files, true, AcsParserSE.IncludeType.NONE, false))
|
||||
{
|
||||
// Add them to arrays
|
||||
namedscriptslist.AddRange(parser.NamedScripts);
|
||||
numberedscriptslist.AddRange(parser.NumberedScripts);
|
||||
scripincludeslist.AddRange(parser.GetIncludes());
|
||||
|
||||
// Add to text resource list
|
||||
General.Map.Data.TextResources[parser.ScriptType].UnionWith(parser.TextResources.Values);
|
||||
|
||||
// Update the names
|
||||
UpdateScriptNames(parser);
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if(parser.HasError)
|
||||
else
|
||||
{
|
||||
compilererrors.Add(new CompilerError(parser.ErrorDescription, parser.ErrorSource, parser.ErrorLine));
|
||||
if(logerrors) parser.LogError();
|
||||
break;
|
||||
// Clear collections
|
||||
namedscripts.Clear();
|
||||
numberedscripts.Clear();
|
||||
}
|
||||
|
||||
// Log errors, if any
|
||||
if(parser.HasError) parser.LogError();
|
||||
|
||||
// Done here
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add to collections
|
||||
scriptincludes.Clear();
|
||||
if(compilererrors.Count == 0)
|
||||
{
|
||||
namedscripts = new Dictionary<string, ScriptItem>(namedscriptslist.Count);
|
||||
numberedscripts = new Dictionary<int, ScriptItem>(numberedscriptslist.Count);
|
||||
|
||||
// Sort script names
|
||||
namedscriptslist.Sort(ScriptItem.SortByName);
|
||||
numberedscriptslist.Sort(ScriptItem.SortByIndex);
|
||||
|
||||
foreach(ScriptItem item in namedscriptslist)
|
||||
if(!namedscripts.ContainsKey(item.Name.ToLowerInvariant())) namedscripts.Add(item.Name.ToLowerInvariant(), item);
|
||||
foreach(ScriptItem item in numberedscriptslist)
|
||||
if(!numberedscripts.ContainsKey(item.Index)) numberedscripts.Add(item.Index, item);
|
||||
foreach(string include in scripincludeslist)
|
||||
if(!scriptincludes.Contains(include)) scriptincludes.Add(include);
|
||||
}
|
||||
else
|
||||
//mxd
|
||||
internal void UpdateScriptNames(AcsParserSE parser)
|
||||
{
|
||||
if(parser.HasError)
|
||||
{
|
||||
// Clear collections
|
||||
namedscripts.Clear();
|
||||
numberedscripts.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add to collections
|
||||
namedscripts = new Dictionary<string, ScriptItem>(parser.NamedScripts.Count);
|
||||
numberedscripts = new Dictionary<int, ScriptItem>(parser.NumberedScripts.Count);
|
||||
|
||||
return compilererrors;
|
||||
// Sort script names
|
||||
parser.NamedScripts.Sort(ScriptItem.SortByName);
|
||||
parser.NumberedScripts.Sort(ScriptItem.SortByIndex);
|
||||
|
||||
foreach(ScriptItem item in parser.NamedScripts)
|
||||
{
|
||||
if(!namedscripts.ContainsKey(item.Name.ToLowerInvariant()))
|
||||
namedscripts.Add(item.Name.ToLowerInvariant(), item);
|
||||
}
|
||||
|
||||
foreach(ScriptItem item in parser.NumberedScripts)
|
||||
{
|
||||
if(!numberedscripts.ContainsKey(item.Index))
|
||||
numberedscripts.Add(item.Index, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -2389,8 +2248,8 @@ namespace CodeImp.DoomBuilder
|
|||
General.MainWindow.DisplayStatus(oldstatus);
|
||||
Cursor.Current = oldcursor;
|
||||
|
||||
//mxd. Update includes list and script names
|
||||
UpdateScriptNames(true);
|
||||
//mxd. Update script names
|
||||
UpdateScriptNames();
|
||||
}
|
||||
|
||||
// Game Configuration action
|
||||
|
|
Loading…
Reference in a new issue