scaffold.libs_as.starling.events.EventDispatcher.as Maven / Gradle / Ivy
// =================================================================================================
//
// Starling Framework
// Copyright 2011-2015 Gamua. All Rights Reserved.
//
// This program is free software. You can redistribute and/or modify it
// in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================
package starling.events
{
import flash.utils.Dictionary;
import starling.core.starling_internal;
import starling.display.DisplayObject;
use namespace starling_internal;
/** The EventDispatcher class is the base class for all classes that dispatch events.
* This is the Starling version of the Flash class with the same name.
*
* The event mechanism is a key feature of Starling's architecture. Objects can communicate
* with each other through events. Compared the the Flash event system, Starling's event system
* was simplified. The main difference is that Starling events have no "Capture" phase.
* They are simply dispatched at the target and may optionally bubble up. They cannot move
* in the opposite direction.
*
* As in the conventional Flash classes, display objects inherit from EventDispatcher
* and can thus dispatch events. Beware, though, that the Starling event classes are
* not compatible with Flash events: Starling display objects dispatch
* Starling events, which will bubble along Starling display objects - but they cannot
* dispatch Flash events or bubble along Flash display objects.
*
* @see Event
* @see starling.display.DisplayObject DisplayObject
*/
public class EventDispatcher
{
private var _eventListeners:Dictionary;
/** Helper object. */
private static var sBubbleChains:Array = [];
/** Creates an EventDispatcher. */
public function EventDispatcher()
{ }
/** Registers an event listener at a certain object. */
public function addEventListener(type:String, listener:Function):void
{
if (_eventListeners == null)
_eventListeners = new Dictionary();
var listeners:Vector. = _eventListeners[type] as Vector.;
if (listeners == null)
_eventListeners[type] = new [listener];
else if (listeners.indexOf(listener) == -1) // check for duplicates
listeners[listeners.length] = listener; // avoid 'push'
}
/** Removes an event listener from the object. */
public function removeEventListener(type:String, listener:Function):void
{
if (_eventListeners)
{
var listeners:Vector. = _eventListeners[type] as Vector.;
var numListeners:int = listeners ? listeners.length : 0;
if (numListeners > 0)
{
// we must not modify the original vector, but work on a copy.
// (see comment in 'invokeEvent')
var index:int = listeners.indexOf(listener);
if (index != -1)
{
var restListeners:Vector. = listeners.slice(0, index);
for (var i:int=index+1; i = _eventListeners ?
_eventListeners[event.type] as Vector. : null;
var numListeners:int = listeners == null ? 0 : listeners.length;
if (numListeners)
{
event.setCurrentTarget(this);
// we can enumerate directly over the vector, because:
// when somebody modifies the list while we're looping, "addEventListener" is not
// problematic, and "removeEventListener" will create a new Vector, anyway.
for (var i:int=0; i;
var element:DisplayObject = this as DisplayObject;
var length:int = 1;
if (sBubbleChains.length > 0) { chain = sBubbleChains.pop(); chain[0] = element; }
else chain = new [element];
while ((element = element.parent) != null)
chain[int(length++)] = element;
for (var i:int=0; i = _eventListeners ? _eventListeners[type] : null;
if (listeners == null) return false;
else
{
if (listener != null) return listeners.indexOf(listener) != -1;
else return listeners.length != 0;
}
}
}
}