Created
July 24, 2012 19:18
-
-
Save vrobel/3172033 to your computer and use it in GitHub Desktop.
SystemEnabledRule
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
package com.blackmoondev.ashes.boot.vo | |
{ | |
import net.richardlord.ash.core.Game; | |
import net.richardlord.ash.core.SystemEnabledRule; | |
import org.hamcrest.Matcher; | |
import org.hamcrest.collection.inArray; | |
import org.hamcrest.core.not; | |
import org.hamcrest.object.equalTo; | |
public class StateSystemRules | |
{ | |
private var systemRules:Vector.<SystemEnabledRule>; | |
public function StateSystemRules() { | |
systemRules = new <SystemEnabledRule>[]; | |
} | |
public function setCurrentState(game:Game, state:String):void { | |
for each (var rule:SystemEnabledRule in systemRules) { | |
rule.update(game, state); | |
} | |
} | |
public function enableSystemsIfState(stateOrStates:*, ...systemClasses):void { | |
var rule:Matcher = getRuleForStateOrStates(stateOrStates); | |
var systemEnabledRule:SystemEnabledRule = new SystemEnabledRule(rule, systemClasses); | |
systemRules.push(systemEnabledRule); | |
} | |
public function disableSystemsIfState(stateOrStates:*, ...systemClasses):void { | |
var rule:Matcher = not(getRuleForStateOrStates(stateOrStates)); | |
var systemEnabledRule:SystemEnabledRule = new SystemEnabledRule(rule, systemClasses); | |
systemRules.push(systemEnabledRule); | |
} | |
private function getRuleForStateOrStates(stateOrStates:*):Matcher { | |
if (stateOrStates is String) { | |
return equalTo(stateOrStates); | |
} else if (stateOrStates is Array) { | |
return inArray(stateOrStates) | |
} else { | |
throw new ArgumentError('Not supported stateOrStates type ' + stateOrStates + ' should be String or Array'); | |
} | |
} | |
} | |
} |
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
package com.blackmoondev.ashes.boot.vo | |
{ | |
import net.richardlord.ash.core.Game; | |
import org.flexunit.assertThat; | |
import org.hamcrest.object.notNullValue; | |
import org.hamcrest.object.nullValue; | |
public class StateSystemRulesTest | |
{ | |
private var game:Game; | |
private var stateRules:StateSystemRules; | |
private static const STATE_A:String = 'STATE_A'; | |
private static const STATE_B:String = 'STATE_B'; | |
[Before] | |
public function setup():void { | |
game = new Game(); | |
game.addSystem(new SystemA(), 0); | |
game.addSystem(new SystemB(), 1); | |
stateRules = new StateSystemRules(); | |
} | |
[Test] | |
public function system_removed_when_state_match_for_disable():void { | |
stateRules.disableSystemsIfState(STATE_A, SystemA); | |
setState(STATE_A); | |
assertThat(game.getSystem(SystemA), nullValue()); | |
} | |
[Test] | |
public function system_not_removed_when_state_not_match_for_disable():void { | |
stateRules.disableSystemsIfState(STATE_A, SystemA); | |
setState(STATE_B); | |
assertThat(game.getSystem(SystemA), notNullValue()); | |
} | |
[Test] | |
public function system_removed_when_state_not_match_for_enable():void { | |
stateRules.enableSystemsIfState(STATE_A, SystemA); | |
setState(STATE_B); | |
assertThat(game.getSystem(SystemA), nullValue()); | |
} | |
[Test] | |
public function system_not_removed_when_state_match_for_enable():void { | |
stateRules.enableSystemsIfState(STATE_A, SystemA); | |
setState(STATE_A); | |
assertThat(game.getSystem(SystemA), notNullValue()); | |
} | |
[Test] | |
public function system_readded_when_state_goes_to_disabled_and_then_not_disabled():void { | |
stateRules.disableSystemsIfState(STATE_A, SystemA); | |
setState(STATE_A); | |
setState(STATE_B); | |
assertThat(game.getSystem(SystemA), notNullValue()); | |
} | |
[Test] | |
public function system_readded_when_state_goes_to_not_enabled_and_then_enabled():void { | |
stateRules.enableSystemsIfState(STATE_A, SystemA); | |
setState(STATE_B); | |
setState(STATE_A); | |
assertThat(game.getSystem(SystemA), notNullValue()); | |
} | |
private function setState(state:String):void { | |
stateRules.setCurrentState(game, state); | |
} | |
} | |
} | |
import net.richardlord.ash.core.System; | |
internal class SystemA extends System {} | |
internal class SystemB extends System {} |
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
//I use this package just to use internal priority value | |
package net.richardlord.ash.core | |
{ | |
import flash.utils.Dictionary; | |
import org.hamcrest.Matcher; | |
public class SystemEnabledRule | |
{ | |
private var _rule:Matcher; | |
private var _systemClasses:Array; | |
private var systemCache:Dictionary = new Dictionary(true); | |
private var inited:Boolean = false; | |
private var added:Boolean = true; //Systems must be added first. | |
public function SystemEnabledRule(rule:Matcher, systemClasses:Array) { | |
_rule = rule; | |
_systemClasses = systemClasses; | |
} | |
public function update(game:Game, checkValue:Object):void { | |
var shouldAdd:Boolean = _rule.matches(checkValue); | |
var stateChange:Boolean = shouldAdd != added; | |
//we cant do addSystems first because systems are not cached yet | |
var notInitedAndShouldRemove:Boolean = !inited && !shouldAdd; | |
var needInvalidation:Boolean = (stateChange) || (notInitedAndShouldRemove); | |
if (needInvalidation) { | |
inited = true; | |
shouldAdd ? addSystems(game) : removeSystems(game) | |
} | |
} | |
private function addSystems(game:Game):void { | |
for (var i:int = 0; i < _systemClasses.length; i++) { | |
addSystem(_systemClasses[i], game); | |
} | |
added = true; | |
} | |
private function addSystem(SystemClass:Class, game:Game):void { | |
var system:System = systemCache[SystemClass]; | |
if(!system) | |
throw new Error("System " + SystemClass + " is not yet created. Add it to the game first"); | |
delete systemCache[SystemClass]; | |
game.addSystem(system, system.priority); | |
} | |
private function removeSystems(game:Game):void { | |
for (var i:int = 0; i < _systemClasses.length; i++) { | |
removeSystem(_systemClasses[i], game); | |
} | |
added = false; | |
} | |
private function removeSystem(SystemClass:Class, game:Game):void { | |
var system:System = game.getSystem(SystemClass); | |
if(!system) | |
throw new Error("System " + SystemClass + " is not yet created. Add it to the game first"); | |
game.removeSystem(system); | |
systemCache[SystemClass] = system; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment