diff --git a/src/Components/Logic/StateMachine.bf b/src/Components/Logic/StateMachine.bf new file mode 100644 index 0000000..30e8be2 --- /dev/null +++ b/src/Components/Logic/StateMachine.bf @@ -0,0 +1,137 @@ +using System; +using System.Collections; + +namespace Strawberry +{ + public class StateMachine : Component where TIndex : struct, IHashable + { + private Dictionary states = new Dictionary() ~ delete _; + private TIndex state; + private bool inStateCall; + + public TIndex PreviousState { get; private set; } + public TIndex NextState { get; private set; } + + public this(TIndex startState) + : base(true, false) + { + NextState = PreviousState = state = startState; + } + + public ~this() + { + for (let s in states.Values) + delete s; + } + + public override void Started() + { + CallEnter(); + } + + public override void Update() + { + CallUpdate(); + } + + public override void Draw() + { + + } + + public void Add(TIndex state, delegate TIndex() enter = null, delegate TIndex() update = null, delegate TIndex() exit = null) + { + let s = new State(); + s.Enter = enter; + s.Update = update; + s.Exit = exit; + states[state] = s; + } + + public TIndex State + { + get => state; + set => Set(value); + } + + private Result Set(TIndex to) + { + if (inStateCall) + Runtime.FatalError("Cannot set State directly from inside a State Enter/Exit/Update call. Return the desired State change instead."); + + if (to != state) + { + NextState = to; + if (CallExit()) + return true; + + PreviousState = state; + state = to; + + CallEnter(); + return true; + } + else + return false; + } + + private bool CallEnter() + { + let s = states[state]; + if (s != null) + { + inStateCall = true; + let set = s.Enter(); + inStateCall = false; + return Set(set); + } + else + return false; + } + + private bool CallUpdate() + { + let s = states[state]; + if (s != null) + { + inStateCall = true; + let set = s.Update(); + inStateCall = false; + return Set(set); + } + else + return false; + } + + private bool CallExit() + { + let s = states[state]; + if (s != null) + { + inStateCall = true; + let set = s.Exit(); + inStateCall = false; + return Set(set); + } + else + return false; + } + + public class State + { + public delegate TIndex() Enter; + public delegate TIndex() Update; + public delegate TIndex() Exit; + + public ~this() + { + if (Enter != null) + delete Enter; + if (Update != null) + delete Update; + if (Exit != null) + delete Exit; + } + } + } +} diff --git a/src/Components/Timer.bf b/src/Components/Logic/Timer.bf similarity index 92% rename from src/Components/Timer.bf rename to src/Components/Logic/Timer.bf index a52f25d..43ede34 100644 --- a/src/Components/Timer.bf +++ b/src/Components/Logic/Timer.bf @@ -24,6 +24,33 @@ namespace Strawberry RemoveOnComplete = destroyOnComplete; } + public override void Started() + { + + } + + public override void Update() + { + if (value > 0) + { + value -= Time.Delta; + if (value <= 0) + { + value = 0; + Active = false; + + OnComplete?.Invoke(); + if (RemoveOnComplete) + RemoveSelf(); + } + } + } + + public override void Draw() + { + + } + public float Value { [Inline] @@ -47,23 +74,6 @@ namespace Strawberry Active = false; } - public override void Update() - { - if (value > 0) - { - value -= Time.Delta; - if (value <= 0) - { - value = 0; - Active = false; - - OnComplete?.Invoke(); - if (RemoveOnComplete) - RemoveSelf(); - } - } - } - static public implicit operator bool(Timer timer) { return timer.value > 0; diff --git a/src/Core/Component.bf b/src/Core/Component.bf index 59f8afe..7ebb9a6 100644 --- a/src/Core/Component.bf +++ b/src/Core/Component.bf @@ -15,30 +15,19 @@ namespace Strawberry Visible = visible; } - public void Added(Entity entity) + private void Added(Entity entity) { Entity = entity; } - public void Removed() + private void Removed() { Entity = null; } - public virtual void Started() - { - - } - - public virtual void Update() - { - - } - - public virtual void Draw() - { - - } + public abstract void Started(); + public abstract void Update(); + public abstract void Draw(); [Inline] public void RemoveSelf() diff --git a/src/Core/Entity.bf b/src/Core/Entity.bf index fe91b73..cbca976 100644 --- a/src/Core/Entity.bf +++ b/src/Core/Entity.bf @@ -89,7 +89,7 @@ namespace Strawberry { components.Remove(c); Scene.[Friend]UntrackComponent(c); - c.Removed(); + c.[Friend]Removed(); delete c; } @@ -102,7 +102,7 @@ namespace Strawberry { components.Add(c); Scene.[Friend]TrackComponent(c); - c.Added(this); + c.[Friend]Added(this); } toAdd.Clear(); diff --git a/src/Physics/Actor.bf b/src/Physics/Actor.bf index b2fa705..f06812a 100644 --- a/src/Physics/Actor.bf +++ b/src/Physics/Actor.bf @@ -39,7 +39,6 @@ namespace Strawberry public override void Update() { base.Update(); - MovedByGeometry = Point.Zero; }