2021-01-26 00:19:24 +01:00
|
|
|
package armory.system;
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
class FSM<T> {
|
|
|
|
final transitions = new Array<Transition<T>>();
|
|
|
|
final tempTransitions = new Array<Transition<T>>();
|
|
|
|
var state: Null<State<T>>;
|
2021-01-26 00:19:24 +01:00
|
|
|
var entered = false;
|
|
|
|
|
|
|
|
public function new() {}
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
public function bindTransition(canEnter: Void -> Bool, fromState: State<T>, toState: State<T>) {
|
|
|
|
final transition = new Transition<T>(canEnter, fromState, toState);
|
|
|
|
transitions.push(transition);
|
2021-01-26 00:19:24 +01:00
|
|
|
syncTransitions();
|
|
|
|
}
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
public function setInitState(state: State<T>) {
|
|
|
|
this.state = state;
|
2021-01-26 00:19:24 +01:00
|
|
|
syncTransitions();
|
|
|
|
}
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
public function update() {
|
2021-01-26 00:19:24 +01:00
|
|
|
if (!entered) {
|
|
|
|
state.onEnter();
|
|
|
|
entered = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
state.onUpdate();
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
for (transition in tempTransitions) {
|
|
|
|
if (transition.canEnter()) {
|
2021-01-26 00:19:24 +01:00
|
|
|
state.onExit();
|
2021-02-14 23:21:26 +01:00
|
|
|
state = transition.toState;
|
2021-01-26 00:19:24 +01:00
|
|
|
entered = false;
|
|
|
|
syncTransitions();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
public function syncTransitions() {
|
|
|
|
tempTransitions.resize(0);
|
2021-01-26 00:19:24 +01:00
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
for (transition in transitions) {
|
|
|
|
if (transition.fromState == state) tempTransitions.push(transition);
|
|
|
|
}
|
2021-01-26 00:19:24 +01:00
|
|
|
}
|
2021-02-14 23:21:26 +01:00
|
|
|
}
|
2021-01-26 00:19:24 +01:00
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
class Transition<T> {
|
|
|
|
public final canEnter: Void -> Bool;
|
|
|
|
public final fromState: State<T>;
|
|
|
|
public final toState: State<T>;
|
2021-01-26 00:19:24 +01:00
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
public function new(canEnter: Void -> Bool, fromState: State<T>, toState: State<T>) {
|
|
|
|
this.canEnter = canEnter;
|
|
|
|
this.fromState = fromState;
|
|
|
|
this.toState = toState;
|
2021-01-26 00:19:24 +01:00
|
|
|
}
|
2021-02-14 23:21:26 +01:00
|
|
|
}
|
2021-01-26 00:19:24 +01:00
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
class State<T> {
|
|
|
|
final owner: T;
|
|
|
|
|
|
|
|
public function new(owner: T) {
|
|
|
|
this.owner = owner;
|
2021-01-26 00:19:24 +01:00
|
|
|
}
|
|
|
|
|
2021-02-14 23:21:26 +01:00
|
|
|
public function onEnter() {}
|
|
|
|
|
|
|
|
public function onUpdate() {}
|
|
|
|
|
|
|
|
public function onExit() {}
|
2021-01-26 00:19:24 +01:00
|
|
|
}
|