From 1479e23ed99def7488e4c5b62d947fb42cf92595 Mon Sep 17 00:00:00 2001 From: MaxED <j.maxed@gmail.com> Date: Mon, 25 Jan 2016 14:39:55 +0000 Subject: [PATCH] Merged changes from DB2 R2482. --- Source/Core/General/MapManager.cs | 198 +++++++++++------- Source/Core/Plugins/Plug.cs | 7 + Source/Core/Plugins/PluginManager.cs | 3 +- Source/Plugins/NodesViewer/NodesForm.cs | 2 +- Source/Plugins/NodesViewer/NodesViewerMode.cs | 24 +-- 5 files changed, 132 insertions(+), 102 deletions(-) diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index e029e828d..4a2449bc7 100644 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -634,7 +634,93 @@ namespace CodeImp.DoomBuilder /// </summary> public bool ExportToFile(string filepathname) { - return SaveMap(filepathname, SavePurpose.Testing); + General.Plugins.OnMapSaveBegin(SavePurpose.Testing); + bool result = SaveMap(filepathname, SavePurpose.Testing); + General.Plugins.OnMapSaveEnd(SavePurpose.Testing); + return result; + } + + /// <summary> + /// This writes the map structures to the temporary file. + /// </summary> + private bool WriteMapToTempFile() + { + StatusInfo oldstatus = General.MainWindow.Status; + + // Make a copy of the map data + MapSet outputset = map.Clone(); + + // Remove all flags from all 3D Start things + foreach(Thing t in outputset.Things) + { + if(t.Type == config.Start3DModeThingType) + { + // We're not using SetFlag here, this doesn't have to be undone. + // Please note that this is totally exceptional! + List<string> flagkeys = new List<string>(t.Flags.Keys); + foreach(string k in flagkeys) t.Flags[k] = false; + } + } + + // Do we need sidedefs compression? + if(map.Sidedefs.Count > io.MaxSidedefs) + { + // Compress sidedefs + General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs..."); + outputset.CompressSidedefs(); + + // Check if it still doesnt fit + if(outputset.Sidedefs.Count > io.MaxSidedefs) + { + // Problem! Can't save the map like this! + General.ShowErrorMessage("Unable to save the map: There are too many unique sidedefs!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + } + + // Check things + if(map.Things.Count > io.MaxThings) + { + General.ShowErrorMessage("Unable to save the map: There are too many things!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // Check sectors + if(map.Sectors.Count > io.MaxSectors) + { + General.ShowErrorMessage("Unable to save the map: There are too many sectors!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // Check linedefs + if(map.Linedefs.Count > io.MaxLinedefs) + { + General.ShowErrorMessage("Unable to save the map: There are too many linedefs!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // Check vertices + if(map.Vertices.Count > io.MaxVertices) + { + General.ShowErrorMessage("Unable to save the map: There are too many vertices!", MessageBoxButtons.OK); + General.MainWindow.DisplayStatus(oldstatus); + return false; + } + + // TODO: Check for more limitations + + // Write to temporary file + General.WriteLogLine("Writing map data structures to file..."); + int index = Math.Max(0, tempwad.FindLumpIndex(TEMP_MAP_HEADER)); + io.Write(outputset, TEMP_MAP_HEADER, index); + outputset.Dispose(); + + General.MainWindow.DisplayStatus(oldstatus); + return true; } // Initializes for an existing map @@ -642,7 +728,6 @@ namespace CodeImp.DoomBuilder { string settingsfile; WAD targetwad; - int index; bool includenodes; General.WriteLogLine("Saving map to file: " + newfilepathname); @@ -673,82 +758,14 @@ namespace CodeImp.DoomBuilder // (not when only scripts have changed) if(changed) { - // Make a copy of the map data - MapSet outputset = map.Clone(); - - // Remove all flags from all 3D Start things - foreach(Thing t in outputset.Things) - { - if(t.Type == config.Start3DModeThingType) - { - // We're not using SetFlag here, this doesn't have to be undone. - // Please note that this is totally exceptional! - List<string> flagkeys = new List<string>(t.Flags.Keys); - foreach(string k in flagkeys) t.Flags[k] = false; - } - } - - // Do we need sidedefs compression? - StatusInfo oldstatus; - if(map.Sidedefs.Count > io.MaxSidedefs) - { - // Compress sidedefs - oldstatus = General.MainWindow.Status; - General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs..."); - outputset.CompressSidedefs(); - General.MainWindow.DisplayStatus(oldstatus); - - // Check if it still doesnt fit - if(outputset.Sidedefs.Count > io.MaxSidedefs) - { - // Problem! Can't save the map like this! - General.ShowErrorMessage("Unable to save the map: There are too many unique sidedefs!", MessageBoxButtons.OK); - return false; - } - } - - // Check things - if(map.Things.Count > io.MaxThings) - { - General.ShowErrorMessage("Unable to save the map: There are too many things!", MessageBoxButtons.OK); - return false; - } - - // Check sectors - if(map.Sectors.Count > io.MaxSectors) - { - General.ShowErrorMessage("Unable to save the map: There are too many sectors!", MessageBoxButtons.OK); - return false; - } - - // Check linedefs - if(map.Linedefs.Count > io.MaxLinedefs) - { - General.ShowErrorMessage("Unable to save the map: There are too many linedefs!", MessageBoxButtons.OK); - return false; - } - - // Check vertices - if(map.Vertices.Count > io.MaxVertices) - { - General.ShowErrorMessage("Unable to save the map: There are too many vertices!", MessageBoxButtons.OK); - return false; - } - - // TODO: Check for more limitations - - // Write to temporary file - General.WriteLogLine("Writing map data structures to file..."); - index = tempwad.FindLumpIndex(TEMP_MAP_HEADER); - if(index == -1) index = 0; - io.Write(outputset, TEMP_MAP_HEADER, index); - outputset.Dispose(); + // Write the current map structures to the temp file + if(!WriteMapToTempFile()) return false; // Get the corresponding nodebuilder string nodebuildername = (purpose == SavePurpose.Testing) ? configinfo.NodebuilderTest : configinfo.NodebuilderSave; // Build the nodes - oldstatus = General.MainWindow.Status; + StatusInfo oldstatus = General.MainWindow.Status; General.MainWindow.DisplayStatus(StatusType.Busy, "Building map nodes..."); includenodes = (!string.IsNullOrEmpty(nodebuildername) && BuildNodes(nodebuildername, true)); General.MainWindow.DisplayStatus(oldstatus); @@ -896,7 +913,7 @@ namespace CodeImp.DoomBuilder targetwad = new WAD(newfilepathname); } } - catch (IOException) + catch(IOException) { General.ShowErrorMessage("IO Error while writing target file: " + newfilepathname + ". Please make sure the location is accessible and not in use by another program.", MessageBoxButtons.OK); if(!string.IsNullOrEmpty(origwadfile) && File.Exists(origwadfile)) File.Delete(origwadfile); //mxd. Clean-up @@ -904,7 +921,7 @@ namespace CodeImp.DoomBuilder General.WriteLogLine("Map saving failed"); return false; } - catch (UnauthorizedAccessException) + catch(UnauthorizedAccessException) { General.ShowErrorMessage("Error while accessing target file: " + newfilepathname + ". Please make sure the location is accessible and not in use by another program.", MessageBoxButtons.OK); if(!string.IsNullOrEmpty(origwadfile) && File.Exists(origwadfile)) File.Delete(origwadfile); //mxd. Clean-up @@ -924,7 +941,7 @@ namespace CodeImp.DoomBuilder General.WriteLogLine("Changing map name from '" + options.PreviousName + "' to '" + options.CurrentName + "'"); // Find the map header in target - index = targetwad.FindLumpIndex(options.PreviousName); + int index = targetwad.FindLumpIndex(options.PreviousName); if(index > -1) { // Rename the map lump name @@ -967,7 +984,7 @@ namespace CodeImp.DoomBuilder settingsfile = newfilepathname.Substring(0, newfilepathname.Length - 4) + ".dbs"; options.WriteConfiguration(settingsfile); } - catch (Exception e) + catch(Exception e) { // Warning only General.ErrorLogger.Add(ErrorType.Warning, "Could not write the map settings configuration file. " + e.GetType().Name + ": " + e.Message); @@ -1056,6 +1073,30 @@ namespace CodeImp.DoomBuilder #region ================== Nodebuild + /// <summary> + /// This stores the current structures in memory to the temporary file and rebuilds the nodes. + /// The 'nodebuildername' must be a valid nodebuilder configuration profile. + /// Returns True on success, False when failed. + /// </summary> + public bool RebuildNodes(string nodebuildername, bool failaswarning) + { + bool result; + + // Write the current map structures to the temp file + if(!WriteMapToTempFile()) return false; + + // Build the nodes + StatusInfo oldstatus = General.MainWindow.Status; + General.MainWindow.DisplayStatus(StatusType.Busy, "Building map nodes..."); + if(!string.IsNullOrEmpty(nodebuildername)) + result = BuildNodes(nodebuildername, failaswarning); + else + result = false; + General.MainWindow.DisplayStatus(oldstatus); + + return result; + } + // This builds the nodes in the temproary file with the given configuration name private bool BuildNodes(string nodebuildername, bool failaswarning) { @@ -1178,6 +1219,9 @@ namespace CodeImp.DoomBuilder // Clean up compiler.Dispose(); + // Let the plugins know + if(lumpscomplete) General.Plugins.OnMapNodesRebuilt(); + // Return result return lumpscomplete; } diff --git a/Source/Core/Plugins/Plug.cs b/Source/Core/Plugins/Plug.cs index 9edf7b989..cbffaf5c8 100644 --- a/Source/Core/Plugins/Plug.cs +++ b/Source/Core/Plugins/Plug.cs @@ -308,6 +308,13 @@ namespace CodeImp.DoomBuilder.Plugins /// </summary> public virtual void OnEditAccept() { } + /// <summary> + /// Called just after the nodes have been (re)built. This allows a plugin to intervene with + /// the nodebuilder output using GetLumpData and SetLumpData. If the map is being saved, this + /// is called after the nodes are rebuilt and just before they are stored in the target file. + /// </summary> + public virtual void OnMapNodesRebuilt() { } + // Interface events public virtual void OnEditMouseClick(MouseEventArgs e) { } public virtual void OnEditMouseDoubleClick(MouseEventArgs e) { } diff --git a/Source/Core/Plugins/PluginManager.cs b/Source/Core/Plugins/PluginManager.cs index d89052926..2e2b41a61 100644 --- a/Source/Core/Plugins/PluginManager.cs +++ b/Source/Core/Plugins/PluginManager.cs @@ -301,8 +301,9 @@ namespace CodeImp.DoomBuilder.Plugins public void OnEditRedrawDisplayBegin() { foreach(Plugin p in plugins) p.Plug.OnEditRedrawDisplayBegin(); } public void OnEditRedrawDisplayEnd() { foreach(Plugin p in plugins) p.Plug.OnEditRedrawDisplayEnd(); } public void OnPresentDisplayBegin() { foreach(Plugin p in plugins) p.Plug.OnPresentDisplayBegin(); } + public void OnMapNodesRebuilt() { foreach(Plugin p in plugins) p.Plug.OnMapNodesRebuilt(); } - //mxd. Hilight events + //mxd. Highlight events public void OnHighlightSector(Sector s) { foreach(Plugin p in plugins) p.Plug.OnHighlightSector(s); } public void OnHighlightLinedef(Linedef l) { foreach(Plugin p in plugins) p.Plug.OnHighlightLinedef(l); } public void OnHighlightThing(Thing t) { foreach(Plugin p in plugins) p.Plug.OnHighlightThing(t); } diff --git a/Source/Plugins/NodesViewer/NodesForm.cs b/Source/Plugins/NodesViewer/NodesForm.cs index 641a5beb3..c42d8f42f 100644 --- a/Source/Plugins/NodesViewer/NodesForm.cs +++ b/Source/Plugins/NodesViewer/NodesForm.cs @@ -160,7 +160,7 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer // (Re)build the nodes private void buildnodesbutton_Click(object sender, EventArgs e) { - mode.BuildNodes(); + General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true); // Restart the mode so that the new structures are loaded in. // This will automatically close and re-open this window. diff --git a/Source/Plugins/NodesViewer/NodesViewerMode.cs b/Source/Plugins/NodesViewer/NodesViewerMode.cs index 5d4a61072..c99a18a17 100644 --- a/Source/Plugins/NodesViewer/NodesViewerMode.cs +++ b/Source/Plugins/NodesViewer/NodesViewerMode.cs @@ -85,20 +85,6 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer #region ================== Methods - /// <summary> - /// This (re)builds the nodes for the whole map. - /// </summary> - public void BuildNodes() - { - // There is no API available to do this directly, but we export the map which will - // cause the DB core to build the nodes (with testing parameters) - General.Interface.DisplayStatus(StatusType.Busy, "Building map nodes..."); - string tempfile = BuilderPlug.MakeTempFilename(".wad"); - General.Map.IsChanged = true; - General.Map.ExportToFile(tempfile); - File.Delete(tempfile); - } - /// <summary> /// This loads all nodes structures data from the lumps /// </summary> @@ -810,14 +796,6 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer Cursor.Current = Cursors.WaitCursor; base.OnEngage(); - //mxd. General.Map.ExportToFile in BuildNodes() won't do the trick if the map was never saved - if(string.IsNullOrEmpty(General.Map.FilePathName)) - { - MessageBox.Show("Please save the map before running Nodes Viewer mode.", "Nodes Viewer mode", MessageBoxButtons.OK, MessageBoxIcon.Error); - General.Editing.CancelMode(); - return; - } - //mxd bool haveNodes = General.Map.LumpExists("NODES"); bool haveZnodes = General.Map.LumpExists("ZNODES"); @@ -828,7 +806,7 @@ namespace CodeImp.DoomBuilder.Plugins.NodesViewer if(General.Map.IsChanged || !(haveZnodes || (haveNodes || haveSectors || haveSegs || haveVerts))) { // We need to build the nodes! - BuildNodes(); + if(!General.Map.RebuildNodes(General.Map.ConfigSettings.NodebuilderSave, true)) return; //mxd. Update nodes availability haveNodes = General.Map.LumpExists("NODES"); -- GitLab