From 5ddbd73916657a0c871c08e8ac0a78dde8aacac4 Mon Sep 17 00:00:00 2001
From: biwa <6475593+biwa@users.noreply.github.com>
Date: Sun, 21 Jun 2020 12:52:36 +0200
Subject: [PATCH] Sectors Mode: the sectors things are in are only determined
 if necessary, which should increase performance when switching into Sectors
 Mode in very big maps

---
 Source/Core/Map/Thing.cs                      | 16 +++++++
 .../BuilderModes/ClassicModes/SectorsMode.cs  | 47 +++++++++++++++----
 2 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/Source/Core/Map/Thing.cs b/Source/Core/Map/Thing.cs
index edca715be..23e44224c 100755
--- a/Source/Core/Map/Thing.cs
+++ b/Source/Core/Map/Thing.cs
@@ -266,6 +266,22 @@ namespace CodeImp.DoomBuilder.Map
 			sector = map.GetSectorByCoordinates(pos);
 		}
 
+		/// <summary>
+		/// Determines what sector a thing is in, given a blockmap
+		/// </summary>
+		/// <param name="blockmap">The blockmap to use</param>
+		public void DetermineSector(BlockMap<BlockEntry> blockmap)
+		{
+			BlockEntry be = blockmap.GetBlockAt(pos);
+
+			foreach (Sector s in be.Sectors)
+				if (s.Intersect(pos))
+				{
+					sector = s;
+					return;
+				}
+		}
+
 		// This determines which sector the thing is in and links it
 		public void DetermineSector(VisualBlockMap blockmap)
 		{
diff --git a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
index 82b6c3610..2d6f93ac3 100755
--- a/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
+++ b/Source/Plugins/BuilderModes/ClassicModes/SectorsMode.cs
@@ -69,8 +69,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
 		//mxd. Cached overlays stuff
 		private FlatVertex[] overlayGeometry;
 		private Dictionary<Sector, string[]> selectedEffectLabels;
-		private Dictionary<Sector, string[]> unselectedEffectLabels; 
-		
+		private Dictionary<Sector, string[]> unselectedEffectLabels;
+
+		// The blockmap makes synchronized editing faster
+		BlockMap<BlockEntry> blockmap;
+
 		#endregion
 
 		#region ================== Properties
@@ -542,8 +545,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
 					//mxd. Also (de)select things?
 					if(General.Interface.AltState ^ BuilderPlug.Me.SyncronizeThingEdit)
 					{
-						foreach(Thing t in General.Map.Map.Things) 
-							if(t.Sector == s && t.Selected != s.Selected) t.Selected = s.Selected;
+						List<BlockEntry> belist = blockmap.GetSquareRange(s.BBox);
+
+						foreach(BlockEntry be in belist)
+						{
+							foreach(Thing t in be.Things)
+							{
+								if (t.Sector == null)
+									t.DetermineSector(blockmap);
+
+								if (t.Sector == s && t.Selected != s.Selected) t.Selected = s.Selected;
+							}
+						}
+						//foreach(Thing t in General.Map.Map.Things) 
+						//	if(t.Sector == s && t.Selected != s.Selected) t.Selected = s.Selected;
 					}
 
 					if(update) 
@@ -723,19 +738,31 @@ namespace CodeImp.DoomBuilder.BuilderModes
 			//mxd. Update the tooltip
 			BuilderPlug.Me.MenusForm.SyncronizeThingEditButton.ToolTipText = "Synchronized Things Editing" + Environment.NewLine + BuilderPlug.Me.MenusForm.SyncronizeThingEditSectorsItem.ToolTipText;
 
-			//mxd. Determine thing sectors. Cause SyncronizeThingEdit requires that
-			foreach(Thing t in General.Map.Map.Things) t.DetermineSector();
+			// Create the blockmap
+			RectangleF area = MapSet.CreateArea(General.Map.Map.Vertices);
+			area = MapSet.IncreaseArea(area, General.Map.Map.Things);
+			blockmap = new BlockMap<BlockEntry>(area);
+			blockmap.AddSectorsSet(General.Map.Map.Sectors);
+			blockmap.AddThingsSet(General.Map.Map.Things);
 
 			//mxd. Select things as well?
 			if(BuilderPlug.Me.SyncronizeThingEdit)
 			{
 				ICollection<Sector> sectors = General.Map.Map.GetSelectedSectors(true);
-				if(sectors.Count > 0)
+
+				foreach(Sector s in sectors)
 				{
-					foreach(Thing t in General.Map.Map.Things)
+					List<BlockEntry> belist = blockmap.GetSquareRange(s.BBox);
+
+					foreach (BlockEntry be in belist)
 					{
-						if(!t.Selected && t.Sector != null && sectors.Contains(t.Sector))
-							t.Selected = true;
+						foreach (Thing t in be.Things)
+						{
+							if (t.Sector == null)
+								t.DetermineSector(blockmap);
+
+							if (t.Sector == s && t.Selected != s.Selected) t.Selected = s.Selected;
+						}
 					}
 				}
 			}
-- 
GitLab