using System.Collections; using System; namespace Strawberry { public class Scene { public float TimeStarted { get; private set; } public Rect Bounds; private List entities; private HashSet toRemove; private HashSet toAdd; private Dictionary> entityTracker; private Dictionary> componentTracker; public this() { entities = new List(); toAdd = new HashSet(); toRemove = new HashSet(); entityTracker = new Dictionary>(); for (let type in Game.[Friend]entityAssignableLists.Keys) entityTracker.Add(type, new List()); componentTracker = new Dictionary>(); for (let type in Game.[Friend]componentAssignableLists.Keys) 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 entityTracker.Values) delete list; delete entityTracker; for (let list in componentTracker.Values) delete list; delete componentTracker; } public virtual void Started() { TimeStarted = Time.Elapsed; } public virtual void Update() { UpdateLists(); for (let e in entities) if (e.Active) e.Update(); } public virtual void Draw() { for (let e in entities) if (e.Visible) e.Draw(); } public T Add(T e) where T : Entity { if (e.Scene == null) toAdd.Add(e); return e; } public T Remove(T e) where T : Entity { if (e.Scene == this) toRemove.Add(e); return e; } private void UpdateLists() { if (toRemove.Count > 0) { for (let e in toRemove) { entities.Remove(e); UntrackEntity(e); e.[Friend]Removed(); if (e.DeleteOnRemove) delete e; } toRemove.Clear(); } if (toAdd.Count > 0) { for (let e in toAdd) { entities.Add(e); TrackEntity(e); e.[Friend]Added(this); } entities.Sort(scope => Entity.Compare); } for (let e in entities) e.[Friend]UpdateLists(); if (toAdd.Count > 0) { for (let e in toAdd) e.Started(); toAdd.Clear(); } } // Tracking private void TrackEntity(Entity e) { for (let t in Game.[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 Game.[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 Game.[Friend]componentAssignableLists[c.GetType()]) componentTracker[t].Add(c); } private void UntrackComponent(Component c) { for (let t in Game.[Friend]componentAssignableLists[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 Entities public int Count() where T : Entity { return entityTracker[typeof(T)].Count; } public bool Check(Point point) where T : Entity { for (let e in entityTracker[typeof(T)]) if (e.Check(point)) return true; return false; } public bool Check(Rect rect) where T : Entity { for (let e in entityTracker[typeof(T)]) if (e.Check(rect)) return true; return false; } public T First() where T : Entity { for (let e in entityTracker[typeof(T)]) return e as T; return null; } public T First(Point point) where T : Entity { for (let e in entityTracker[typeof(T)]) if (e.Check(point)) return e as T; return null; } public T First(Rect rect) where T : Entity { for (let e in entityTracker[typeof(T)]) if (e.Check(rect)) return e as T; return null; } public List All(List into) where T : Entity { for (let e in entityTracker[typeof(T)]) into.Add(e as T); return into; } public List All(Point point, List into) where T : Entity { for (let e in entityTracker[typeof(T)]) if (e.Check(point)) into.Add(e as T); return into; } public List All(Rect rect, List into) where T : Entity { for (let e in entityTracker[typeof(T)]) if (e.Check(rect)) into.Add(e as T); return into; } /* Finding Components */ public int Count() where T : Component { return componentTracker[typeof(T)].Count; } } }