The great module refactor continues -- seems mostly done.
authordsc <david.schoonover@gmail.com>
Sun, 5 Dec 2010 13:29:28 +0000 (05:29 -0800)
committerdsc <david.schoonover@gmail.com>
Sun, 5 Dec 2010 13:29:28 +0000 (05:29 -0800)
21 files changed:
index.html
src/Y/core.cjs
src/Y/delegate.cjs [new file with mode: 0644]
src/Y/index.cjs
src/Y/modules/y.kv.cjs
src/Y/op.cjs
src/Y/type.cjs
src/Y/types/array.cjs
src/Y/types/collection.cjs
src/Y/types/function.cjs
src/Y/types/string.cjs
src/Y/utils.cjs
src/ezl/layer.cjs
src/tanks/index.js
src/tanks/map/level.cjs
src/tanks/map/pathmap.cjs
src/tanks/thing/tank.cjs
src/tanks/ui/main.cjs
src/tanks/util/config.cjs
tags.html
tanks.php

index 5fff680..fcf29d6 100644 (file)
@@ -62,7 +62,7 @@
 </div></div>
 
 <div id="scripts">
-<!--# include file="build/tags.html" -->
+<!--# include file="tags.html" -->
 </div>
 
 </body>
index ee42dc3..72fa583 100644 (file)
@@ -1,21 +1,13 @@
 // Generic Collection Functions
+
 var undefined
 ,   globals   = (function(){ return this; })()
 ,   _Function = globals.Function
 ,   _Array    = globals.Array
-,   PT = "prototype"
-,   slice = _Array[PT].slice
-,   type = require('Y/type')
-;
-
-// function slice(a){
-//     return _asl.apply(a, _asl.call(arguments, 1));
-// }
+,   slice     = _Array.prototype.slice
 
