mirror of
https://github.com/MaddyThorson/StrawberryBF.git
synced 2025-02-21 12:28:27 +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)
|
for (var c in toRemove)
|
||||||
{
|
{
|
||||||
components.Remove(c);
|
components.Remove(c);
|
||||||
|
Scene.[Friend]UntrackComponent(c);
|
||||||
c.Removed();
|
c.Removed();
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
@ -100,6 +101,7 @@ namespace Strawberry
|
|||||||
for (var c in toAdd)
|
for (var c in toAdd)
|
||||||
{
|
{
|
||||||
components.Add(c);
|
components.Add(c);
|
||||||
|
Scene.[Friend]TrackComponent(c);
|
||||||
c.Added(this);
|
c.Added(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,8 @@ namespace Strawberry
|
|||||||
SDLImage.Init(.PNG | .JPG);
|
SDLImage.Init(.PNG | .JPG);
|
||||||
SDLMixer.OpenAudio(44100, SDLMixer.MIX_DEFAULT_FORMAT, 2, 4096);
|
SDLMixer.OpenAudio(44100, SDLMixer.MIX_DEFAULT_FORMAT, 2, 4096);
|
||||||
SDLTTF.Init();
|
SDLTTF.Init();
|
||||||
|
|
||||||
|
TypeTree.[Friend]Build();
|
||||||
Input.[Friend]Init(gamepadLimit);
|
Input.[Friend]Init(gamepadLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +99,7 @@ namespace Strawberry
|
|||||||
delete VirtualInputs;
|
delete VirtualInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeTree.[Friend]Dispose();
|
||||||
Input.[Friend]Dispose();
|
Input.[Friend]Dispose();
|
||||||
Game = null;
|
Game = null;
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,22 @@ namespace Strawberry
|
|||||||
private List<Entity> entities;
|
private List<Entity> entities;
|
||||||
private HashSet<Entity> toRemove;
|
private HashSet<Entity> toRemove;
|
||||||
private HashSet<Entity> toAdd;
|
private HashSet<Entity> toAdd;
|
||||||
|
private Dictionary<Type, List<Entity>> entityTracker;
|
||||||
|
private Dictionary<Type, List<Component>> componentTracker;
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
entities = new List<Entity>();
|
entities = new List<Entity>();
|
||||||
toAdd = new HashSet<Entity>();
|
toAdd = new HashSet<Entity>();
|
||||||
toRemove = 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()
|
public ~this()
|
||||||
@ -36,6 +46,14 @@ namespace Strawberry
|
|||||||
delete toAdd;
|
delete toAdd;
|
||||||
|
|
||||||
delete toRemove;
|
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()
|
public virtual void Started()
|
||||||
@ -79,6 +97,7 @@ namespace Strawberry
|
|||||||
for (var e in toRemove)
|
for (var e in toRemove)
|
||||||
{
|
{
|
||||||
entities.Remove(e);
|
entities.Remove(e);
|
||||||
|
UntrackEntity(e);
|
||||||
e.Removed();
|
e.Removed();
|
||||||
if (e.DeleteOnRemove)
|
if (e.DeleteOnRemove)
|
||||||
delete e;
|
delete e;
|
||||||
@ -92,6 +111,7 @@ namespace Strawberry
|
|||||||
for (var e in toAdd)
|
for (var e in toAdd)
|
||||||
{
|
{
|
||||||
entities.Add(e);
|
entities.Add(e);
|
||||||
|
TrackEntity(e);
|
||||||
e.Added(this);
|
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
|
// Time
|
||||||
|
|
||||||
public float TimeElapsed => Time.Elapsed - TimeStarted;
|
public float TimeElapsed => Time.Elapsed - TimeStarted;
|
||||||
@ -125,52 +177,62 @@ namespace Strawberry
|
|||||||
|
|
||||||
// Finding Entities
|
// Finding Entities
|
||||||
|
|
||||||
|
public int Count<T>() where T : Entity
|
||||||
|
{
|
||||||
|
return entityTracker[typeof(T)].Count;
|
||||||
|
}
|
||||||
|
|
||||||
public T First<T>() where T : Entity
|
public T First<T>() where T : Entity
|
||||||
{
|
{
|
||||||
for (var e in entities)
|
for (var e in entityTracker[typeof(T)])
|
||||||
if (e is T)
|
return e as T;
|
||||||
return e as T;
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T First<T>(Point point) where T : Entity
|
public T First<T>(Point point) where T : Entity
|
||||||
{
|
{
|
||||||
for (var e in entities)
|
for (var e in entityTracker[typeof(T)])
|
||||||
if (e is T && e.Check(point))
|
if (e.Check(point))
|
||||||
return e as T;
|
return e as T;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T First<T>(Rect rect) where T : Entity
|
public T First<T>(Rect rect) where T : Entity
|
||||||
{
|
{
|
||||||
for (var e in entities)
|
for (var e in entityTracker[typeof(T)])
|
||||||
if (e is T && e.Check(rect))
|
if (e.Check(rect))
|
||||||
return e as T;
|
return e as T;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> All<T>(List<T> into) where T : Entity
|
public List<T> All<T>(List<T> into) where T : Entity
|
||||||
{
|
{
|
||||||
for (var e in entities)
|
for (var e in entityTracker[typeof(T)])
|
||||||
if (e is T)
|
into.Add(e as T);
|
||||||
into.Add(e as T);
|
|
||||||
return into;
|
return into;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> All<T>(Point point, List<T> into) where T : Entity
|
public List<T> All<T>(Point point, List<T> into) where T : Entity
|
||||||
{
|
{
|
||||||
for (var e in entities)
|
for (var e in entityTracker[typeof(T)])
|
||||||
if (e is T && e.Check(point))
|
if (e.Check(point))
|
||||||
into.Add(e as T);
|
into.Add(e as T);
|
||||||
return into;
|
return into;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> All<T>(Rect rect, List<T> into) where T : Entity
|
public List<T> All<T>(Rect rect, List<T> into) where T : Entity
|
||||||
{
|
{
|
||||||
for (var e in entities)
|
for (var e in entityTracker[typeof(T)])
|
||||||
if (e is T && e.Check(rect))
|
if (e.Check(rect))
|
||||||
into.Add(e as T);
|
into.Add(e as T);
|
||||||
return into;
|
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);
|
v.ToString(string);
|
||||||
Debug.WriteLine(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
|
namespace Strawberry
|
||||||
{
|
{
|
||||||
public enum Cardinals
|
public enum Cardinals
|
||||||
@ -66,5 +68,33 @@ namespace Strawberry
|
|||||||
return Point.Down;
|
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