Created
December 16, 2010 16:09
-
-
Save abeldebeer/743573 to your computer and use it in GitHub Desktop.
AS3Signals implementation of @stray_and_ruby's GuardedCommandMap (first, untested version)
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 org.robotlegs.core | |
{ | |
import org.osflash.signals.ISignal; | |
/** | |
* @author Abel de Beer | |
*/ | |
public interface IGuardedSignalCommandMap | |
{ | |
function mapGuardedSignal(signal:ISignal, commandClass:Class, guards:*, oneShot:Boolean = false):void; | |
function mapGuardedSignalClass(signalClass:Class, commandClass:Class, guards:*, oneShot:Boolean = false):ISignal; | |
} | |
} | |
package org.robotlegs.base | |
{ | |
import org.osflash.signals.ISignal; | |
import org.robotlegs.core.IGuardedSignalCommandMap; | |
import org.robotlegs.core.IInjector; | |
import flash.utils.Dictionary; | |
import flash.utils.describeType; | |
/** | |
* @author Abel de Beer | |
*/ | |
public class GuardedSignalCommandMap extends SignalCommandMap implements IGuardedSignalCommandMap | |
{ | |
protected var verifiedGuardClasses:Dictionary; | |
public static const E_GUARD_NOIMPL:String = "Guard Class does not implement an approve() method."; | |
public function GuardedSignalCommandMap(injector:IInjector) | |
{ | |
super(injector); | |
verifiedGuardClasses = new Dictionary(false); | |
} | |
public function mapGuardedSignal(signal:ISignal, commandClass:Class, guards:*, oneShot:Boolean = false):void | |
{ | |
verifyCommandClass(commandClass); | |
if (hasSignalCommand(signal, commandClass)) | |
return; | |
if(!(guards is Array)) | |
{ | |
guards = [guards]; | |
} | |
verifyGuardClasses(guards); | |
var signalCommandMap:Dictionary = signalMap[signal] ||= new Dictionary(false); | |
var callback:Function = function(a:* = null, b:* = null, c:* = null, d:* = null, e:* = null, f:* = null, g:* = null):void | |
{ | |
routeSignalToGuardedCommand(signal, arguments, commandClass, oneShot, guards); | |
}; | |
signalCommandMap[commandClass] = callback; | |
signal.add(callback); | |
} | |
public function mapGuardedSignalClass(signalClass:Class, commandClass:Class, guards:*, oneShot:Boolean = false):ISignal | |
{ | |
var signal:ISignal = getSignalClassInstance(signalClass); | |
mapGuardedSignal(signal, commandClass, guards, oneShot); | |
return signal; | |
} | |
private function getSignalClassInstance(signalClass:Class):ISignal | |
{ | |
return ISignal(signalClassMap[signalClass]) || createSignalClassInstance(signalClass); | |
} | |
private function createSignalClassInstance(signalClass:Class):ISignal | |
{ | |
var injectorForSignalInstance:IInjector = injector; | |
var signal:ISignal; | |
if(injector.hasMapping(IInjector)) | |
injectorForSignalInstance = injector.getInstance(IInjector); | |
signal = injectorForSignalInstance.instantiate(signalClass); | |
injectorForSignalInstance.mapValue(signalClass, signal); | |
signalClassMap[signalClass] = signal; | |
return signal; | |
} | |
protected function routeSignalToGuardedCommand(signal:ISignal, valueObjects:Array, commandClass:Class, oneshot:Boolean, guardClasses:Array):void | |
{ | |
mapSignalValueClasses(signal.valueClasses, valueObjects); | |
for each (var guardClass:Class in guardClasses) | |
{ | |
var nextGuard:Object = injector.instantiate(guardClass); | |
if (nextGuard.approve() == false) | |
{ | |
unmapSignalValueClasses(signal.valueClasses); | |
return; | |
} | |
} | |
injector.instantiate(commandClass).execute(); | |
if (oneshot) | |
unmapSignal(signal, commandClass); | |
} | |
private function mapSignalValueClasses(valueClasses:Array, valueObjects:Array):void | |
{ | |
for (var i:int = 0; i < valueClasses.length; i++) | |
{ | |
injector.mapValue(valueClasses[i], valueObjects[i]); | |
} | |
} | |
private function unmapSignalValueClasses(valueClasses:Array):void | |
{ | |
for (var i:int = 0; i < valueClasses.length; i++) | |
{ | |
injector.unmap(valueClasses[i]); | |
} | |
} | |
protected function verifyGuardClasses(guardClasses:Array):void | |
{ | |
for each (var guardClass:Class in guardClasses) | |
{ | |
if (!verifiedGuardClasses[guardClass]) | |
{ | |
verifiedGuardClasses[guardClass] = describeType(guardClass).factory.method.(@name == "approve").length(); | |
if (!verifiedGuardClasses[guardClass]) | |
throw new ContextError(E_GUARD_NOIMPL + ' - ' + guardClass); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment