2020-05-05 11:50:38 +08:00
|
|
|
using System.Collections;
|
|
|
|
using System;
|
|
|
|
|
|
|
|
namespace Strawberry
|
|
|
|
{
|
|
|
|
public class Scene
|
|
|
|
{
|
2020-05-05 12:11:12 +08:00
|
|
|
public float TimeStarted { get; private set; }
|
|
|
|
|
2020-05-05 11:50:38 +08:00
|
|
|
private List<Entity> entities;
|
|
|
|
private HashSet<Entity> toRemove;
|
|
|
|
private HashSet<Entity> toAdd;
|
2020-05-22 12:24:04 +08:00
|
|
|
private Dictionary<Type, List<Component>> componentTracker;
|
2020-05-05 11:50:38 +08:00
|
|
|
|
|
|
|
public this()
|
|
|
|
{
|
|
|
|
entities = new List<Entity>();
|
|
|
|
toAdd = new HashSet<Entity>();
|
|
|
|
toRemove = new HashSet<Entity>();
|
2020-05-22 12:24:04 +08:00
|
|
|
|
|
|
|
componentTracker = new Dictionary<Type, List<Component>>();
|
2021-02-05 15:11:51 +08:00
|
|
|
for (let type in Tracker.AssignmentLists.Keys)
|
|
|
|
componentTracker.Add(type, new List<Component>());
|
|
|
|
for (let type in Tracker.Interfaces)
|
2020-05-22 12:24:04 +08:00
|
|
|
componentTracker.Add(type, new List<Component>());
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2020-05-22 12:24:04 +08:00
|
|
|
|
|
|
|
for (let list in componentTracker.Values)
|
|
|
|
delete list;
|
|
|
|
delete componentTracker;
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void Started()
|
|
|
|
{
|
2020-05-05 12:11:12 +08:00
|
|
|
TimeStarted = Time.Elapsed;
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void Update()
|
|
|
|
{
|
|
|
|
UpdateLists();
|
2021-02-05 15:11:51 +08:00
|
|
|
|
|
|
|
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public virtual void Draw()
|
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public Entity Add(Entity e)
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
|
|
|
if (e.Scene == null)
|
|
|
|
toAdd.Add(e);
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public Entity Remove(Entity e)
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
|
|
|
if (e.Scene == this)
|
|
|
|
toRemove.Add(e);
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UpdateLists()
|
|
|
|
{
|
|
|
|
if (toRemove.Count > 0)
|
|
|
|
{
|
2020-05-31 07:19:46 +08:00
|
|
|
for (let e in toRemove)
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
|
|
|
entities.Remove(e);
|
2020-05-31 07:19:46 +08:00
|
|
|
e.[Friend]Removed();
|
2020-05-05 11:50:38 +08:00
|
|
|
if (e.DeleteOnRemove)
|
|
|
|
delete e;
|
|
|
|
}
|
|
|
|
|
|
|
|
toRemove.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (toAdd.Count > 0)
|
|
|
|
{
|
2020-05-31 07:19:46 +08:00
|
|
|
for (let e in toAdd)
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
|
|
|
entities.Add(e);
|
2020-05-31 07:19:46 +08:00
|
|
|
e.[Friend]Added(this);
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
2021-02-07 08:37:38 +08:00
|
|
|
toAdd.Clear();
|
2020-05-06 10:53:13 +08:00
|
|
|
}
|
|
|
|
|
2020-05-31 07:19:46 +08:00
|
|
|
for (let e in entities)
|
|
|
|
e.[Friend]UpdateLists();
|
2021-02-07 08:37:38 +08:00
|
|
|
for (let e in entities)
|
|
|
|
e.[Friend]AwakeCheck();
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
|
2020-05-22 12:24:04 +08:00
|
|
|
// Tracking
|
|
|
|
|
|
|
|
private void TrackComponent(Component c)
|
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (let t in Tracker.AssignmentLists[c.GetType()])
|
2020-05-22 12:24:04 +08:00
|
|
|
componentTracker[t].Add(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UntrackComponent(Component c)
|
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (let t in Tracker.AssignmentLists[c.GetType()])
|
2020-05-22 12:24:04 +08:00
|
|
|
componentTracker[t].Remove(c);
|
|
|
|
}
|
|
|
|
|
2020-05-05 12:11:12 +08:00
|
|
|
// Time
|
|
|
|
|
2020-05-08 10:10:54 +08:00
|
|
|
public float TimeElapsed => Time.Elapsed - TimeStarted;
|
|
|
|
public float PreviousTimeElapsed => Time.PreviousElapsed - TimeStarted;
|
2020-05-05 12:11:12 +08:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
/*
|
|
|
|
Finding Components
|
|
|
|
*/
|
2020-05-05 11:50:38 +08:00
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public int Count<T>() where T : Component
|
2020-05-22 12:24:04 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
return componentTracker[typeof(T)].Count;
|
2020-05-22 12:24:04 +08:00
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public int Count<T>(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<T>(delegate bool(T) condition) where T : Component
|
|
|
|
{
|
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (condition(c))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public bool Check<T>(Point point) where T : Component, IHasHitbox
|
2020-09-13 14:52:13 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (c.Hitbox.Check(point))
|
2020-09-13 14:52:13 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public bool Check<T>(Rect rect) where T : Component, IHasHitbox
|
2020-09-13 14:52:13 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (c.Hitbox.Check(rect))
|
2020-09-13 14:52:13 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public T First<T>() where T : Component
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
return c;
|
2020-05-05 11:50:38 +08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public T First<T>(delegate bool(T) condition) where T : Component
|
|
|
|
{
|
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (condition(c))
|
|
|
|
return c;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public T First<T>(Point point) where T : Component, IHasHitbox
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (c.Hitbox.Check(point))
|
|
|
|
return c as T;
|
2020-05-05 11:50:38 +08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public T First<T>(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;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public T First<T>(Rect rect) where T : Component, IHasHitbox
|
2020-05-05 11:50:38 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (c.Hitbox.Check(rect))
|
|
|
|
return c as T;
|
2020-05-05 11:50:38 +08:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public T First<T>(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<T> All<T>(List<T> into) where T : Component
|
2020-09-20 13:46:45 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
2020-09-20 13:46:45 +08:00
|
|
|
into.Add(c as T);
|
|
|
|
return into;
|
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public List<T> All<T>(List<T> 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;
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:11:51 +08:00
|
|
|
public List<T> All<T>(Point point, List<T> into) where T : Component, IHasHitbox
|
2020-09-20 13:46:45 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (c.Hitbox.Check(point))
|
2020-09-20 13:46:45 +08:00
|
|
|
into.Add(c as T);
|
|
|
|
return into;
|
|
|
|
}
|
|
|
|
|
2021-02-07 08:37:38 +08:00
|
|
|
public List<T> All<T>(Point point, List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
|
2020-09-20 13:46:45 +08:00
|
|
|
{
|
2021-02-05 15:11:51 +08:00
|
|
|
for (T c in componentTracker[typeof(T)])
|
2021-02-07 08:37:38 +08:00
|
|
|
if (condition(c) && c.Hitbox.Check(point))
|
|
|
|
into.Add(c as T);
|
|
|
|
return into;
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<T> All<T>(Rect rect, List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
|
|
|
|
{
|
|
|
|
for (T c in componentTracker[typeof(T)])
|
|
|
|
if (condition(c) && c.Hitbox.Check(rect))
|
2020-09-20 13:46:45 +08:00
|
|
|
into.Add(c as T);
|
|
|
|
return into;
|
|
|
|
}
|
2020-05-05 11:50:38 +08:00
|
|
|
}
|
|
|
|
}
|