, event = require('Y/modules/y.event')
, Event = event.Event
, Emitter = event.Emitter
+
+, MATCH_CACHE = {}
,
/**
- init : function init( type, target, trigger, data ){
- data = data || {};
- for (var k in data) this[k] = data[k];
- this.data = this._o = data;
-
- this.type = type;
- this.target = target || trigger;
- this.trigger = trigger || target;
- },
-
- has : function has(){
-
- },
-
- hasNoun : function hasNoun(noun){
-
+ init : function init(type, triggerType, target, trigger, data){
+ Event.init.call(this, type, target, trigger, data);
+ this.triggerType = triggerType;
},
- hasVerb : function hasVerb(verb){
-
- },
+ // has : function has(){},
+ // hasNoun : function hasNoun(noun){},
+ // hasVerb : function hasVerb(verb){},
- toString: function(){ return "PolyEvent("+this.type+")"; }
+ toString: function(){ return "PolyEvent("+this.type+", triggerType="+this.triggerType+")"; }
})
/**
, methods = {
emit : function emit(evtname, trigger, data){
- var q = this.queues[evtname]
- , L = q ? q.length : 0
- ;
- if ( !L )
- return this;
-
- q = q._o.slice(0);
var A = arguments
, target = this.target
- , evt = new PolyEvent(evtname, target, trigger, data)
- , method = (A.length > 3 ? 'apply' : 'call')
- , args = (A.length > 3 ? [evt].concat(Y(A,3)) : evt)
+ , evt = new PolyEvent(evtname, evtname, target, trigger, data)
+ , types = ( evtname.indexOf('.') === -1 ? [ evtname ] : this.getMatchingEvents(evtname) )
+ , stopped = false
;
- for (var i=0, fn=q[i]; i<L; fn=q[++i])
- fn[method](target, args);
- if (this.parent && !evt._stopped)
+ for (var i=0, tlen=types.length, t=types[i]; i<tlen; t=types[++i]) {
+ var q = this.queues[t]
+ , L = q ? q.length : 0
+ ;
+ if ( L ) {
+ q = q._o.slice(0);
+ evt.type = t;
+ var method = (A.length > 3 ? 'apply' : 'call')
+ , args = (A.length > 3 ? [evt].concat(Y(A,3)) : evt)
+ ;
+ for (var j=0, fn=q[j]; j<L; fn=q[++j]){
+ fn[method](target, args);
+ stopped = stopped || evt._stopped;
+ }
+ }
+ }
+
+ if (this.parent && !stopped )
this.parent.emit.apply(this.parent, A);
return evt;
},
/**
- * @param {String} evt Event string to normalize and expand.
- * @return {PolyEvent...}
+ * @param {String} event Event string to normalize and expand.
+ * @return {String...} Array of all events which match the given event.
*/
- getMatchingEvents : function getMatchingEvents(evt){
+ getMatchingEvents : function getMatchingEvents(event){
+ if ( !MATCH_CACHE[event] ) {
+ // Segregate event groups in a manner worthy of strict scrutiny
+ var seg = event.split('.').reduce(
+ function(seg, token){
+ if (token.indexOf('-') !== -1)
+ seg.special.push(token);
+ else
+ seg.plain.push(token);
+ return seg;
+ }, { plain:[], special:[] });
+
+ // Calculate the correct powerset for each event-group
+ var evtset;
+ if ( !seg.special.length ){
+ evtset = powerset( seg.plain ).map(sorter).map(joiner);
+ } else {
+ evtset = propertyset( seg.special ).reduce(
+ function(acc, t){
+ return acc.concat(
+ powerset( seg.plain.concat([ t ]) ).map(sorter).map(joiner) );
+ }, new Y.YArray());
+ }
+
+ // Remove invalid permutations and duplicates
+ MATCH_CACHE[event] = evtset.unique().reverse();
+
+ // Always notify 'all'
+ MATCH_CACHE[event].push('all');
+ }
+ // console.log("getMatchingEvents("+event+") --> [ "+MATCH_CACHE[event].join(",\n ")+" ]");
+ return MATCH_CACHE[event];
+ },
+
+ // Sure would be nice if I had a macro expander
+
+ listeners : function listeners(evt) {
+ return Emitter.fn.listeners.call(this, evt.split('.').sort().join('.'));
+ },
+
+ willTrigger : function willTrigger(evt) {
+ return Emitter.fn.willTrigger.call(this, evt.split('.').sort().join('.'));
+ },
+
+ hasListener : function hasListener(evt) {
+ return Emitter.fn.hasListener.call(this, evt.split('.').sort().join('.'));
+ },
+
+ addListener : function addListener(evt, fn) {
+ return Emitter.fn.addListener.call(this, evt.split('.').sort().join('.'), fn);
+ },
+
+ removeListener : function removeListener(evt, fn) {
+ return Emitter.fn.removeListener.call(this, evt.split('.').sort().join('.'), fn);
+ },
+
+ removeAllListeners : function removeAllListeners(evt) {
+ return Emitter.fn.removeAllListeners.call(this, evt.split('.').sort().join('.'));
+ },
+
+ once : function once(evt, fn) {
+ return Emitter.fn.once.call(this, evt.split('.').sort().join('.'), fn);
},
/**
for (var k in methods)
delegate[k] = methods[k].bind(this);
return delegate;
- }
+ },
+
+ repeat : Y(repeat).methodize()
}
,
}
}, methods) )
;
+
+methods.on = methods.addListener;
PolyEmitter.methods = methods;
// Global Event Hub
// Helper Functions
-var _match_cache = {};
-
-/**
- * Returns an array of all events which match the given event.
- * @param event
- */
-function getMatchingEvents(event, base_event) {
- if ( !_match_cache[event] ) {
-
- // Segregate event groups in a manner worthy of strict scrutiny
- var seg = event.split('.').reduce(
- function(seg, token){
- if (!base_event)
- base_event = token;
- if (token.indexOf('-') !== -1)
- seg.special.push(token);
- else
- seg.plain.push(token);
- return seg;
- }, { plain:[], special:[] });
-
- // Calculate the correct powerset for each event-group
- var evtset;
- if ( !seg.special.length )
- evtset = powerset( seg.plain ).map(sorter).map(joiner);
- else {
- evtset = propertyset( seg.special ).reduce(
- function(acc, t) {
- return acc.concat(
- powerset( seg.plain.concat([ t ]) ).map(sorter).map(joiner) );
- }, new Y.YArray());
- }
- // Remove invalid permutations and duplicates
- _match_cache[event] = evtset
- .filter(function(v) {
- return v.indexOf(base_event) === 0;
- })
- .unique()
- .reverse();
-
- // Always notify 'all'
- _match_cache[event].push('all');
- }
-
- // console.log("getMatchingEvents( event="+event+", base_event="+base_event+" ) --> [ "+_match_cache[event].join(",\n ")+" ]");
- return _match_cache[event];
-}
-
/**
* Calculates the set of all unique subsets of S (without regard for order) of size k (ie, combination (S k).
* @param {Array} S A collection.
}
function shove(A, v){ A.push(v); return A; }
-function sorter(A){ A.sort(cmp); return A; }
+// function sorter(A){ A.sort(cmp); return A; }
+function sorter(A){ A.sort(); return A; }
function joiner(A){ return A.join('.'); }
function unique(A){
}
-Y.extend( exports, { comb:comb, powerset:powerset, propertyset:propertyset, unique:unique, getMatchingEvents:getMatchingEvents });
+function repeat(emitter){
+ return function(evt){
+ if (!evt) return;
+ var A = arguments;
+ if (A.length > 1) {
+ emitter.emit.apply(emitter, [evt.triggerType, evt.trigger, evt.data].concat(Y(A,1)));
+ } else {
+ emitter.emit(emitter, evt.triggerType, evt.trigger, evt.data);
+ }
+ };
+}
+
+function setupRepeater(fromEmitter, toEmitter, evt){
+ evt = evt || 'all';
+ fromEmitter.on( evt, repeat(toEmitter) );
+ return fromEmitter;
+}
+
+Y.extend( exports, { 'repeat':repeat, 'setupRepeater':setupRepeater });
Y.extend( Y['event'], exports );
__bind__ : [ 'onItemUpdated', 'onDrop' ],
_layerClasses : 'item-container hud',
- inherit : 'name title showTitle max cols'.split(' '),
+ inherit : 'name title showTitle isDraggable max cols'.split(' '),
name : null,
title : null,
showTitle : false,
- defaultContainer : false,
+ isDraggable : true,
max : 1,
cols : 3,
init : function initContainerUI(unit, container, options){
var keys = (options||{}).inherit || this.inherit;
for (var i=0, L=keys.length, k=keys[i]; i<L; k=keys[++i])
- if (container[k]) this[k] = container[k];
+ if (k in container) this[k] = container[k];
if (options) Y.core.extend(this, options);
this.slots = new Y(0, this.max).map(this._makeSlot, this);
this.layer.append('<div class="clearer"/>');
- if (this.defaultContainer) {
- unit.on('item.acquire', this.onItemUpdated);
- unit.on('item.lose', this.onItemUpdated);
- unit.on('item.move', this.onItemUpdated);
- }
+ container.on('item.acquire', this.onItemUpdated);
+ container.on('item.lose', this.onItemUpdated);
+ container.on('item.move', this.onItemUpdated);
},
_makeSlot : function _makeSlot(idx){
var item = ui.draggable.data('item')
, toIdx = $(evt.target).data('idx')
;
- // console.log(this+'.onDrop(item='+item+', toIdx='+toIdx+')', evt);
- this.unit.moveItem(item, toIdx);
+ console.log('onDrop(item='+item+', bag='+this+', toIdx='+toIdx+')', evt);
+ this.unit.inventory.moveItem(item, this.container, toIdx);
// Clear flag preventing the drag from activing the item
setTimeout(function(){ item.dragging = false; }, 250);
artWidth : 50,
artHeight : 50,
+ isDraggable : true,
idx : -1,
dragging : false,
init : function initContainerUISlot(parent, idx){
Y.bindAll(this, 'onActivate', 'onDragStart');
Layer.init.call(this);
+
this.parent = parent;
+ this.isDraggable = parent.isDraggable;
this.container = parent.container;
+
this.idx = idx;
this.layer.addClass('slot'+idx);
this.inner =
this.inner.layer
.addClass('item')
.data('item', item)
- .draggable({
- start : this.onDragStart,
- revert : 'invalid',
- zIndex : 10
- })
.attr('title', '<b>'+item.name+'</b>'+(item.desc ? '<br/>'+item.desc : ''))
.tipsy({ 'html':true, 'gravity':$.fn.tipsy.autoNS })
;
+ if (this.isDraggable)
+ this.inner.layer
+ .draggable({
+ start : this.onDragStart,
+ revert : 'invalid',
+ zIndex : 10
+ });
if (icon)
img.attr('src', icon);