mirror of
https://github.com/MaddyThorson/StrawberryBF.git
synced 2025-02-20 11:58:28 +08:00
Proper Entity and Component bucketing/tracking
This commit is contained in:
parent
df00a1ec82
commit
0b1a938fe2
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,5 +53,13 @@ namespace Strawberry
|
||||
v.ToString(string);
|
||||
Debug.WriteLine(string);
|
||||
}
|
||||
|
||||
[Inline]
|
||||
static public void Log(delegate void(String) del)
|
||||
{
|
||||
String string = scope String();
|
||||
del(string);
|
||||
Debug.WriteLine(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
src/Static/TypeTree.bf
Normal file
61
src/Static/TypeTree.bf
Normal file
@ -0,0 +1,61 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
static public class TypeTree
|
||||
{
|
||||
static private Dictionary<Type, List<Type>> EntityAssignableLists;
|
||||
static private Dictionary<Type, List<Type>> ComponentAssignableLists;
|
||||
|
||||
static private void Build()
|
||||
{
|
||||
/*
|
||||
For each Type that extends Entity, we build a list of all the other Entity Types that it is assignable to.
|
||||
We cache these lists, and use them later to bucket Entities as they are added to the Scene.
|
||||
This allows us to retrieve Entities by type very easily.
|
||||
*/
|
||||
|
||||
EntityAssignableLists = new Dictionary<Type, List<Type>>();
|
||||
for (let type in Type.Enumerator())
|
||||
{
|
||||
if (type != typeof(Entity) && type.IsSubtypeOf(typeof(Entity)))
|
||||
{
|
||||
let list = new List<Type>();
|
||||
for (let check in Type.Enumerator())
|
||||
if (check != typeof(Entity) && check.IsSubtypeOf(typeof(Entity)) && type.IsSubtypeOf(check))
|
||||
list.Add(check);
|
||||
EntityAssignableLists.Add(type, list);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
And then we also do this for components
|
||||
*/
|
||||
|
||||
ComponentAssignableLists = new Dictionary<Type, List<Type>>();
|
||||
for (let type in Type.Enumerator())
|
||||
{
|
||||
if (type != typeof(Component) && type.IsSubtypeOf(typeof(Component)))
|
||||
{
|
||||
let list = new List<Type>();
|
||||
for (let check in Type.Enumerator())
|
||||
if (check != typeof(Component) && check.IsSubtypeOf(typeof(Component)) && type.IsSubtypeOf(check))
|
||||
list.Add(check);
|
||||
ComponentAssignableLists.Add(type, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static private void Dispose()
|
||||
{
|
||||
for (let list in EntityAssignableLists.Values)
|
||||
delete list;
|
||||
delete EntityAssignableLists;
|
||||
|
||||
for (let list in ComponentAssignableLists.Values)
|
||||
delete list;
|
||||
delete ComponentAssignableLists;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public enum Cardinals
|
||||
@ -66,5 +68,33 @@ namespace Strawberry
|
||||
return Point.Down;
|
||||
}
|
||||
}
|
||||
|
||||
static public Result<Cardinals> FromPoint(Point p)
|
||||
{
|
||||
if (p.X > 0 && p.Y == 0)
|
||||
return .Right;
|
||||
else if (p.X < 0 && p.Y == 0)
|
||||
return .Left;
|
||||
else if (p.Y < 0 && p.X == 0)
|
||||
return .Up;
|
||||
else if (p.Y > 0 && p.X == 0)
|
||||
return .Down;
|
||||
else
|
||||
return .Err;
|
||||
}
|
||||
|
||||
static public Result<Cardinals> FromVector(Vector v)
|
||||
{
|
||||
if (v.X > 0 && v.Y == 0)
|
||||
return .Right;
|
||||
else if (v.X < 0 && v.Y == 0)
|
||||
return .Left;
|
||||
else if (v.Y < 0 && v.X == 0)
|
||||
return .Up;
|
||||
else if (v.Y > 0 && v.X == 0)
|
||||
return .Down;
|
||||
else
|
||||
return .Err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user