Skip to content

Instantly share code, notes, and snippets.

/gist:9aeb57a266c7435684ef Secret
Created Feb 23, 2011

Embed
What would you like to do?
FunctionSlot1
/*
MIT License, Copyright (c) 2010 Jackson Dunstan
http://jacksondunstan.com/articles/585
Modified by Mark Knol, blog.stroep.nl
*/
package com.jacksondunstan.signals
{
import flash.utils.*;
import flash.errors.*;
/**
* A signal holds a list of slots and calls them all when the signal is
* "dispatched". This signal passes one parameter to its slots.
* @author Jackson Dunstan
*/
public class FunctionSignal1
{
/** List of Slot1 to call when we dispatch */
private var __slots:Vector.<Slot1> = new Vector.<Slot1>();
private var __dict:Dictionary = new Dictionary();
/** If we are currently dispatching and haven't copied the __slots list,
*** we need to copy it before changes (either add or remove) are made */
private var __slotsNeedCopying:Boolean;
/** Number of dispatch() calls that are currently calling back listeners */
private var __numDispatchesInProgress:uint;
/**
* Add a slot to be called during dispatch()
* @param slot Slot to add. This function has no effect if the slot is
* null or the signal already has the slot.
*/
public function addSlot(func:Function): void
{
// Only add valid slots we don't already have
if (func == null || __slots.indexOf(__dict[func]) >= 0)
{
return;
}
// Copy the list during dispatch
if (__slotsNeedCopying)
{
__slots = __slots.slice();
__slotsNeedCopying = false;
}
__slots[__slots.length] = __dict[func] = new FunctionSlot1(func);
}
/**
* Remove a slot so that it is not called during dispatch()
* @param slot Slot to remove. This function has no effect if the slot
* is null or the signal does not have the slot.
*/
public function removeSlot(func:Function): void
{
// Can't remove a slot we don't have
var index:int = __slots.indexOf(__dict[func]);
if (index < 0)
{
return;
}
// Copy the list during dispatch
if (__slotsNeedCopying)
{
__slots = __slots.slice();
__slotsNeedCopying = false;
}
__slots.splice(index, 1);
}
/**
* Remove all slots so that they are not called during dispatch()
*/
public function removeAllSlots(): void
{
if (__slotsNeedCopying)
{
__slots.concat();
__slotsNeedCopying = false;
}
else
{
__slots.length = 0;
}
}
/**
* Check if the signal has a slot
* @param slot Slot to check
* @return If the signal has the given slot
*/
public function hasSlot(func:Function): Boolean
{
return __slots.indexOf(__dict[func]) >= 0;
}
/**
* Get the number of slots the signal has
* @return The number of slots the signal has
*/
public function get numSlots(): uint
{
return __slots.length;
}
/**
* Get the index of a slot in the list of slots this signal has
* @return The index of the given slot in the list of slots this signal
* has or -1 if this signal does not have the given slot
*/
public function getSlotIndex(func:Function): int
{
return __slots.indexOf(__dict[func]);
}
/**
* Call all of the slots the signal has. Calls to addSlot() or
* removeSlot() by any slot in response to these calls will not change
* which slots are called or the order in which they are called during
* this particular dispatch.
* @param arg Argument to pass to the slots
*/
public function dispatch(arg:*): void
{
__slotsNeedCopying = true;
__numDispatchesInProgress++;
for (var i:uint, len:uint = __slots.length; i < len; ++i)
{
__slots[i].onSignal1(arg);
}
__numDispatchesInProgress--;
if (__numDispatchesInProgress == 0)
{
__slotsNeedCopying = false;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.