using System.Collections; using System; namespace Strawberry { public class Scene { public float TimeStarted { get; private set; } private List entities; private HashSet toRemove; private HashSet toAdd; private Dictionary> componentTracker; public this() { entities = new List(); toAdd = new HashSet(); toRemove = new HashSet(); componentTracker = new Dictionary>(); for (let type in Tracker.AssignmentLists.Keys) componentTracker.Add(type, new List()); for (let type in Tracker.Interfaces) componentTracker.Add(type, new List()); } public ~this() { 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() { TimeStarted = Time.Elapsed; } public virtual void Update() { UpdateLists(); } public virtual void Draw() { } public Entity Add(Entity e) { if (e.Scene == null) toAdd.Add(e); return e; } public Entity Remove(Entity e) { if (e.Scene == this) toRemove.Add(e); return e; } private void UpdateLists() { if (toRemove.Count > 0) { for (let e in toRemove) { entities.Remove(e); e.[Friend]Removed(); if (e.DeleteOnRemove) delete e; } toRemove.Clear(); } if (toAdd.Count > 0) { for (let e in toAdd) { entities.Add(e); e.[Friend]Added(this); } toAdd.Clear(); } for (let e in entities) e.[Friend]UpdateLists(); for (let e in entities) e.[Friend]AwakeCheck(); } // Tracking private void TrackComponent(Component c) { for (let t in Tracker.AssignmentLists[c.GetType()]) componentTracker[t].Add(c); } private void UntrackComponent(Component c) { for (let t in Tracker.AssignmentLists[c.GetType()]) componentTracker[t].Remove(c); } // Time public float TimeElapsed => Time.Elapsed - TimeStarted; public float PreviousTimeElapsed => Time.PreviousElapsed - TimeStarted; public bool TimeOnInterval(float interval, float offset = 0) { return (int)((TimeElapsed - offset) / interval) != (int)((PreviousTimeElapsed - offset) / interval); } public bool TimeBetweenInterval(float interval, float offset = 0) { return (TimeElapsed - offset) % (interval * 2) >= interval; } /* Finding Components */ public int Count() where T : Component { return componentTracker[typeof(T)].Count; } public int Count(delegate bool(T) condition) where T : Component { int count = 0; for (T c in componentTracker[typeof(T)]) if (condition(c)) count++; return count; } public bool Check(delegate bool(T) condition) where T : Component { for (T c in componentTracker[typeof(T)]) if (condition(c)) return true; return false; } public bool Check(Point point) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (c.Hitbox.Check(point)) return true; return false; } public bool Check(Rect rect) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (c.Hitbox.Check(rect)) return true; return false; } public T First() where T : Component { for (T c in componentTracker[typeof(T)]) return c; return null; } public T First(delegate bool(T) condition) where T : Component { for (T c in componentTracker[typeof(T)]) if (condition(c)) return c; return null; } public T First(Point point) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (c.Hitbox.Check(point)) return c as T; return null; } public T First(Point point, delegate bool(T) condition) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (condition(c) && c.Hitbox.Check(point)) return c as T; return null; } public T First(Rect rect) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (c.Hitbox.Check(rect)) return c as T; return null; } public T First(Rect rect, delegate bool(T) condition) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (condition(c) && c.Hitbox.Check(rect)) return c as T; return null; } public List All(List into) where T : Component { for (T c in componentTracker[typeof(T)]) into.Add(c as T); return into; } public List All(List into, delegate bool(T) condition) where T : Component { for (T c in componentTracker[typeof(T)]) if (condition(c)) into.Add(c as T); return into; } public List All(Point point, List into) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (c.Hitbox.Check(point)) into.Add(c as T); return into; } public List All(Point point, List into, delegate bool(T) condition) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (condition(c) && c.Hitbox.Check(point)) into.Add(c as T); return into; } public List All(Rect rect, List into, delegate bool(T) condition) where T : Component, IHasHitbox { for (T c in componentTracker[typeof(T)]) if (condition(c) && c.Hitbox.Check(rect)) into.Add(c as T); return into; } } }