/*jslint plusplus: true, white: true, indent: 2, maxlen: 90 */
/*global $wk$ */
/**
* @author Wolfgang Kowarschick
* @copyright 2012-2013, Wolfgang Kowarschick
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted under the terms of the
* Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported
* (CC BY-NC-SA 3.0: http://creativecommons.org/licenses/by-nc-sa/3.0/).
*/
////////////////////////////////////////////////////////////////////////////////
// Class "$wk$.observer.WKcSignaler"
////////////////////////////////////////////////////////////////////////////////
$wk$("$wk$.WKcClass",
function($)
{ "use strict";
//console.log("WKcSignaler", $.$trace$);
/**
* The class <code>WKcSignaler</code> can be used to signal events
* (observer pattern). The class methods are usually inherited by
* or mixed into other classes.
*
* @class
* @name $wk$.observer.WKcSignaler
* @returns {Object} A new <code>WKcSignaler</code> object.
*/
var WKcSignaler =
new $.WKcClass
({fullName: "$wk$.observer.WKcSignaler",
methods:
{ init:
function()
{ this.v_observers = {}; },
/**
* Adds an observer for events of type <code>p_type</code>.
*
* @method
* @name $wk$.observer.WKcSignaler#addObserver
*
* @param {String|int} p_type
* The type of the event signaled. Usually
* a property value of the object
* <code>$wk$.$E$</code>. The pseudo type
* <code>"*"</code> denotes that all events
* are signaled to the observer.
* @param {Function} p_observer
* A callback function. The parameter list of that
* function depends on the signaler that dispatches
* events of type <code>p_type</code>
* @returns {WKcSignaler} <code>this</code>
*/
addObserver:
function(p_type, p_observer)
{ var l_observers = this.v_observers[p_type];
if(!l_observers)
{ l_observers = this.v_observers[p_type] = {}; }
l_observers[p_observer] = p_observer;
return this;
},
/**
* Simultaniously adds observers for several events.
*
* @method
* @name $wk$.observer.WKcSignaler#addObservers
*
* @param {Object} p_observers
* A hash map. Each key denotes an event type.
* The values must contain the observer
* functions to be called.
* @returns {WKcSignaler} <code>this</code>
*/
addObservers:
function(p_observers)
{ var l_type = null;
for (l_type in p_observers)
{ if (p_observers.hasOwnProperty(l_type))
{ this.addEventobserver(l_type, p_observers[l_type]); }
}
return this;
},
/**
* Removes an observer for events of type <code>p_type</code>.
*
* @method
* @name $wk$.observer.WKcSignaler#removeObserver
*
* @param {String|int} p_type
* The type of the event signaled. Usually
* a property value of the object
* <code>$wk$.$E$</code>. The pseudo type
* <code>"*"</code> denotes that all events
* are signaled to the observer.
* @param {Object} p_observer
* A callback function. The parameter list of that
* function depends on the signaler that dispatches
* events of type <code>p_type</code>
* @returns {WKcSignaler} <code>this</code>
*/
removeObserver:
function(p_type, p_observer)
{ var l_observers = this.v_observers[p_type];
if(l_observers)
{ delete l_observers[p_observer]; }
return this;
},
/**
* Simultaniously removes observers for several events.
*
* @method
* @name $wk$.observer.WKcSignaler#removeObservers
*
* @param {Object} p_observers
* A hash map. Each key denotes an event type.
* The values must contain the observer
* functions to be called.
* @returns {WKcSignaler} <code>this</code>
*/
removeObservers:
function(p_observers)
{ var l_type = null;
for (l_type in p_observers)
{ if (p_observers.hasOwnProperty(l_type))
{ this.removeObserver(l_type, p_observers[l_type]); }
}
return this;
},
/**
* Signals to all current observers that an event has occured.
*
* Signals an event of type <code>p_event</code> or
* <code>p_event.type</code> to all observers that are currently
* listening on events of this type. As signaler object that dispatches
* this event acts either <code>p_event.signaler</code> (if that property
* exists) or <code>this</code>.
*
* @method
* @name $wk$.observer.WKcSignaler#signal
*
* @param {String|int|Object} p_event
* The event to be signaled.
* Usually a property value of the object <code>$wk$.$E$</code>,
* which denotes an event type. If <code>p_event</code> is an
* object, <code>p_event.type</code> is used as the type of
* the event to be signaled.
* @param {Array} arguments
* Arbitrary further arguments that are passed
* to the observer functions (together with
* <code>p_event</code>).
* @returns {WKcSignaler} <code>this</code>
*/
signal:
function(p_event)
{ if (!p_event)
{ throw "signal: p_event must not be empty."; }
var p_type = (p_event instanceof Object) ? p_event.type : p_event,
p_signaler = (p_event instanceof Object && p_event.signaler)
? p_event.signaler
: this,
l_args = Array.prototype.slice.call(arguments, 0);
function f_signal(p_observers)
{ var l_type = null,
l_observer;
if (p_observers)
{ for (l_type in p_observers)
{ if (p_observers.hasOwnProperty(l_type))
{ l_observer = p_observers[l_type];
if (l_observer instanceof Function)
{ l_observer.apply(p_signaler, l_args); }
else
{ throw new Error("Observers must be functions,"); }
}
}
}
}
f_signal(p_signaler.v_observers[p_type]);
f_signal(p_signaler.v_observers["*"]);
return this;
},
},
});
$.moduleAdd({name: "$wk$.observer.WKcSignaler",
module: { WKcSignaler: WKcSignaler }
});
});
////////////////////////////////////////////////////////////////////////////////
// End of Class "$wk$.observer.WKcSignaler"
////////////////////////////////////////////////////////////////////////////////