-function notWrapped(fn){
-    var self = arguments.callee.caller;
-    return fn && fn !== self && fn.__wraps__ !== self;
-}
+,   type      = require('Y/type')
+;
 
 function reduce(o, fn, acc){
     if ( !o )
@@ -23,12 +15,12 @@ function reduce(o, fn, acc){
     
     fn = _Function.toFunction(fn);
     var cxt = arguments[3] || o;
-    if ( notWrapped(o.reduce) )
-        return o.reduce.apply(o, [fn, acc, cxt]);
+    
+    if ( o instanceof _Array )
+        return o.reduce.call(o, fn, acc, cxt);
     
     for ( var name in o )
         acc = fn.call(cxt, acc, o[name], name, o);
-    
     return acc;
 }
 
@@ -38,17 +30,23 @@ function map(o, fn){
     
     fn = _Function.toFunction(fn);
     var acc = {}, cxt = arguments[2] || o;
-    if ( notWrapped(o.map) )
-        return o.map.apply(o, [fn, cxt]);
+    
+    if ( o instanceof _Array )
+        return o.map(fn, cxt);
     
     for ( var name in o )
         acc[name] = fn.call(cxt, o[name], name, o);
-    
     return acc;
 }
 
 function forEach(o, fn){
-    map(o, fn, arguments[2] || o);
+    var cxt = arguments[2] || o;
+    
+    if ( o instanceof _Array )
+        o.forEach(fn, cxt);
+    else
+        map(o, fn, cxt);
+    
     return o;
 }
 
@@ -58,13 +56,13 @@ function filter(o, fn){
     
     fn = _Function.toFunction(fn);
     var acc = {}, cxt = arguments[2] || o;
-    if ( notWrapped(o.filter) )
-        return o.filter.apply(o, [fn, cxt]);
+    
+    if ( o instanceof _Array )
+        return o.filter(fn, cxt);
     
     for ( var name in o )
         if ( fn.call(cxt, o[name], name, o) )
             acc[name] = o[name];
-    
     return acc;
 }
 
@@ -77,13 +75,6 @@ function set(o, key, value, def){
     return o;
 }
 
-function dset(o, key, value, def){
-    if ( o && notWrapped(o.set) )
-        return o.set.apply(o, slice.call(arguments,1));
-    else
-        return set(o, key, value, def);
-}
-
 function attr(o, key, value, def){
     if ( !o || key === undefined ) return o;
     
@@ -91,30 +82,17 @@ function attr(o, key, value, def){
         return extend(o, key);
     
     if ( value !== undefined || def !== undefined ){
-        return dset(o, key, value, def);
+        return set(o, key, value, def);
     } else
         return o[key];
 }
 
-function dattr(o, key, value, def){
-    if ( o && notWrapped(o.attr) )
-        return o.attr.apply(o, slice.call(arguments,1));
-    else
-        return attr(o, key, value, def);
-}
-
 function extend( A, B ){
     return slice.call(arguments,1).reduce(extendall, A);
 }
 function extendall(A, donor){ return reduce(donor, attrvk, A); }
 function attrvk(o, v, k){ return attr(o, k, v, o[k]); }
 
-function dextend( A, B ){
-    return slice.call(arguments,1).reduce(dextendall, A);
-}
-function dextendall(A, donor){ return reduce(donor, dattrvk, A); }
-function dattrvk(o, v, k){ return dattr(o, k, v, o[k]); }
-
 
 exports['reduce']  = reduce;
 exports['map']     = map;
@@ -125,7 +103,4 @@ exports['set']     = set;
 exports['attr']    = attr;
 exports['extend']  = extend;
 
-exports['dset']    = dset;
-exports['dattr']   = dattr;
-exports['dextend'] = dextend;
-exports['slice']   = slice;
\ No newline at end of file
+exports['slice']   = slice;
diff --git a/src/Y/delegate.cjs b/src/Y/delegate.cjs
new file mode 100644 (file)
index 0000000..016be83
--- /dev/null
@@ -0,0 +1,110 @@
+// Delegating Collection Functions
+var undefined
+,   _Function = Function
+,   type = require('Y/type')
+,   core = require('Y/core')
+,   slice = core.slice
+;
+
+function notWrapped(fn){
+    var self = arguments.callee.caller;
+    return fn && fn !== self && fn.__wraps__ !== self;
+}
+
+function reduce(o, fn, acc){
+    if ( !o )
+        return acc;
+    
+    fn = _Function.toFunction(fn);
+    var cxt = arguments[3] || o;
+    
+    if ( notWrapped(o.reduce) )
+        return o.reduce.call(o, fn, acc, cxt);
+    
+    for ( var name in o )
+        acc = fn.call(cxt, acc, o[name], name, o);
+    
+    return acc;
+}
+
+function map(o, fn){
+    if ( !o )
+        return o;
+    
+    fn = _Function.toFunction(fn);
+    var acc = {}, cxt = arguments[2] || o;
+    
+    if ( notWrapped(o.map) )
+        return o.map.call(o, fn, cxt);
+    
+    for ( var name in o )
+        acc[name] = fn.call(cxt, o[name], name, o);
+    
+    return acc;
+}
+
+function forEach(o, fn){
+    var cxt = arguments[2] || o;
+    
+    if ( notWrapped(o.forEach) )
+        o.forEach.call(o, fn, cxt);
+    else
+        map(o, fn, cxt);
+    
+    return o;
+}
+
+function filter(o, fn){
+    if ( !o )
+        return o;
+    
+    fn = _Function.toFunction(fn);
+    var acc = {}, cxt = arguments[2] || o;
+    
+    if ( notWrapped(o.filter) )
+        return o.filter.call(o, fn, cxt);
+    
+    for ( var name in o )
+        if ( fn.call(cxt, o[name], name, o) )
+            acc[name] = o[name];
+    
+    return acc;
+}
+
+function set(o, key, value, def){
+    if ( o && notWrapped(o.set) )
+        return o.set.apply(o, slice.call(arguments,1));
+    else
+        return core.set(o, key, value, def);
+}
+
+function attr(o, key, value, def){
+    if ( !o || key === undefined ) return o;
+    
+    if ( notWrapped(o.attr) )
+        return o.attr.apply(o, slice.call(arguments,1));
+    
+    if ( type.isPlainObject(key) )
+        return extend(o, key);
+    
+    if ( value !== undefined || def !== undefined ){
+        return set(o, key, value, def);
+    } else
+        return o[key];
+}
+
+function extend( A, B ){
+    return slice.call(arguments,1).reduce(extendall, A);
+}
+function extendall(A, donor){ return reduce(donor, attrvk, A); }
+function attrvk(o, v, k){ return attr(o, k, v, o[k]); }
+
+
+exports['reduce']  = reduce;
+exports['map']     = map;
+exports['forEach'] = forEach;
+exports['filter']  = filter;
+
+exports['set']     = set;
+exports['attr']    = attr;
+exports['extend']  = extend;
index 41ecf34..387f5d7 100644 (file)
@@ -16,15 +16,11 @@ exports['Y'] = Y;
 // same name as its namespace
 core.extend(type.type, type);
 
-// Attach core & type to Y
-core.extend(Y, core, type);
-delete Y.slice; // grr
-
-// Make top-level setters refer to the delegating versions
-Y['core']   = core;
-Y['set']    = core.dset;
-Y['attr']   = core.dattr;
-Y['extend'] = core.dextend;
+// Attach delegate-core & type to Y
+var del = require('Y/delegate');
+core.extend(Y, type, del);
+Y['core']     = core;
+Y['delegate'] = del;
 
 
 /// Patch modules that weren't available earlier ///
@@ -35,6 +31,7 @@ var yfn = require('Y/types/function')
 
 YFunction(Y);
 core.forEach(core, YFunction);
+core.forEach(del,  YFunction);
 YFunction(Y.type);
 Y['is'] = YFunction(Y.is).curry();
 
@@ -42,12 +39,10 @@ addNames('curry methodize genericize compose chain memoize', yfn);
 
 // Curry all operators
 var op = require('Y/op');
-core.forEach(op, YFunction);
-// Y['op'] = op['curried'] = op.extend({}, core.map(op, yfn.curry));
 Y['op'] =
 op['curried'] = 
     core.reduce(op, function(Yop, fn, k){
-        Yop[k] = fn.curry();
+        Yop[k] = YFunction(fn).curry();
         return Yop;
     }, {});
 
@@ -61,6 +56,8 @@ addNames('YObject',       require('Y/types/object'));
 addNames('YString',       require('Y/types/string'));
 addNames('YNumber range', require('Y/types/number'));
 
+var utils = require('Y/utils');
+Y['bindAll'] = utils.bindAll;
 
 function addName(name){ Y[name] = this[name]; }
 function addNames(names, ns){ names.split(' ').forEach(addName, ns); }
index a05be23..15a456a 100644 (file)
@@ -5,22 +5,27 @@ var Y   = require('Y').Y
 
 Y.YCollection.prototype.toKV =
     function toKV(del){
-        return this.reduce(function(acc, v, k){
-            return acc.push( enc(k) + '=' + enc(v) );
-        }, Y([]))
-        .join(del !== undefined ? del : "&");
+        return this
+            .reduce(encoder, Y([]))
+            .join(del !== undefined ? del : "&");
     };
 
 Y.YString.prototype.toObject =
 Y.YString.prototype.fromKV =
     function fromKV(del){
-        return Y(this.split(del || '&'))
-            .reduce(function(acc, pair){
-                var idx = pair.indexOf('=')
-                ,   k = dec(pair.slice(0,idx))
-                ,   v = dec(pair.slice(idx+1)) ;
-                if (k) acc[k] = v;
-                return acc;
-            }, {});
+        return this
+            .split(del || '&')
+            .reduce(decoder, {});
     };
 
+
+function encoder(acc, v, k){
+    return acc.push( enc(k) + '=' + enc(v) );
+}
+function decoder(acc, pair){
+    var idx = pair.indexOf('=')
+    ,   k = dec(pair.slice(0,idx))
+    ,   v = dec(pair.slice(idx+1)) ;
+    if (k) acc[k] = v;
+    return acc;
+}
\ No newline at end of file
index e52348b..3b2971c 100644 (file)
@@ -61,19 +61,12 @@ var core = require('Y/core')
         var args = slice.call(arguments,1);
         return function(obj){
             if (obj && obj[name])
-                return obj[name].apply( obj, args.concat(slice.call(arguments)) );
+                return obj[name].apply( obj, args.concat(slice.call(arguments,0)) );
             else
                 return obj;
         };
-    },
-    extend : function extend(A,B){
-        return slice.call(arguments,1).reduce(extender, A);
     }
     
 };
 
