Fixed memory and performance issues in Visual Mode for things with 0 with or height. (note to developers: VisualMode::GetVisualThing(t) may return null!)

This commit is contained in:
codeimp 2011-12-02 23:11:16 +00:00
parent 32c13b9b4e
commit a418868dfd
5 changed files with 123 additions and 78 deletions

View file

@ -164,11 +164,11 @@ namespace CodeImp.DoomBuilder.VisualModes
// Dispose
foreach(KeyValuePair<Sector, VisualSector> vs in allsectors)
vs.Value.Dispose();
if(vs.Value != null) vs.Value.Dispose();
// Dispose
foreach(KeyValuePair<Thing, VisualThing> 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<Sector, VisualSector> vs in allsectors)
vs.Value.Dispose();
if(vs.Value != null) vs.Value.Dispose();
foreach(KeyValuePair<Thing, VisualThing> 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<Sector, VisualSector> 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<Thing, VisualThing> 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
/// <summary>
/// Returns True when a VisualSector has been created for the specified Sector.
/// </summary>
public bool VisualSectorExists(Sector s) { return allsectors.ContainsKey(s); }
public bool VisualSectorExists(Sector s) { return allsectors.ContainsKey(s) && (allsectors[s] != null); }
/// <summary>
/// Returns True when a VisualThing has been created for the specified Thing.
/// </summary>
public bool VisualThingExists(Thing t) { return allthings.ContainsKey(t); }
public bool VisualThingExists(Thing t) { return allthings.ContainsKey(t) && (allthings[t] != null); }
/// <summary>
/// This is called when the blockmap needs to be refilled, because it was invalidated.

View file

@ -290,23 +290,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
selectedobjects = new List<IVisualEventReceiver>();
foreach(KeyValuePair<Sector, VisualSector> 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<VisualGeometry> 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<VisualGeometry> sidedefgeos = bvs.GetSidedefGeometry(sd);
foreach(VisualGeometry sdg in sidedefgeos)
{
if(sdg.Selected) selectedobjects.Add((sdg as IVisualEventReceiver));
}
}
}
}
foreach(KeyValuePair<Thing, VisualThing> 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<Sector, VisualSector> 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<Thing, VisualThing> 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<Thing, VisualThing> 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<Thing, VisualThing> vt in allthings)
vt.Value.Dispose();
if(vt.Value != null) vt.Value.Dispose();
// Apply new lists
allthings = new Dictionary<Thing, VisualThing>(allthings.Count);
@ -899,23 +911,29 @@ namespace CodeImp.DoomBuilder.BuilderModes
foreach(KeyValuePair<Sector, VisualSector> 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<VisualGeometry> 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<VisualGeometry> sidedefgeos = bvs.GetSidedefGeometry(sd);
foreach(VisualGeometry sdg in sidedefgeos)
{
sdg.Selected = false;
}
}
}
}
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
{
BaseVisualThing bvt = (BaseVisualThing)vt.Value;
bvt.Selected = false;
if(vt.Value != null)
{
BaseVisualThing bvt = (BaseVisualThing)vt.Value;
bvt.Selected = false;
}
}
}

View file

@ -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();
}

View file

@ -296,23 +296,29 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
selectedobjects = new List<IVisualEventReceiver>();
foreach(KeyValuePair<Sector, VisualSector> 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<VisualGeometry> 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<VisualGeometry> sidedefgeos = bvs.GetSidedefGeometry(sd);
foreach(VisualGeometry sdg in sidedefgeos)
{
if(sdg.Selected) selectedobjects.Add((sdg as IVisualEventReceiver));
}
}
}
}
foreach(KeyValuePair<Thing, VisualThing> 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<Sector, VisualSector> 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<Thing, VisualThing> 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<Thing, VisualThing> 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<Thing, VisualThing> vt in allthings)
vt.Value.Dispose();
if(vt.Value != null) vt.Value.Dispose();
// Apply new lists
allthings = new Dictionary<Thing, VisualThing>(allthings.Count);
@ -1124,25 +1136,31 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
foreach(KeyValuePair<Sector, VisualSector> 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<VisualGeometry> 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<VisualGeometry> sidedefgeos = bvs.GetSidedefGeometry(sd);
foreach(VisualGeometry sdg in sidedefgeos)
{
sdg.Selected = false;
}
}
}
}
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
{
BaseVisualThing bvt = (BaseVisualThing)vt.Value;
bvt.Selected = false;
if(vt.Value != null)
{
BaseVisualThing bvt = (BaseVisualThing)vt.Value;
bvt.Selected = false;
}
}
}

View file

@ -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);
}