From a418868dfd6cf58095b77f8ba43b720f6ef745c9 Mon Sep 17 00:00:00 2001 From: codeimp Date: Fri, 2 Dec 2011 23:11:16 +0000 Subject: [PATCH] Fixed memory and performance issues in Visual Mode for things with 0 with or height. (note to developers: VisualMode::GetVisualThing(t) may return null!) --- Source/Core/VisualModes/VisualMode.cs | 27 +++---- .../VisualModes/BaseVisualMode.cs | 66 ++++++++++------- .../VisualModes/BaseVisualThing.cs | 24 +++---- .../VisualModes/BaseVisualMode.cs | 70 ++++++++++++------- .../VisualModes/BaseVisualThing.cs | 14 +++- 5 files changed, 123 insertions(+), 78 deletions(-) diff --git a/Source/Core/VisualModes/VisualMode.cs b/Source/Core/VisualModes/VisualMode.cs index 363f7983..7f6e858a 100644 --- a/Source/Core/VisualModes/VisualMode.cs +++ b/Source/Core/VisualModes/VisualMode.cs @@ -164,11 +164,11 @@ namespace CodeImp.DoomBuilder.VisualModes // Dispose foreach(KeyValuePair vs in allsectors) - vs.Value.Dispose(); + if(vs.Value != null) vs.Value.Dispose(); // Dispose foreach(KeyValuePair vt in allthings) - vt.Value.Dispose(); + if(vt.Value != null) vt.Value.Dispose(); // Apply camera position to thing General.Map.VisualCamera.ApplyToThing(); @@ -368,7 +368,7 @@ namespace CodeImp.DoomBuilder.VisualModes { // Create new visual thing vt = CreateVisualThing(t); - if(vt != null) allthings.Add(t, vt); + allthings.Add(t, vt); } if(vt != null) @@ -658,10 +658,10 @@ namespace CodeImp.DoomBuilder.VisualModes { // Dispose foreach(KeyValuePair vs in allsectors) - vs.Value.Dispose(); + if(vs.Value != null) vs.Value.Dispose(); foreach(KeyValuePair vt in allthings) - vt.Value.Dispose(); + if(vt.Value != null) vt.Value.Dispose(); // Clear collections allsectors.Clear(); @@ -724,16 +724,19 @@ namespace CodeImp.DoomBuilder.VisualModes // Dispose if source was disposed or marked foreach(KeyValuePair vs in allsectors) { - if(vs.Key.IsDisposed || vs.Key.Marked) - vs.Value.Dispose(); - else - newsectors.Add(vs.Key, vs.Value); + if(vs.Value != null) + { + if(vs.Key.IsDisposed || vs.Key.Marked) + vs.Value.Dispose(); + else + newsectors.Add(vs.Key, vs.Value); + } } // Things depend on the sector they are in and because we can't // easily determine which ones changed, we dispose all things foreach(KeyValuePair vt in allthings) - vt.Value.Dispose(); + if(vt.Value != null) vt.Value.Dispose(); // Apply new lists allsectors = newsectors; @@ -775,12 +778,12 @@ namespace CodeImp.DoomBuilder.VisualModes /// /// Returns True when a VisualSector has been created for the specified Sector. /// - public bool VisualSectorExists(Sector s) { return allsectors.ContainsKey(s); } + public bool VisualSectorExists(Sector s) { return allsectors.ContainsKey(s) && (allsectors[s] != null); } /// /// Returns True when a VisualThing has been created for the specified Thing. /// - public bool VisualThingExists(Thing t) { return allthings.ContainsKey(t); } + public bool VisualThingExists(Thing t) { return allthings.ContainsKey(t) && (allthings[t] != null); } /// /// This is called when the blockmap needs to be refilled, because it was invalidated. diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs index 3e0db9e9..02b9491f 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualMode.cs @@ -290,23 +290,29 @@ namespace CodeImp.DoomBuilder.BuilderModes selectedobjects = new List(); foreach(KeyValuePair vs in allsectors) { - BaseVisualSector bvs = (BaseVisualSector)vs.Value; - if((bvs.Floor != null) && bvs.Floor.Selected) selectedobjects.Add(bvs.Floor); - if((bvs.Ceiling != null) && bvs.Ceiling.Selected) selectedobjects.Add(bvs.Ceiling); - foreach(Sidedef sd in vs.Key.Sidedefs) + if(vs.Value != null) { - List sidedefgeos = bvs.GetSidedefGeometry(sd); - foreach(VisualGeometry sdg in sidedefgeos) + BaseVisualSector bvs = (BaseVisualSector)vs.Value; + if((bvs.Floor != null) && bvs.Floor.Selected) selectedobjects.Add(bvs.Floor); + if((bvs.Ceiling != null) && bvs.Ceiling.Selected) selectedobjects.Add(bvs.Ceiling); + foreach(Sidedef sd in vs.Key.Sidedefs) { - if(sdg.Selected) selectedobjects.Add((sdg as IVisualEventReceiver)); + List sidedefgeos = bvs.GetSidedefGeometry(sd); + foreach(VisualGeometry sdg in sidedefgeos) + { + if(sdg.Selected) selectedobjects.Add((sdg as IVisualEventReceiver)); + } } } } foreach(KeyValuePair vt in allthings) { - BaseVisualThing bvt = (BaseVisualThing)vt.Value; - if(bvt.Selected) selectedobjects.Add(bvt); + if(vt.Value != null) + { + BaseVisualThing bvt = (BaseVisualThing)vt.Value; + if(bvt.Selected) selectedobjects.Add(bvt); + } } } @@ -397,14 +403,20 @@ namespace CodeImp.DoomBuilder.BuilderModes { foreach(KeyValuePair vs in allsectors) { - BaseVisualSector bvs = (BaseVisualSector)vs.Value; - if(bvs.Changed) bvs.Rebuild(); + if(vs.Value != null) + { + BaseVisualSector bvs = (BaseVisualSector)vs.Value; + if(bvs.Changed) bvs.Rebuild(); + } } foreach(KeyValuePair vt in allthings) { - BaseVisualThing bvt = (BaseVisualThing)vt.Value; - if(bvt.Changed) bvt.Rebuild(); + if(vt.Value != null) + { + BaseVisualThing bvt = (BaseVisualThing)vt.Value; + if(bvt.Changed) bvt.Rebuild(); + } } } @@ -602,14 +614,14 @@ namespace CodeImp.DoomBuilder.BuilderModes // No sectors or geometry changed. So we only have // to update things when they have changed. foreach(KeyValuePair vt in allthings) - if(vt.Key.Marked) (vt.Value as BaseVisualThing).Rebuild(); + if((vt.Value != null) && vt.Key.Marked) (vt.Value as BaseVisualThing).Rebuild(); } else { // Things depend on the sector they are in and because we can't // easily determine which ones changed, we dispose all things foreach(KeyValuePair vt in allthings) - vt.Value.Dispose(); + if(vt.Value != null) vt.Value.Dispose(); // Apply new lists allthings = new Dictionary(allthings.Count); @@ -899,23 +911,29 @@ namespace CodeImp.DoomBuilder.BuilderModes foreach(KeyValuePair vs in allsectors) { - BaseVisualSector bvs = (BaseVisualSector)vs.Value; - if(bvs.Floor != null) bvs.Floor.Selected = false; - if(bvs.Ceiling != null) bvs.Ceiling.Selected = false; - foreach(Sidedef sd in vs.Key.Sidedefs) + if(vs.Value != null) { - List sidedefgeos = bvs.GetSidedefGeometry(sd); - foreach(VisualGeometry sdg in sidedefgeos) + BaseVisualSector bvs = (BaseVisualSector)vs.Value; + if(bvs.Floor != null) bvs.Floor.Selected = false; + if(bvs.Ceiling != null) bvs.Ceiling.Selected = false; + foreach(Sidedef sd in vs.Key.Sidedefs) { - sdg.Selected = false; + List sidedefgeos = bvs.GetSidedefGeometry(sd); + foreach(VisualGeometry sdg in sidedefgeos) + { + sdg.Selected = false; + } } } } foreach(KeyValuePair vt in allthings) { - BaseVisualThing bvt = (BaseVisualThing)vt.Value; - bvt.Selected = false; + if(vt.Value != null) + { + BaseVisualThing bvt = (BaseVisualThing)vt.Value; + bvt.Selected = false; + } } } diff --git a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs index f10b6388..f3e60497 100644 --- a/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/BuilderModes/VisualModes/BaseVisualThing.cs @@ -76,9 +76,17 @@ namespace CodeImp.DoomBuilder.BuilderModes public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t) { this.mode = mode; - - Rebuild(); - + + // Find thing information + info = General.Map.Data.GetThingInfo(Thing.Type); + + // Find sprite texture + if(info.Sprite.Length > 0) + { + sprite = General.Map.Data.GetSpriteImage(info.Sprite); + if(sprite != null) sprite.AddReference(); + } + // We have no destructor GC.SuppressFinalize(this); } @@ -232,16 +240,6 @@ namespace CodeImp.DoomBuilder.BuilderModes // This forces to rebuild the whole thing public void Rebuild() { - // Find thing information - info = General.Map.Data.GetThingInfo(Thing.Type); - - // Find sprite texture - if(info.Sprite.Length > 0) - { - sprite = General.Map.Data.GetSpriteImage(info.Sprite); - if(sprite != null) sprite.AddReference(); - } - // Setup visual thing Setup(); } diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs index 24f26db4..d2d27ecb 100644 --- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs +++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs @@ -296,23 +296,29 @@ namespace CodeImp.DoomBuilder.GZDoomEditing selectedobjects = new List(); foreach(KeyValuePair vs in allsectors) { - BaseVisualSector bvs = (BaseVisualSector)vs.Value; - if((bvs.Floor != null) && bvs.Floor.Selected) selectedobjects.Add(bvs.Floor); - if((bvs.Ceiling != null) && bvs.Ceiling.Selected) selectedobjects.Add(bvs.Ceiling); - foreach(Sidedef sd in vs.Key.Sidedefs) + if(vs.Value != null) { - List sidedefgeos = bvs.GetSidedefGeometry(sd); - foreach(VisualGeometry sdg in sidedefgeos) + BaseVisualSector bvs = (BaseVisualSector)vs.Value; + if((bvs.Floor != null) && bvs.Floor.Selected) selectedobjects.Add(bvs.Floor); + if((bvs.Ceiling != null) && bvs.Ceiling.Selected) selectedobjects.Add(bvs.Ceiling); + foreach(Sidedef sd in vs.Key.Sidedefs) { - if(sdg.Selected) selectedobjects.Add((sdg as IVisualEventReceiver)); + List sidedefgeos = bvs.GetSidedefGeometry(sd); + foreach(VisualGeometry sdg in sidedefgeos) + { + if(sdg.Selected) selectedobjects.Add((sdg as IVisualEventReceiver)); + } } } } foreach(KeyValuePair vt in allthings) { - BaseVisualThing bvt = (BaseVisualThing)vt.Value; - if(bvt.Selected) selectedobjects.Add(bvt); + if(vt.Value != null) + { + BaseVisualThing bvt = (BaseVisualThing)vt.Value; + if(bvt.Selected) selectedobjects.Add(bvt); + } } } @@ -413,14 +419,20 @@ namespace CodeImp.DoomBuilder.GZDoomEditing { foreach(KeyValuePair vs in allsectors) { - BaseVisualSector bvs = (BaseVisualSector)vs.Value; - if(bvs.Changed) bvs.Rebuild(); + if(vs.Value != null) + { + BaseVisualSector bvs = (BaseVisualSector)vs.Value; + if(bvs.Changed) bvs.Rebuild(); + } } foreach(KeyValuePair vt in allthings) { - BaseVisualThing bvt = (BaseVisualThing)vt.Value; - if(bvt.Changed) bvt.Rebuild(); + if(vt.Value != null) + { + BaseVisualThing bvt = (BaseVisualThing)vt.Value; + if(bvt.Changed) bvt.Rebuild(); + } } } @@ -824,14 +836,14 @@ namespace CodeImp.DoomBuilder.GZDoomEditing // No sectors or geometry changed. So we only have // to update things when they have changed. foreach(KeyValuePair vt in allthings) - if(vt.Key.Marked) (vt.Value as BaseVisualThing).Rebuild(); + if((vt.Value != null) && vt.Key.Marked) (vt.Value as BaseVisualThing).Rebuild(); } else { // Things depend on the sector they are in and because we can't // easily determine which ones changed, we dispose all things foreach(KeyValuePair vt in allthings) - vt.Value.Dispose(); + if(vt.Value != null) vt.Value.Dispose(); // Apply new lists allthings = new Dictionary(allthings.Count); @@ -1124,25 +1136,31 @@ namespace CodeImp.DoomBuilder.GZDoomEditing foreach(KeyValuePair vs in allsectors) { - BaseVisualSector bvs = (BaseVisualSector)vs.Value; - if(bvs.Floor != null) bvs.Floor.Selected = false; - if(bvs.Ceiling != null) bvs.Ceiling.Selected = false; - foreach(VisualFloor vf in bvs.ExtraFloors) vf.Selected = false; - foreach(VisualCeiling vc in bvs.ExtraCeilings) vc.Selected = false; - foreach(Sidedef sd in vs.Key.Sidedefs) + if(vs.Value != null) { - List sidedefgeos = bvs.GetSidedefGeometry(sd); - foreach(VisualGeometry sdg in sidedefgeos) + BaseVisualSector bvs = (BaseVisualSector)vs.Value; + if(bvs.Floor != null) bvs.Floor.Selected = false; + if(bvs.Ceiling != null) bvs.Ceiling.Selected = false; + foreach(VisualFloor vf in bvs.ExtraFloors) vf.Selected = false; + foreach(VisualCeiling vc in bvs.ExtraCeilings) vc.Selected = false; + foreach(Sidedef sd in vs.Key.Sidedefs) { - sdg.Selected = false; + List sidedefgeos = bvs.GetSidedefGeometry(sd); + foreach(VisualGeometry sdg in sidedefgeos) + { + sdg.Selected = false; + } } } } foreach(KeyValuePair vt in allthings) { - BaseVisualThing bvt = (BaseVisualThing)vt.Value; - bvt.Selected = false; + if(vt.Value != null) + { + BaseVisualThing bvt = (BaseVisualThing)vt.Value; + bvt.Selected = false; + } } } diff --git a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs index 953e996b..57ca3314 100644 --- a/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs +++ b/Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs @@ -76,9 +76,17 @@ namespace CodeImp.DoomBuilder.GZDoomEditing public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t) { this.mode = mode; - - Rebuild(); - + + // Find thing information + info = General.Map.Data.GetThingInfo(Thing.Type); + + // Find sprite texture + if(info.Sprite.Length > 0) + { + sprite = General.Map.Data.GetSpriteImage(info.Sprite); + if(sprite != null) sprite.AddReference(); + } + // We have no destructor GC.SuppressFinalize(this); }