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; public this() { entities = new List(); toAdd = new HashSet(); toRemove = new HashSet(); } 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; } public virtual void Started() { TimeStarted = Time.Elapsed; } public virtual void Update() { UpdateLists(); for (var e in entities) if (e.Active) e.Update(); } public virtual void Draw() { for (var 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 (var e in toRemove) { entities.Remove(e); e.Removed(); if (e.DeleteOnRemove) delete e; } toRemove.Clear(); } if (toAdd.Count > 0) { for (var e in toAdd) { entities.Add(e); e.Added(this); } } for (var e in entities) e.UpdateLists(); if (toAdd.Count > 0) { for (var e in toAdd) e.Started(); toAdd.Clear(); } } // 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 T First() where T : Entity { for (var e in entities) if (e is T) return e as T; return null; } public T First(Point point) where T : Entity { for (var e in entities) if (e is T && e.Check(point)) return e as T; return null; } public T First(Rect rect) where T : Entity { for (var e in entities) if (e is T && e.Check(rect)) return e as T; return null; } public List All(List into) where T : Entity { for (var e in entities) if (e is T) into.Add(e as T); return into; } public List All(Point point, List into) where T : Entity { for (var e in entities) if (e is T && e.Check(point)) into.Add(e as T); return into; } public List All(Rect rect, List into) where T : Entity { for (var e in entities) if (e is T && e.Check(rect)) into.Add(e as T); return into; } } }