Improved FSM
This commit is contained in:
parent
49a599dc66
commit
0ee35adc81
|
@ -1,49 +1,25 @@
|
||||||
package armory.system;
|
package armory.system;
|
||||||
|
|
||||||
class FSM {
|
class FSM<T> {
|
||||||
var state: Null<State>;
|
final transitions = new Array<Transition<T>>();
|
||||||
var nextState: Null<State>;
|
final tempTransitions = new Array<Transition<T>>();
|
||||||
var transitions = new Array<Transition>();
|
var state: Null<State<T>>;
|
||||||
var tempTransitions = new Array<Transition>();
|
|
||||||
var entered = false;
|
var entered = false;
|
||||||
|
|
||||||
public function new() {}
|
public function new() {}
|
||||||
|
|
||||||
/**
|
public function bindTransition(canEnter: Void -> Bool, fromState: State<T>, toState: State<T>) {
|
||||||
* Set the initial / current state of the FSM and return it
|
final transition = new Transition<T>(canEnter, fromState, toState);
|
||||||
* @param state The state to be set
|
transitions.push(transition);
|
||||||
* @return State
|
syncTransitions();
|
||||||
**/
|
}
|
||||||
public function setState(state: State) {
|
|
||||||
|
public function setInitState(state: State<T>) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
syncTransitions();
|
syncTransitions();
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function update() {
|
||||||
* Bind multiple transitions to the specified state
|
|
||||||
* @param canEnter The function that returns true or false to enter the transition
|
|
||||||
* @param toState The next state the transiiton will return
|
|
||||||
* @param fromStates The states that are allowed to be changed by the next state
|
|
||||||
* @return Void
|
|
||||||
**/
|
|
||||||
public function bindTransitions(canEnter: Void -> Bool, toState: State, fromStates: Array<State>) {
|
|
||||||
for (s in fromStates) {
|
|
||||||
transitions.push(new Transition(canEnter, s, toState));
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTransitions();
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncTransitions() {
|
|
||||||
tempTransitions = [];
|
|
||||||
|
|
||||||
for (t in transitions) {
|
|
||||||
if (t.isConnected(state)) tempTransitions.push(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function run() {
|
|
||||||
if (!entered) {
|
if (!entered) {
|
||||||
state.onEnter();
|
state.onEnter();
|
||||||
entered = true;
|
entered = true;
|
||||||
|
@ -51,45 +27,48 @@ class FSM {
|
||||||
|
|
||||||
state.onUpdate();
|
state.onUpdate();
|
||||||
|
|
||||||
for (t in tempTransitions) {
|
for (transition in tempTransitions) {
|
||||||
if (t.canEnter()) {
|
if (transition.canEnter()) {
|
||||||
nextState = t.getNextState();
|
|
||||||
state.onExit();
|
state.onExit();
|
||||||
state = nextState;
|
state = transition.toState;
|
||||||
entered = false;
|
entered = false;
|
||||||
syncTransitions();
|
syncTransitions();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class Transition {
|
public function syncTransitions() {
|
||||||
final func: Void -> Bool;
|
tempTransitions.resize(0);
|
||||||
final from: State;
|
|
||||||
final to: State;
|
|
||||||
|
|
||||||
public function new(func: Void -> Bool, from: State, to: State) {
|
for (transition in transitions) {
|
||||||
this.func = func;
|
if (transition.fromState == state) tempTransitions.push(transition);
|
||||||
this.from = from;
|
}
|
||||||
this.to = to;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function canEnter() {
|
|
||||||
return func();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isConnected(state: State) {
|
|
||||||
return from == state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNextState() {
|
|
||||||
return to;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
class Transition<T> {
|
||||||
function onEnter(): Void;
|
public final canEnter: Void -> Bool;
|
||||||
function onUpdate(): Void;
|
public final fromState: State<T>;
|
||||||
function onExit(): Void;
|
public final toState: State<T>;
|
||||||
|
|
||||||
|
public function new(canEnter: Void -> Bool, fromState: State<T>, toState: State<T>) {
|
||||||
|
this.canEnter = canEnter;
|
||||||
|
this.fromState = fromState;
|
||||||
|
this.toState = toState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class State<T> {
|
||||||
|
final owner: T;
|
||||||
|
|
||||||
|
public function new(owner: T) {
|
||||||
|
this.owner = owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onEnter() {}
|
||||||
|
|
||||||
|
public function onUpdate() {}
|
||||||
|
|
||||||
|
public function onExit() {}
|
||||||
}
|
}
|
Loading…
Reference in a new issue