Tracker fixes and debug methods. ComponentInterfaceAttribute removed, interface use is auto-detected. Scene actually calls update and draw methods

This commit is contained in:
Maddy Thorson 2021-02-06 23:13:02 -08:00
parent 5dde4ce375
commit 1fb4ed7c9b
9 changed files with 142 additions and 52 deletions

View File

@ -8,6 +8,16 @@ namespace Strawberry
public bool Collidable = true;
public Rect Rect;
public this(Rect rect)
{
Rect = rect;
}
public this(int x, int y, int width, int height)
{
Rect = .(x, y, width, height);
}
public void DebugDraw()
{
Game.Batcher.Rect(SceneHitbox, .Red);
@ -116,52 +126,62 @@ namespace Strawberry
Single Collisions
*/
[Inline]
public bool Check(Point point)
{
return SceneHitbox.Contains(point);
}
[Inline]
public bool Check(Rect rect)
{
return SceneHitbox.Intersects(rect);
}
[Inline]
public bool Check(Grid grid)
{
return grid != null && grid.Check(SceneHitbox);
}
[Inline]
public bool Check(Grid grid, Point offset)
{
return grid != null && grid.Check(SceneHitbox + offset);
}
[Inline]
public bool Check(Hitbox other)
{
return other.Collidable && SceneHitbox.Intersects(other.SceneHitbox);
}
[Inline]
public bool Check(Hitbox other, Point offset)
{
return other.Collidable && (SceneHitbox + offset).Intersects(other.SceneHitbox);
}
[Inline]
public bool CheckOutside(Hitbox other, Point offset)
{
return other.Collidable && !SceneHitbox.Intersects(other.SceneHitbox) && (SceneHitbox + offset).Intersects(other.SceneHitbox);
}
public bool Check<T>(T other) where T : Component, IHasHitbox
[Inline]
public bool Check(IHasHitbox other)
{
return Check(other.Hitbox);
}
public bool Check<T>(T other, Point offset) where T : Component, IHasHitbox
[Inline]
public bool Check(IHasHitbox other, Point offset)
{
return Check(other.Hitbox, offset);
}
public bool CheckOutside<T>(T other, Point offset) where T : Component, IHasHitbox
[Inline]
public bool CheckOutside(IHasHitbox other, Point offset)
{
return CheckOutside(other.Hitbox, offset);
}

View File

@ -1,6 +1,7 @@
using System;
namespace Strawberry
{
[ComponentInterface]
public interface IDebugDraw
{
public void DebugDraw();

View File

@ -1,6 +1,7 @@
using System;
namespace Strawberry
{
[ComponentInterface]
public interface IDraw
{
public void Draw();

View File

@ -1,6 +1,7 @@
using System;
namespace Strawberry
{
[ComponentInterface]
public interface IHasHitbox
{
public Hitbox Hitbox { get; }

View File

@ -1,6 +1,7 @@
using System;
namespace Strawberry
{
[ComponentInterface]
public interface ILateUpdate
{
public void LateUpdate();

View File

@ -1,6 +1,7 @@
using System;
namespace Strawberry
{
[ComponentInterface]
public interface IUpdate
{
public void Update();

View File

@ -1,9 +0,0 @@
using System;
namespace Strawberry
{
public struct ComponentInterfaceAttribute : Attribute
{
}
}

View File

@ -7,18 +7,13 @@ namespace Strawberry
{
public float TimeStarted { get; private set; }
private List<Entity> entities;
private HashSet<Entity> toRemove;
private HashSet<Entity> toAdd;
private Dictionary<Type, List<Component>> componentTracker;
private List<Entity> entities = new .() ~ delete _;
private HashSet<Entity> toRemove = new .() ~ delete _;
private HashSet<Entity> toAdd = new .() ~ delete _;
private Dictionary<Type, List<Component>> componentTracker = new .() ~ DeleteDictionaryAndValues!(_);
public this()
{
entities = new List<Entity>();
toAdd = new HashSet<Entity>();
toRemove = new HashSet<Entity>();
componentTracker = new Dictionary<Type, List<Component>>();
for (let type in Tracker.AssignmentLists.Keys)
componentTracker.Add(type, new List<Component>());
for (let type in Tracker.Interfaces)
@ -30,18 +25,10 @@ namespace Strawberry
for (var e in entities)
if (e.DeleteOnRemove)
delete e;
delete entities;
for (var e in toAdd)
if (e.DeleteOnRemove)
delete e;
delete toAdd;
delete toRemove;
for (let list in componentTracker.Values)
delete list;
delete componentTracker;
}
public virtual void Started()
@ -51,16 +38,20 @@ namespace Strawberry
public virtual void Update()
{
ForEach<IUpdate>(scope (u) => u.Update());
ForEach<ILateUpdate>(scope (u) => u.LateUpdate());
UpdateLists();
}
public virtual void Draw()
{
ForEach<IDraw>(scope (d) => d.Draw());
}
/*
Entities
*/
public Entity Add(Entity e)
{
if (e.Scene == null)
@ -106,7 +97,9 @@ namespace Strawberry
e.[Friend]AwakeCheck();
}
// Tracking
/*
Tracking
*/
private void TrackComponent(Component c)
{
@ -120,7 +113,9 @@ namespace Strawberry
componentTracker[t].Remove(c);
}
// Time
/*
Time
*/
public float TimeElapsed => Time.Elapsed - TimeStarted;
public float PreviousTimeElapsed => Time.PreviousElapsed - TimeStarted;
@ -263,5 +258,21 @@ namespace Strawberry
into.Add(c as T);
return into;
}
public void ForEach<T>(delegate void(T) action) where T : interface
{
List<Component> list;
if (componentTracker.TryGetValue(typeof(T), out list))
for (let c in list)
action(c as T);
}
public void ForEach<T>(delegate void(T) action) where T : Component
{
List<Component> list;
if (componentTracker.TryGetValue(typeof(T), out list))
for (T c in list)
action(c);
}
}
}

View File

@ -1,18 +1,45 @@
using System.Collections;
using System;
using System.Reflection;
namespace Strawberry
{
static public class Tracker
{
static public Dictionary<Type, List<Type>> AssignmentLists = new .() ~ DeleteDictionaryAndValues!(_);
static public List<Type> Components = new .() ~ delete _;
static public List<Type> Interfaces = new .() ~ delete _;
static public Dictionary<Type, List<Type>> AssignmentLists = new .() ~ DeleteDictionaryAndValues!(_);
static private void BuildAssignmentLists()
{
// Find all component types
for (let type in Type.Types)
if (type != typeof(Component) && type.IsSubtypeOf(typeof(Component)))
Components.Add(type);
// Find all interfaces with ComponentInterfaceAttribute
for (let type in Type.Enumerator())
if (type.IsInterface && type.HasCustomAttribute<ComponentInterfaceAttribute>())
Interfaces.Add(type);
for (let type in Type.Types)
{
if (type.IsInterface)
{
bool foundUse = false;
Find: for (let c in Components)
{
for (let i in c.Interfaces)
{
if (i == type)
{
foundUse = true;
break Find;
}
}
}
if (foundUse)
Interfaces.Add(type);
}
}
/*
For each Type that extends Component, we build a list of all the tracked Interfaces it implements.
@ -20,18 +47,54 @@ namespace Strawberry
This allows us to retrieve Components by their type or by any of their implemented interface types.
*/
for (let type in Type.Enumerator())
for (let type in Components)
{
if (type != typeof(Component) && type.IsSubtypeOf(typeof(Component)))
{
let list = new List<Type>();
list.Add(type);
for (let check in Interfaces)
if (type.IsSubtypeOf(check))
list.Add(check);
let list = new List<Type>();
list.Add(type);
for (let int in type.Interfaces)
if (Interfaces.Contains(int))
list.Add(int);
AssignmentLists.Add(type, list);
AssignmentLists.Add(type, list);
}
Calc.Log(scope => GetTrackedInterfacesInfo);
Calc.Log(scope => GetTrackedTypesInfo);
}
static public void GetTrackedInterfacesInfo(String buffer)
{
buffer.Append("Tracked Interfaces:\n");
for (int i = 0; i < Interfaces.Count; i++)
{
buffer.Append("-");
Interfaces[i].GetName(buffer);
if (i < Interfaces.Count - 1)
buffer.Append('\n');
}
}
static public void GetTrackedTypesInfo(String buffer)
{
buffer.Append("Tracked Types:\n");
int index = 0;
for (let kv in AssignmentLists)
{
buffer.Append("-");
kv.key.GetName(buffer);
buffer.Append(" as ");
for (int i = 0; i < kv.value.Count; i++)
{
kv.value[i].GetName(buffer);
if (i < kv.value.Count - 1)
buffer.Append(", ");
}
index++;
if (index < AssignmentLists.Count)
buffer.Append('\n');
}
}
}