All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.org.osflash.signals.DeluxeSignal.as Maven / Gradle / Ivy

package org.osflash.signals
{
	import org.osflash.signals.events.IBubbleEventHandler;
	import org.osflash.signals.events.IEvent;

	/**
	 * Allows the valueClasses to be set in MXML, e.g.
	 * {[String, uint]}
	 */
	[DefaultProperty("valueClasses")]
	/**
	 * Signal dispatches events to multiple listeners.
	 * It is inspired by C# events and delegates, and by
	 * signals and slots
	 * in Qt.
	 * A Signal adds event dispatching functionality through composition and interfaces,
	 * rather than inheriting from a dispatcher.
	 * 

* Project home: http://github.com/robertpenner/as3-signals/ */ public class DeluxeSignal extends PrioritySignal { protected var _target : Object; /** @inheritDoc */ public function get target() : Object { return _target; } public function set target( value : Object ) : void { if( value == _target ) return; removeAll(); _target = value; } /** * Creates a DeluxeSignal instance to dispatch events on behalf of a target object. * @param target The object the signal is dispatching events on behalf of. * @param valueClasses Any number of class references that enable type checks in dispatch(). * For example, new DeluxeSignal(this, String, uint) * would allow: signal.dispatch("the Answer", 42) * but not: signal.dispatch(true, 42.5) * nor: signal.dispatch() * * NOTE: Subclasses cannot call super.apply(null, valueClasses), * but this constructor has logic to support super(valueClasses). */ public function DeluxeSignal( target : Object = null, ...valueClasses ) { _target = target; // Cannot use super.apply(null, valueClasses), so allow the subclass to call super(valueClasses). valueClasses = (valueClasses.length == 1 && valueClasses[ 0 ] is Array) ? valueClasses[ 0 ] : valueClasses; super( valueClasses ); } /** * @inheritDoc * @throws ArgumentError ArgumentError: Incorrect number of arguments. * @throws ArgumentError ArgumentError: Value object is not an instance of the appropriate valueClasses Class. */ override public function dispatch( ...valueObjects ) : void { // Validate value objects against pre-defined value classes. const numValueClasses : int = _valueClasses.length; const numValueObjects : int = valueObjects.length; if( numValueObjects < numValueClasses ) { throw new ArgumentError( 'Incorrect number of arguments. ' + 'Expected at least ' + numValueClasses + ' but received ' + numValueObjects + '.' ); } // Cannot dispatch differently typed objects than declared classes. for( var i : int = 0; i < numValueClasses; i++ ) { // Optimized for the optimistic case that values are correct. if( valueObjects[ i ] is _valueClasses[ i ] || valueObjects[ i ] === null ) continue; throw new ArgumentError( 'Value object <' + valueObjects[ i ] + '> is not an instance of <' + _valueClasses[ i ] + '>.' ); } // Extract and clone event object if necessary. var event : IEvent = valueObjects[ 0 ] as IEvent; if( event ) { if( event.target ) { event = event.clone(); valueObjects[ 0 ] = event; } event.target = target; event.currentTarget = target; event.signal = this; } // Broadcast to listeners. var slotsToProcess : SlotList = slots; while( slotsToProcess.nonEmpty ) { slotsToProcess.head.execute( valueObjects ); slotsToProcess = slotsToProcess.tail; } // Bubble the event as far as possible. if( !event || !event.bubbles ) return; var currentTarget : Object = target; while( currentTarget && currentTarget.hasOwnProperty( "parent" ) ) { currentTarget = currentTarget[ "parent" ]; if( !currentTarget ) break; if( currentTarget is IBubbleEventHandler ) { // onEventBubbled() can stop the bubbling by returning false. if( !IBubbleEventHandler( event.currentTarget = currentTarget ).onEventBubbled( event ) ) break; } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy