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 bool Collidable = true;
public Rect Rect; 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() public void DebugDraw()
{ {
Game.Batcher.Rect(SceneHitbox, .Red); Game.Batcher.Rect(SceneHitbox, .Red);
@ -116,52 +126,62 @@ namespace Strawberry
Single Collisions Single Collisions
*/ */
[Inline]
public bool Check(Point point) public bool Check(Point point)
{ {
return SceneHitbox.Contains(point); return SceneHitbox.Contains(point);
} }
[Inline]
public bool Check(Rect rect) public bool Check(Rect rect)
{ {
return SceneHitbox.Intersects(rect); return SceneHitbox.Intersects(rect);
} }
[Inline]
public bool Check(Grid grid) public bool Check(Grid grid)
{ {
return grid != null && grid.Check(SceneHitbox); return grid != null && grid.Check(SceneHitbox);
} }
[Inline]
public bool Check(Grid grid, Point offset) public bool Check(Grid grid, Point offset)
{ {
return grid != null && grid.Check(SceneHitbox + offset); return grid != null && grid.Check(SceneHitbox + offset);
} }
[Inline]
public bool Check(Hitbox other) public bool Check(Hitbox other)
{ {
return other.Collidable && SceneHitbox.Intersects(other.SceneHitbox); return other.Collidable && SceneHitbox.Intersects(other.SceneHitbox);
} }
[Inline]
public bool Check(Hitbox other, Point offset) public bool Check(Hitbox other, Point offset)
{ {
return other.Collidable && (SceneHitbox + offset).Intersects(other.SceneHitbox); return other.Collidable && (SceneHitbox + offset).Intersects(other.SceneHitbox);
} }
[Inline]
public bool CheckOutside(Hitbox other, Point offset) public bool CheckOutside(Hitbox other, Point offset)
{ {
return other.Collidable && !SceneHitbox.Intersects(other.SceneHitbox) && (SceneHitbox + offset).Intersects(other.SceneHitbox); 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); 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); 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); return CheckOutside(other.Hitbox, offset);
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
using System;
namespace Strawberry namespace Strawberry
{ {
[ComponentInterface]
public interface IUpdate public interface IUpdate
{ {
public void Update(); 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; } public float TimeStarted { get; private set; }
private List<Entity> entities; private List<Entity> entities = new .() ~ delete _;
private HashSet<Entity> toRemove; private HashSet<Entity> toRemove = new .() ~ delete _;
private HashSet<Entity> toAdd; private HashSet<Entity> toAdd = new .() ~ delete _;
private Dictionary<Type, List<Component>> componentTracker; private Dictionary<Type, List<Component>> componentTracker = new .() ~ DeleteDictionaryAndValues!(_);
public this() 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) for (let type in Tracker.AssignmentLists.Keys)
componentTracker.Add(type, new List<Component>()); componentTracker.Add(type, new List<Component>());
for (let type in Tracker.Interfaces) for (let type in Tracker.Interfaces)
@ -30,18 +25,10 @@ namespace Strawberry
for (var e in entities) for (var e in entities)
if (e.DeleteOnRemove) if (e.DeleteOnRemove)
delete e; delete e;
delete entities;
for (var e in toAdd) for (var e in toAdd)
if (e.DeleteOnRemove) if (e.DeleteOnRemove)
delete e; delete e;
delete toAdd;
delete toRemove;
for (let list in componentTracker.Values)
delete list;
delete componentTracker;
} }
public virtual void Started() public virtual void Started()
@ -51,16 +38,20 @@ namespace Strawberry
public virtual void Update() public virtual void Update()
{ {
ForEach<IUpdate>(scope (u) => u.Update());
ForEach<ILateUpdate>(scope (u) => u.LateUpdate());
UpdateLists(); UpdateLists();
} }
public virtual void Draw() public virtual void Draw()
{ {
ForEach<IDraw>(scope (d) => d.Draw());
} }
/*
Entities
*/
public Entity Add(Entity e) public Entity Add(Entity e)
{ {
if (e.Scene == null) if (e.Scene == null)
@ -106,7 +97,9 @@ namespace Strawberry
e.[Friend]AwakeCheck(); e.[Friend]AwakeCheck();
} }
// Tracking /*
Tracking
*/
private void TrackComponent(Component c) private void TrackComponent(Component c)
{ {
@ -120,7 +113,9 @@ namespace Strawberry
componentTracker[t].Remove(c); componentTracker[t].Remove(c);
} }
// Time /*
Time
*/
public float TimeElapsed => Time.Elapsed - TimeStarted; public float TimeElapsed => Time.Elapsed - TimeStarted;
public float PreviousTimeElapsed => Time.PreviousElapsed - TimeStarted; public float PreviousTimeElapsed => Time.PreviousElapsed - TimeStarted;
@ -263,5 +258,21 @@ namespace Strawberry
into.Add(c as T); into.Add(c as T);
return into; 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.Collections;
using System; using System;
using System.Reflection;
namespace Strawberry namespace Strawberry
{ {
static public class Tracker 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 List<Type> Interfaces = new .() ~ delete _;
static public Dictionary<Type, List<Type>> AssignmentLists = new .() ~ DeleteDictionaryAndValues!(_);
static private void BuildAssignmentLists() 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 // Find all interfaces with ComponentInterfaceAttribute
for (let type in Type.Enumerator()) for (let type in Type.Types)
if (type.IsInterface && type.HasCustomAttribute<ComponentInterfaceAttribute>()) {
Interfaces.Add(type); 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. 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. 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);
let list = new List<Type>(); for (let int in type.Interfaces)
list.Add(type); if (Interfaces.Contains(int))
for (let check in Interfaces) list.Add(int);
if (type.IsSubtypeOf(check))
list.Add(check);
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');
} }
} }
} }