Backpack works again, woo.
authordsc <david.schoonover@gmail.com>
Sat, 12 Feb 2011 11:42:59 +0000 (03:42 -0800)
committerdsc <david.schoonover@gmail.com>
Sat, 12 Feb 2011 11:42:59 +0000 (03:42 -0800)
src/Y/modules/y.polyevent.cjs
src/evt.cjs
src/tanks/inventory/bag.cjs
src/tanks/inventory/bagbag.cjs
src/tanks/inventory/container.cjs
src/tanks/inventory/inventory.cjs
src/tanks/ui/inventory/containerui.cjs
www/css/lttl.css

index 14cd527..56638e8 100644 (file)
@@ -2,6 +2,8 @@ var Y = require('Y').Y
 ,   event = require('Y/modules/y.event')
 ,   Event = event.Event
 ,   Emitter = event.Emitter
+
+,   MATCH_CACHE = {}
 ,
 
 /**
@@ -21,29 +23,16 @@ Event.subclass('PolyEvent', {
     
     
     
-    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+")"; }
 })
 
 /**
@@ -52,34 +41,103 @@ Event.subclass('PolyEvent', {
 , 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);
     },
     
     /**
@@ -93,7 +151,9 @@ Event.subclass('PolyEvent', {
         for (var k in methods)
             delegate[k] = methods[k].bind(this);
         return delegate;
-    }
+    },
+    
+    repeat : Y(repeat).methodize()
 }
 ,
 
@@ -106,6 +166,8 @@ Emitter.subclass('PolyEmitter',
         }
     }, methods) )
 ;
+
+methods.on = methods.addListener;
 PolyEmitter.methods = methods;
 
 // Global Event Hub
@@ -115,54 +177,6 @@ PolyEmitter.global.decorate(exports);
 
 // 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.
@@ -230,7 +244,8 @@ function cmp( a, b ) {
 }
 
 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){
@@ -240,5 +255,23 @@ 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 );
index 9636f40..cce95ee 100644 (file)
@@ -25,7 +25,9 @@ Note: Metaprogramming events cannot depend on Class.
 
 var Y       = require('Y').Y
 ,   core    = require('Y/core')
-,   Emitter = require('Y/modules/y.event').Emitter
+,   Emitter
+,   _Emitter = require('Y/modules/y.event').Emitter
+,   PolyEmitter = Emitter = require('Y/modules/y.polyevent').PolyEmitter
 ,   unwrap  = require('Y/types/function').unwrap
 
 // ,   isFunction      = Y.isFunction
index c65bd52..aa0dac1 100644 (file)
@@ -15,6 +15,7 @@ Item.subclass('Bag', {
     
     /// Setup ///
     hasUI : true,
+    isDraggable : true,
     reqs : null,
     max  : 1,
     cols : 4,
index 3c59c7e..feb4af1 100644 (file)
@@ -12,6 +12,7 @@ Bag.subclass('BagBag', {
     
     /// Setup ///
     hasUI : true,
+    isDraggable : false,
     max  : 1,
     cols : 3,
     reqs : 'bag', // TODO: parse, enforce reqs
index f727d9a..391c833 100644 (file)
@@ -358,7 +358,7 @@ Y.core.extend(ContainerMeta.prototype, {
     },
     
     clone : function clone(){
-        return new ContainerMeta(this.bag, this.idx, this.links); // Don't care about links
+        return new ContainerMeta(this.idx, this.bag, this.links); // Don't care about links
     },
     
     toString : function(){
index 08146dd..ce6f4de 100644 (file)
@@ -153,7 +153,6 @@ evt.subclass('Inventory', {
         
         delete this.items[item.__id__];
         return item.inv.bag.removeItem(item, options);
-        // TODO: Fire event?
     },
     
     /**
index e632b5e..dd59b95 100644 (file)
@@ -13,12 +13,12 @@ HtmlLayer.subclass('ContainerUI', {
     __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,
@@ -29,7 +29,7 @@ HtmlLayer.subclass('ContainerUI', {
     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);
         
@@ -45,11 +45,9 @@ HtmlLayer.subclass('ContainerUI', {
         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){
@@ -91,8 +89,8 @@ HtmlLayer.subclass('ContainerUI', {
         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);
@@ -115,6 +113,7 @@ Layer.subclass('ContainerUISlot', {
     
     artWidth   : 50,
     artHeight  : 50,
+    isDraggable : true,
     
     idx      : -1,
     dragging : false,
@@ -125,8 +124,11 @@ Layer.subclass('ContainerUISlot', {
     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 =
@@ -164,14 +166,16 @@ Layer.subclass('ContainerUISlot', {
         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);
index 55e1cb7..f3ddd51 100644 (file)
@@ -55,7 +55,7 @@ td { text-align:center; vertical-align:middle; }
     .item-container .slot { float:left; position:relative; width:50px; height:50px; margin:0.25em; border:1px solid transparent; }
     .item-container .slot.drophover { border:1px solid #FFF6AE; }
 
-#backpack { position:absolute; bottom:82px; right:1em; /* width:304px; height:254px; */ }
+#backpack { position:absolute; bottom:124px; right:1em; /* width:304px; height:254px; */ }
 #bagbag { bottom:1em; right:1em; }