-function extender(target, donor){
-    return core.reduce(donor, op.vkset, target);
-}
-
-op.extend(exports, op);
+core.extend(exports, op);
index 9996392..966aab8 100644 (file)
@@ -93,7 +93,7 @@ function type( o ) {
 
 function is( A, B ){
     if ( isArray(B) )
-        return B.map( is.bind(this,A) ).any();
+        return B.map( is.bind(this,A) ).any(); // XXX: implicitly depends on YFunction, but we'll just quietly not use it
     else {
         var AT = type(A), BT = type(B);
         return (A instanceof BT || B instanceof AT || AT === BT);
index c1f568b..abbab0c 100644 (file)
@@ -8,7 +8,7 @@ YCollection.subclass('YArray', function(YArray){
     
     mixin(YArray, { donor:Array, chain:true,
         names:'push unshift sort splice reverse'.split(' ') });
-    mixin(YArray, { donor:Array, wrap:YArray,
+    mixin(YArray, { donor:Array, wrap:YArray.instantiate.bind(YArray),
         names:'map forEach filter slice'.split(' ') });
     mixin(YArray, { donor:Array,
         names:'reduce some every indexOf lastIndexOf shift pop join'.split(' ') });
index 56eb0b9..529a329 100644 (file)
@@ -1,18 +1,19 @@
-/** YCollection is the core of Y. */
+/**
+ * A generic collection (which also provides the majority of core functionality for YObject).
+ * Specializations are provided by subclasses. All subclasses must implement reduce().
+ */
 
-var YBase      = require('Y/class').YBase
-,   isFunction = require('Y/type').isFunction
-,   core       = require('Y/core')
-,   op         = require('Y/op')
-,   slice      = core.slice
-,   extend     = core.extend
-,   attr       = core.attr
-,   bool       = op.bool
+var YBase  = require('Y/class').YBase
+// ,   type   = require('Y/type')
+,   core   = require('Y/core')
+,   del    = require('Y/delegate')
+,   op     = require('Y/op')
+,   slice  = core.slice
 ;
 
 
 function extendY(){
-    extend.apply(this, [this._o].concat(slice.call(arguments)));
+    del.extend.apply(this, [this._o].concat(slice.call(arguments)));
     return this;
 }
 
@@ -23,7 +24,7 @@ YBase.subclass('YCollection', {
     },
     
     'attr'   : function attr(k, v, def){
-        var r = attr(this._o, k, v, def);
+        var r = del.attr(this._o, k, v, def);
         if (r === this._o)
             return this;
         else
@@ -80,6 +81,7 @@ YBase.subclass('YCollection', {
         return new this.constructor().extend(this);
     },
     
+    // Dependence on YArray closes the loop
     // 'remove' : function remove(v){
     //     var o = this._o
     //     ,   toRemove = new Y(arguments);
@@ -111,14 +113,14 @@ YBase.subclass('YCollection', {
     },
     
     'every' : function every( fn ){
-        var self = this, fn = fn || bool;
+        var self = this, fn = fn || op.bool;
         return this.reduce(function(acc, v, k, o){
             return acc && fn.call(self, v, k, o);
         }, true);
     },
     
     'any' : function any( fn ){
-        var self = this, fn = fn || bool;
+        var self = this, fn = fn || op.bool;
         return this.reduce(function(acc, v, k, o){
             return acc || fn.call(self, v, k, o);
         }, false);
@@ -134,13 +136,14 @@ YBase.subclass('YCollection', {
     
     'pluck' : function pluck(key){
         return this.map(function(v){
-            return v && (isFunction(v.attr) ? v.attr(key) : v[key]);
+            return del.attr(v, key);
+            // return v && (type.isFunction(v.attr) ? v.attr(key) : v[key]);
         });
     },
     
     'invoke' : function invoke(name){
         var args = slice.call(arguments,1);
-        return core.map(this, function(o){
+        return del.map(this, function(o){
             return o && o[name].apply(o, args);
         });
     },
index 7d8f570..05d704d 100644 (file)
@@ -38,7 +38,10 @@ core.extend( YFP, {
 });
 
 
-
+function wraps(wrapper, fn) {
+    wrapper[WRAPS] = fn;
+    return YFunction(wrapper);
+}
 
 function unwrap(fn){
     return ( fn && isFunction(fn) ) ? unwrap(fn[WRAPS]) || fn : fn;
@@ -63,9 +66,8 @@ function curry(fn){
             return curry.apply(this, [fn].concat(_args));
     }
     
-    curried[WRAPS] = fn;
     curried.__curried__ = args;
-    return curried;
+    return wraps(curried, fn);
 }
 
 
@@ -80,8 +82,7 @@ function methodize(fn) {
         function methodized(){
             return fn.apply(this, [this].concat( slice.call(arguments) ));
         };
-    m[WRAPS] = fn;
-    return m;
+    return wraps(m, fn);
 }
 
 function genericize( fn ) {
@@ -96,8 +97,7 @@ function genericize( fn ) {
             var args = slice.call(arguments);
             return fn.apply(args.shift(), args);
         };
-    g[WRAPS] = fn;
-    return g;
+    return wraps(g, fn);
 };
 
 
@@ -131,7 +131,8 @@ function chain(f,g){
 // function lazy(fn){
 //     var args = slice.call(arguments, 1)
 //     ,   L = unwrap(fn).length
-//     ,   lazied = function(){
+//     ,   lazied =
+//         function lazied(){
 //             var _args = slice.call(arguments)
 //             ,   f = _args[0];
 //             
@@ -146,19 +147,16 @@ function chain(f,g){
 //                 return fn.apply(this, args);
 //             else
 //                 return arguments.callee;
-//         }
-//     ;
-//     lazied[WRAPS] = fn;
+//         };
+//     
 //     lazied.__args = args;
-//     return lazied();
+//     return wraps(lazied, fn)();
 // }
 
 
 var _bind = _Function.prototype.bind;
 function bind(fn, context, args){
-    var bound = _bind.apply(fn, slice.call(arguments,1));
-    bound[WRAPS] = fn;
-    return YFunction(bound);
+    return wraps(_bind.apply(fn, slice.call(arguments,1)), fn);
 }
 
 
@@ -169,8 +167,7 @@ function partial(fn){
         function partially(){
             return fn.apply( this, args.concat(slice.call(arguments)) );
         };
-    partially[WRAPS] = fn;
-    return YFunction(partially);
+    return wraps(partially, fn);
 }
 
 
@@ -197,15 +194,14 @@ function memoize(fn){
             return cache[key];
         };
     
-    m[WRAPS] = fn;
     m.purge = function purge(){
         var cache = this.cache;
         this.cache = {};
         return cache;
     };
-    
     m.purge();
-    return m;
+    
+    return wraps(m, fn);
 }
 
 // Memorized to reduce eval costs
@@ -214,12 +210,13 @@ _ofArityWrapper =
 YFunction._ofArityWrapper =
     memoize(function(n, limit){
         var i = n, args = [];
-        while (i-- > 0) args.unshift('$'+i);
-        // range(n).map( op.add('$') ).join(',')
-        return eval('(function '+(limit ? 'limited' : 'artized')+'(fn){ '+
-            'return function('+args.join(',')+'){ '+
-                'return fn.apply(this,' + (limit ? 'slice.call(arguments, 0,'+n+')' : 'arguments')+ 
-            '); }; })');
+        while (i-- > 0) args.unshift('$'+i); // Can't use Y.range due to deps
+        return eval(
+            '(function '+(limit ? 'limited' : 'artized')+'(fn){ '+
+                'return wraps(function('+args.join(',')+'){ '+
+                    'return fn.apply(this,' + (limit ? 'slice.call(arguments, 0,'+n+')' : 'arguments') + '); '+
+                '}, fn); '+
+            '})');
  &nb