Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
118 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,45 @@ | ||
package de.headjump.superstate { | ||
|
||
public class Superstate { | ||
private var _parent:Superstate; | ||
private var _states:Object; | ||
private var _hooks:Object; | ||
private var _machine:SuperstateMachine; | ||
private var _name:String; | ||
|
||
public function Superstate(hooks:Object = null, states:Object = null) { | ||
_states = states; | ||
/** | ||
* | ||
* @param hooks.enter | ||
* @param hooks.leave | ||
* @param hooks.can can enter from path? -> function(path:Array):Boolean | ||
* @param children | ||
*/ | ||
public function Superstate(hooks:Object = null, children:Object = null) { | ||
_states = children; | ||
_hooks = hooks; | ||
_parent = null; | ||
_machine = null; | ||
_name = ""; // set by machine | ||
} | ||
|
||
protected function get hooks():Object { return _hooks; } | ||
protected function get machine():SuperstateMachine { return _machine; } | ||
public function get machine():SuperstateMachine { return _machine; } | ||
public function set machine(val:SuperstateMachine):void { _machine = val; } | ||
|
||
public function set parent(val:Superstate):void { _parent = val; } | ||
public function set name(val:String):void { _name = val; } | ||
public function get name():String { return _name; } | ||
|
||
public function get path_to_root():Array { | ||
var res:Array = []; | ||
var par:Object = this; | ||
while((par = par.parent) && (!par is SuperstateMachine)) { | ||
res.push(par); | ||
} | ||
return res; | ||
public function get states():Object { return _states; } | ||
|
||
public function canEnter(path:Array):Boolean { | ||
if(_hooks && _hooks.can) return _hooks.can(path); | ||
return true; | ||
} | ||
|
||
public function onEnter():void { | ||
if(_hooks && _hooks.enter) _hooks.enter(); | ||
public function onEnter(path:Array, as_init_state:Boolean = false):void { | ||
if(_hooks && _hooks.enter) _hooks.enter(path, as_init_state); | ||
} | ||
|
||
public function onLeave():void { | ||
if(_hooks && _hooks.leave) _hooks.enter(); | ||
public function onLeave(path:Array):void { | ||
if(_hooks && _hooks.leave) _hooks.leave(path); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,103 @@ | ||
package de.headjump.superstate { | ||
|
||
public class SuperstateMachine extends Superstate { | ||
private var _paths:Vector.<SuperstateMatchineStatePathInfo>; | ||
private var _current_path:Array; | ||
private var _current:Superstate; | ||
private var _current_from:Superstate; | ||
private var _current_to:Superstate; | ||
|
||
public function SuperstateMachine(states:Object = null) { | ||
super(null, states); | ||
|
||
_current_exit_path = null; | ||
_current_enter_path = null; | ||
_current_from = null; | ||
_current_to = null; | ||
_current = null; | ||
|
||
populatePaths(this, []); | ||
} | ||
|
||
/** | ||
* Fill paths info with states and all their parents | ||
*/ | ||
private function populatePaths(current:Superstate, path_to_root:Array):void { | ||
var path_to_root_with_self:Array = path_to_root.concat([current]); | ||
for(var k:String in current.states) { | ||
if(states.hasOwnProperty(k)) { | ||
var s:Superstate = states[k]; | ||
s.name = k; | ||
s.machine = this; | ||
_paths.push(new SuperstateMatchineStatePathInfo(s, path_to_root_with_self)); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Find first state matching name String (e.g "walking" or "shotgun.primary") | ||
* @param name | ||
* @return | ||
*/ | ||
public function stateByName(name:String):Superstate { | ||
for each(var s:SuperstateMatchineStatePathInfo in _paths) { | ||
if(s.matches(name)) return s.state; | ||
} | ||
return null; | ||
} | ||
|
||
public function get current_exit_path():Array { return _current_exit_path; } | ||
public function get current_enter_path():Array { return _current_enter_path; } | ||
public function get current():Superstate { return _current; } | ||
public function get current_from():Superstate { return _current_from; } | ||
public function get current_to():Superstate { return _current_to; } | ||
|
||
public function to(state_name:String):SuperstateMachine { | ||
var target:Superstate = stateByName(state_name); | ||
if(!target || target === current) return this; // state not found || already there: do nothing | ||
|
||
_current_from = current; | ||
_current_to = target; | ||
var paths:Array = pathFromTo(current, target); | ||
_current_exit_path = paths[0]; | ||
_current_enter_path = paths[0]; | ||
|
||
// move along paths | ||
|
||
// reset | ||
_current_from = null; | ||
_current_to = null; | ||
_current_exit_path = null; | ||
_current_enter_path = null; | ||
_current = target; | ||
|
||
return this; | ||
} | ||
|
||
private function pathFromTo(from:Superstate, to:Superstate):Array { | ||
return null; | ||
} | ||
} | ||
} | ||
|
||
import de.headjump.superstate.Superstate; | ||
|
||
class SuperstateMatchineStatePathInfo { | ||
private var _me:Superstate; | ||
private var _parents:Array; | ||
private var _string_path:String; | ||
|
||
public function SuperstateMatchineStatePathInfo(self:Superstate, parents:Array) { | ||
_me = self; | ||
_parents = parents; | ||
_string_path = "." + parents.map(function(el:Superstate, ...ignore):String { return el.name; })+ "."; | ||
} | ||
|
||
public function get state():Superstate { return _me; } | ||
|
||
public function toString():String { return _string_path.substring(1, -1); } | ||
|
||
public function matches(name:String):Boolean { | ||
return _string_path.indexOf("." + name + ".") !== -1; | ||
} | ||
} |