Proper Entity and Component bucketing/tracking

This commit is contained in:
Matt Thorson
2020-05-21 21:24:04 -07:00
parent df00a1ec82
commit 0b1a938fe2
6 changed files with 180 additions and 14 deletions

View File

@ -88,6 +88,7 @@ namespace Strawberry
for (var c in toRemove)
{
components.Remove(c);
Scene.[Friend]UntrackComponent(c);
c.Removed();
delete c;
}
@ -100,6 +101,7 @@ namespace Strawberry
for (var c in toAdd)
{
components.Add(c);
Scene.[Friend]TrackComponent(c);
c.Added(this);
}

View File

@ -77,6 +77,8 @@ namespace Strawberry
SDLImage.Init(.PNG | .JPG);
SDLMixer.OpenAudio(44100, SDLMixer.MIX_DEFAULT_FORMAT, 2, 4096);
SDLTTF.Init();
TypeTree.[Friend]Build();
Input.[Friend]Init(gamepadLimit);
}
@ -97,6 +99,7 @@ namespace Strawberry
delete VirtualInputs;
}
TypeTree.[Friend]Dispose();
Input.[Friend]Dispose();
Game = null;
}

View File

@ -12,12 +12,22 @@ namespace Strawberry
private List<Entity> entities;
private HashSet<Entity> toRemove;
private HashSet<Entity> toAdd;
private Dictionary<Type, List<Entity>> entityTracker;
private Dictionary<Type, List<Component>> componentTracker;
public this()
{
entities = new List<Entity>();
toAdd = new HashSet<Entity>();
toRemove = new HashSet<Entity>();
entityTracker = new Dictionary<Type, List<Entity>>();
for (let type in TypeTree.[Friend]EntityAssignableLists.Keys)
entityTracker.Add(type, new List<Entity>());
componentTracker = new Dictionary<Type, List<Component>>();
for (let type in TypeTree.[Friend]ComponentAssignableLists.Keys)
componentTracker.Add(type, new List<Component>());
}
public ~this()
@ -36,6 +46,14 @@ namespace Strawberry
delete toAdd;
delete toRemove;
for (let list in entityTracker.Values)
delete list;
delete entityTracker;
for (let list in componentTracker.Values)
delete list;
delete componentTracker;
}
public virtual void Started()
@ -79,6 +97,7 @@ namespace Strawberry
for (var e in toRemove)
{
entities.Remove(e);
UntrackEntity(e);
e.Removed();
if (e.DeleteOnRemove)
delete e;
@ -92,6 +111,7 @@ namespace Strawberry
for (var e in toAdd)
{
entities.Add(e);
TrackEntity(e);
e.Added(this);
}
}
@ -108,6 +128,38 @@ namespace Strawberry
}
}
// Tracking
private void TrackEntity(Entity e)
{
for (let t in TypeTree.[Friend]EntityAssignableLists[e.GetType()])
entityTracker[t].Add(e);
for (let c in e.[Friend]components)
TrackComponent(c);
}
private void UntrackEntity(Entity e)
{
for (let t in TypeTree.[Friend]EntityAssignableLists[e.GetType()])
entityTracker[t].Remove(e);
for (let c in e.[Friend]components)
UntrackComponent(c);
}
private void TrackComponent(Component c)
{
for (let t in TypeTree.[Friend]ComponentAssignableLists[c.GetType()])
componentTracker[t].Add(c);
}
private void UntrackComponent(Component c)
{
for (let t in TypeTree.[Friend]ComponentAssignableLists[c.GetType()])
componentTracker[t].Remove(c);
}
// Time
public float TimeElapsed => Time.Elapsed - TimeStarted;
@ -125,52 +177,62 @@ namespace Strawberry
// Finding Entities
public int Count<T>() where T : Entity
{
return entityTracker[typeof(T)].Count;
}
public T First<T>() where T : Entity
{
for (var e in entities)
if (e is T)
return e as T;
for (var e in entityTracker[typeof(T)])
return e as T;
return null;
}
public T First<T>(Point point) where T : Entity
{
for (var e in entities)
if (e is T && e.Check(point))
for (var e in entityTracker[typeof(T)])
if (e.Check(point))
return e as T;
return null;
}
public T First<T>(Rect rect) where T : Entity
{
for (var e in entities)
if (e is T && e.Check(rect))
for (var e in entityTracker[typeof(T)])
if (e.Check(rect))
return e as T;
return null;
}
public List<T> All<T>(List<T> into) where T : Entity
{
for (var e in entities)
if (e is T)
into.Add(e as T);
for (var e in entityTracker[typeof(T)])
into.Add(e as T);
return into;
}
public List<T> All<T>(Point point, List<T> into) where T : Entity
{
for (var e in entities)
if (e is T && e.Check(point))
for (var e in entityTracker[typeof(T)])
if (e.Check(point))
into.Add(e as T);
return into;
}
public List<T> All<T>(Rect rect, List<T> into) where T : Entity
{
for (var e in entities)
if (e is T && e.Check(rect))
for (var e in entityTracker[typeof(T)])
if (e.Check(rect))
into.Add(e as T);
return into;
}
// Finding Components
public int Count<T>() where T : Component
{
return componentTracker[typeof(T)].Count;
}
}
}