Refactors ezl to use CommonJS.
authordsc <david.schoonover@gmail.com>
Mon, 29 Nov 2010 04:12:48 +0000 (20:12 -0800)
committerdsc <david.schoonover@gmail.com>
Mon, 29 Nov 2010 04:12:48 +0000 (20:12 -0800)
60 files changed:
bin/cjs.py
doc/notes.md
index.php
lib/cjs/deps.js [new file with mode: 0644]
lib/cjs/dummy.js [new file with mode: 0644]
lib/cjs/module.js
lib/jquery.js [new symlink]
src/Y/class.cjs
src/Y/core.cjs
src/Y/index.cjs
src/Y/modules/old-y.event.js [moved from src/Y/modules/event.js with 100% similarity]
src/Y/modules/y.cookies.cjs [moved from src/Y/modules/y.cookies.js with 86% similarity]
src/Y/modules/y.event.cjs [moved from src/Y/modules/y.event.js with 94% similarity]
src/Y/modules/y.json.cjs [moved from src/Y/modules/y.json.js with 62% similarity]
src/Y/modules/y.kv.cjs [moved from src/Y/modules/y.kv.js with 88% similarity]
src/Y/op.cjs
src/Y/types/array.cjs
src/Y/types/collection.cjs
src/Y/types/function.cjs
src/Y/types/number.cjs
src/Y/types/object.cjs
src/Y/types/string.cjs
src/Y/utils.cjs [new file with mode: 0644]
src/Y/y.cjs
src/evt/evt.class.js
src/ezl/index.cjs [new file with mode: 0644]
src/ezl/layer.cjs [moved from src/ezl/layer.js with 96% similarity]
src/ezl/loc/boundingbox.cjs [new file with mode: 0644]
src/ezl/loc/index.cjs [new file with mode: 0644]
src/ezl/loc/loc.cjs [new file with mode: 0644]
src/ezl/loc/square.cjs [new file with mode: 0644]
src/ezl/loop/cooldown.cjs [moved from src/ezl/loop/cooldown.js with 92% similarity]
src/ezl/loop/eventloop.cjs [moved from src/ezl/loop/eventloop.js with 87% similarity]
src/ezl/loop/fps.cjs [moved from src/ezl/loop/fps.js with 92% similarity]
src/ezl/loop/index.cjs [new file with mode: 0644]
src/ezl/math/index.cjs [new file with mode: 0644]
src/ezl/math/line.cjs [moved from src/ezl/math/line.js with 70% similarity]
src/ezl/math/math.js [deleted file]
src/ezl/math/rect.cjs
src/ezl/math/vec.cjs [moved from src/ezl/math/vec.js with 78% similarity]
src/ezl/shape/circle.cjs [moved from src/ezl/shape/circle.js with 92% similarity]
src/ezl/shape/index.cjs [new file with mode: 0644]
src/ezl/shape/line.cjs [moved from src/ezl/shape/line.js with 98% similarity]
src/ezl/shape/polygon.cjs [moved from src/ezl/shape/polygon.js with 74% similarity]
src/ezl/shape/rect.cjs [moved from src/ezl/shape/rect.js with 74% similarity]
src/ezl/shape/shape.cjs [moved from src/ezl/shape/shape.js with 93% similarity]
src/ezl/util/astar.cjs [new file with mode: 0644]
src/ezl/util/astar.js [deleted file]
src/ezl/util/binaryheap.cjs [moved from src/ezl/util/binaryheap.js with 98% similarity]
src/ezl/util/graph.cjs [moved from src/ezl/util/graph.js with 76% similarity]
src/ezl/util/tree/pointquadtree.cjs [moved from src/ezl/util/tree/pointquadtree.js with 100% similarity]
src/ezl/util/tree/quadtree.cjs [moved from src/ezl/util/tree/quadtree.js with 97% similarity]
src/ezl/util/tree/rbtree.cjs [moved from src/ezl/util/tree/rbtree.js with 98% similarity]
src/tanks/map/level.cjs
src/tanks/map/loc/bbox.cjs [deleted file]
src/tanks/map/loc/index.cjs [deleted file]
src/tanks/map/loc/loc.cjs [deleted file]
src/tanks/map/loc/rect.cjs [deleted file]
src/tanks/ui/grid.cjs
tanks.php

index 250e42d..dbdbc72 100755 (executable)
@@ -7,7 +7,7 @@ __version__   = (0, 0, 1)
 __all__ = ('ResolutionError', 'Module', 'JSResolver',)
 
 
-import sys, re
+import sys, re, json
 from itertools import chain, repeat
 from collections import defaultdict
 from subprocess import Popen, check_output, STDOUT, PIPE
@@ -18,21 +18,30 @@ from path import path
 import pystache
 
 
+AT_REQUIRE_PAT   = re.compile(r'//@require\(\s*([\'"])(.*?)\1\s*\)')
 LINE_COMMENT_PAT = re.compile(r'(.*?)(//.*?)(?:\n|$)')
 PAIR_COMMENT_PAT = re.compile(r'(.*?)(/\*.*?\*/)')
 REQUIRE_PAT      = re.compile(r'\brequire\(\s*([\'"])(.*?)\1\s*\)')
+
 ROOT             = path(__file__).abspath().dirname().dirname()
 LIB              = ROOT/'lib/cjs'
 CWD              = path('.')
 BLANK            = path('')
+
 MODULE_TEMPLATE  = ''
+DUMMY_TEMPLATE   = ''
+DEPS_TEMPLATE    = ''
 
 try:
-    with (LIB/'module.js').open('rU') as f : 
+    with (LIB/'module.js').open('rU') as f:
         MODULE_TEMPLATE = f.read()
+    with (LIB/'dummy.js').open('rU') as f:
+        DUMMY_TEMPLATE = f.read()
+    with (LIB/'deps.js').open('rU') as f:
+        DEPS_TEMPLATE = f.read()
 except Exception as ex:
     print
-    print 'Error reading module template file!'
+    print 'Error reading template file!'
     print '  ROOT={ROOT}, LIB={LIB}, module.js={}'.format(LIB/'module.js', **locals())
     raise
 
@@ -86,55 +95,41 @@ def canonicalise(query, base=None):
     return str(id)
 
 
-class Repo(object):
-    def __init__(self, filepath, url):
-        self.path = filepath
-        self.url  = url
-    
-    def __repr__(self):
-        return 'Repo({}, url={})'.format(self.path, self.url)
-    
-    def __str__(self):
-        return repr(self)
-
-
 
 class Module(Bunch):
     DEFAULTS = {
-        'id'        : '',   # Canonical Module ID
-        'file'      : None, # path
-        'name'      : '',   # Module Name
-        'uri'       : '',   # Module URI (TODO)
-        'text'      : None, # Unmodified module text
-        'contents'  : None, # Compiled module text
-        '_requires' : None,
-        'outpath'   : None,
+        'id'           : '',   # Canonical Module ID
+        'file'         : None, # path
+        'name'         : '',   # Module Name
+        'uri'          : '',   # Module URI (TODO)
+        'text'         : None, # Unmodified module text
+        'contents'     : None, # Compiled module text
+        'outpath'      : None, # Build directory
+        '_requires'    : None,
+        '_at_requires' : None,
     }
     
     
-    def __init__(self, id, file, uri='', out=None, compile=True):
+    def __init__(self, id, file, uri=BLANK, out=None, compile=True):
         self.update(Module.DEFAULTS)
         
         self.id   = id
         self.file = path(file)
-        self.name = self.id.split('/').pop().capitalize()
+        self.name = re.subn(r'\W', '', self.id.split('/').pop().capitalize())[0]
         
         if out:
-            out = (path(out) / self.id) + '.js'
+            out = path(out)
+            outpath = (out / self.id) + '.js'
         else:
-            out = self.file.replace('.cjs', '.js')
-        self.outpath = path(out)
-        self.uri = uri
+            out = BLANK
+            outpath = self.file.replace('.cjs', '.js')
+        self.outpath = path(outpath)
+        self.uri = str(out/uri/self.id)+'.js'
         
-        if compile: self.compile()
+        self.compile()
         # print "new!", repr(self)
     
     def compile(self):
-        # if uri: self.uri = uri.format(**self) # TODO: calc uri
-        
-        if not self.file.endswith('.cjs'):
-            return self
-        
         outdir = self.outpath.dirname()
         if not outdir.exists():
             outdir.makedirs()
@@ -149,7 +144,8 @@ class Module(Bunch):
             with self.file.open('rU') as f:
                 txt = f.read()
             self['text'] = txt
-            self['contents'] = pystache.render(MODULE_TEMPLATE, self)
+            template = MODULE_TEMPLATE if self.file.endswith('.cjs') else DUMMY_TEMPLATE
+            self['contents'] = pystache.render(template,  self)
         return self[attr]
     
     @property
@@ -160,6 +156,10 @@ class Module(Bunch):
     def contents(self):
         return self.read('contents')
     
+    def findDirectives(self, text):
+        for areq in AT_REQUIRE_PAT.finditer(text):
+            yield canonicalise(areq.group(2), self)
+    
     def findRequires(self, text):
         text = LINE_COMMENT_PAT.subn(r'\1 ', text)[0]
         text = PAIR_COMMENT_PAT.subn(r'\1 ', text)[0]
@@ -167,11 +167,23 @@ class Module(Bunch):
         for mreq in REQUIRE_PAT.finditer(text):
             yield canonicalise(mreq.group(2), self)
     
+    def calcRequires(self, attr):
+        if self._requires is None or self._at_requires is None:
+            self._at_requires = list(self.findDirectives(self.text))
+            self._requires    = list(self.findRequires(self.text))
+        return getattr(self, attr)
+    
+    @property
+    def atRequires(self):
+        return self.calcRequires('_at_requires')
+    
+    @property
+    def nonAtRequires(self):
+        return self.calcRequires('_requires')
+    
     @property
     def requires(self):
-        if self._requires is None:
-            self._requires = list(self.findRequires(self.text))
-        return self._requires
+        return self.calcRequires('_at_requires') + self._requires
     
     def __hash__(self):
         return hash(self.id)
@@ -209,22 +221,30 @@ class CommonJS(object):
                 req = cjs.lookup(query, mod)
                 if req not in seen:
                     queue.append(req)
+        if cjs.deps_name:
+            cjs.genDepLoader()
         return cjs
     
     
     repos   = []
     modules = {} # id -> Module
-    _graph  = None # id -> set(dependants)
-    
-    
-    def __init__(self, repos, out='build', clean=True):
-        self.modules = {}
-        self.repos   = set( path(path(p).abspath()+'/') for p in repos)
-        self.out = None if out is '' else out
+    _graph    = None # id -> set(dependants)
+    _at_graph = None # id -> set(dependants)
+    
+    def __init__(self, repos, out='build', deps_name=None, clean=True, **options):
+        self.modules  = {}
+        self.options  = options
+        self.deps_name = deps_name
+        self.repos    = set( path(path(p).abspath()+'/') for p in repos)
+        self.out      = None if out is '' else out
         
         if self.out is not None and clean:
             out = path(self.out)
-            if out.exists(): out.rmtree()
+            for f in out.glob('*'):
+                if f.isdir():
+                    f.rmtree()
+                elif f.isfile():
+                    f.remove()
     
     def register(self, id, file):
         mod = self.modules[id] = Module(id=id, file=file, out=self.out)
@@ -254,32 +274,67 @@ class CommonJS(object):
         for k, mod in self.modules.iteritems():
             yield k, mod
     
-    @property
-    def graph(self):
+    def calcGraph(self, attr):
         if self._graph is None:
-            graph = self._graph = defaultdict(set)
+            graph   = self._graph    = defaultdict(set)
+            atgraph = self._at_graph = defaultdict(set)
             for mod in self.modules.values():
-                for req in mod.requires:
+                for req in mod.nonAtRequires:
                     graph[req].add(mod)
-        return self._graph
+                for req in mod.atRequires:
+                    atgraph[req].add(mod)
+        return getattr(self, attr)
     
     @property
-    def deplist(self):
-        return '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in self.graph.iteritems() for dep in deps )
+    def graph(self):
+        return self.calcGraph('_graph')
     
     @property
-    def dependencies(self):
+    def atGraph(self):
+        return self.calcGraph('_at_graph')
+    
+    def tsort(self, graph):
         p = Popen(['tsort'], stderr=STDOUT, stdin=PIPE, stdout=PIPE)
-        p.stdin.write( self.deplist )
+        deps = '\n'.join( '%s %s' % (id, dep.id) for (id, deps) in graph.iteritems() for dep in deps )
+        p.stdin.write(deps)
         p.stdin.close()
         if p.wait() != 0:
             raise ResolutionError('Cannot resolve dependencies! Requirements must be acyclic!')
-        return p.stdout.read().strip().split('\n')
+        return p.stdout.read()
+    
+    @property
+    def dependencies(self):
+        deps = (self.tsort(self.atGraph)+self.tsort(self.graph)).strip().split('\n')
+        for i, dep in reversed(list(enumerate(deps[:]))):
+            try:
+                idx = deps.index(dep, 0, i-1)
+                if i != idx:
+                    del deps[idx]
+            except ValueError: pass
+        return deps
+    
+    def dumpDependencies(self):
+        column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
+        mods = self.modules.values()
+        for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
+            column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
+            # print '%s\t->\t%r' % (mod, sorted(mod.requires))
+        column.stdin.close()
+        if column.wait() != 0:
+            print >> sys.stderr, 'Some sort of error has occurred!'
+        return column.stdout.read()
     
-    def cat(self):
-        for dep in self.dependencies:
-            print self.modules[dep].contents
+    def genDepLoader(self):
+        with (path(self.out)/self.deps_name).open('w') as deps:
+            deps.write( pystache.render(DEPS_TEMPLATE, uris=json.dumps(self.uris)) )
     
+    @property
+    def uris(self):
+        return [ self.modules[d].uri for d in self.dependencies ]
+    
+    @property
+    def scriptTags(self):
+        return '\n'.join( '<script src="{}" type="text/javascript"></script>'.format(uri) for uri in self.uris )
 
 
 
@@ -292,15 +347,19 @@ def main():
         usage   = 'usage: %prog [options] file[...] [-- [repo_path[...]]]',
         description = 'Compiles CommonJS modules.',
         version = '%prog'+" %i.%i.%i" % __version__)
-    parser.add_option("-p", "--repo-paths", dest='repos', default='',
+    parser.add_option("-p", "--repo-paths", default='',
         help="Comma-seperated paths to search for unqualified modules. "
              "If a path contains :, the portion afterward will be taken as the repo URL. [default: .]")
     parser.add_option("-o", "--out", default='build',
         help="Root directory to write compiled JS files. Specify '' to write to module's dir. [default: build]")
     parser.add_option("-C", "--no-clean", dest='clean', default=True, action="store_false",
         help="Do not clean the out-dir of compiled files. [default: False if -o, True otherwise]")
-    parser.add_option("-d", "--print-deps", default=False, action="store_true", 
+    parser.add_option("--print-deps", default=False, action="store_true", 
         help="Prints module dependencies after compiling. [default: %default]")
+    parser.add_option("-g", "--gen-deps-script", dest='deps_name', default=None,
+        help="Generates a JS script with the given name which doc-writes tags for this set of modules.")
+    parser.add_option("-s", "--script-tags", default=False, action="store_true",
+        help="Emits script-tags for this set of modules in dependency order. [default: %default]")
     
     (options, args) = parser.parse_args()
     
@@ -310,21 +369,24 @@ def main():
     (files, sep, repos) = partition(sys.argv, '--')
     files = filter(lambda f: f in args, files)
     repos = filter(lambda f: f in args, repos)
-    repos.extend( filter(None, options.repos.split(',')) )
+    repos.extend( filter(None, options.repo_paths.split(',')) )
     
     # print 'files:', files, 'repos:', (repos or ['.'])
-    js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+    try:
+        js = CommonJS.discover(files=files, repos=repos or ['.'], **options.__dict__)
+    except ResolutionError as ex:
+        print >> sys.stderr, str(ex)
+        return 1
+    
+    if options.script_tags:
+        print js.scriptTags
     
     if options.print_deps:
-        column = Popen(['column', '-s', '\t', '-t'], stderr=sys.stderr, stdin=PIPE, stdout=PIPE)
-        mods = js.modules.values()
-        for mod in sorted(mods, key=lambda m: len(m.requires), reverse=True):
-            column.stdin.write('%s\t->\t%r\n' % (mod, sorted(mod.requires)))
-            # print '%s\t->\t%r' % (mod, sorted(mod.requires))
-        
-        column.stdin.close()
-        if column.wait() != 0: print 'Some sort of error has occurred!'
-        print column.stdout.read()
+        print >> sys.stderr, 'All Dependencies:'
+        print >> sys.stderr, js.dumpDependencies()
+        print >> sys.stderr, ''
+        print >> sys.stderr, 'Resolution:'
+        print >> sys.stderr, '\n'.join(js.dependencies)
     
     return 0
 
index 3285ae5..38cd78e 100644 (file)
@@ -2,9 +2,8 @@
 - Tanks seem to get stuck on some corners
 
 # TODOs
-- How-to overlay
-- Restart level button
-- AI: Line-of-sight for dodging, firing
+- change @require to @ensure
+
 - AI: Don't shoot if it'll kill you or your friends
 - AI: Lead shots on moving targets
 - Config-driven unit-types (name, stats, properties; pointers to behavior scripts, assets)
index afcb361..3ac3f78 100644 (file)
--- a/index.php
+++ b/index.php
 </div></div>
 
 <div id="scripts">
-<?php require "tanks.php"; Tanks::writeTags( Tanks::ALL_SCRIPTS ); ?>
+<?php
+    /* require "tanks.php"; Tanks::writeTags( Tanks::ALL_SCRIPTS ); */
+    require "tanks.php"; Tanks::writeLoaders();
+?>
 </div>
 
 </body>
diff --git a/lib/cjs/deps.js b/lib/cjs/deps.js
new file mode 100644 (file)
index 0000000..3735e59
--- /dev/null
@@ -0,0 +1,3 @@
+{{{uris}}}.forEach(function(uri){
+    document.write('<scr'+'ipt src="'+uri+'" type="text/javascript"></scr'+'ipt>');
+});
diff --git a/lib/cjs/dummy.js b/lib/cjs/dummy.js
new file mode 100644 (file)
index 0000000..71c5a6b
--- /dev/null
@@ -0,0 +1,14 @@
+require.install(
+// Module ID
+'{{{id}}}',
+
+// Module metadata
+{
+    'name'  : '{{{name}}}',
+    'id'    : '{{{id}}}',
+    'uri'   : '{{{uri}}}'
+},
+// Dummy module: setup does nothing
+function setup{{{name}}}(require, exports, module){});
+
+{{{text}}}
index 7f225e1..167f51a 100644 (file)
@@ -1,17 +1,17 @@
 require.install(
 // Module ID
-'{{id}}',
+'{{{id}}}',
 
 // Module metadata
 {
-    'name'  : '{{name}}',
-    'id'    : '{{id}}',
-    'uri'   : '{{uri}}'
+    'name'  : '{{{name}}}',
+    'id'    : '{{{id}}}',
+    'uri'   : '{{{uri}}}'
 },
 
 // Module Setup function
-function setup{{name}}(require, exports, module){
+function setup{{{name}}}(require, exports, module){
 
-{{text}}
+{{{text}}}
 
 });
\ No newline at end of file
diff --git a/lib/jquery.js b/lib/jquery.js
new file mode 120000 (symlink)
index 0000000..0185856
--- /dev/null
@@ -0,0 +1 @@
+jquery-1.4.3.min.js
\ No newline at end of file
index 9ca59ab..dc1a4b5 100644 (file)
@@ -1,7 +1,10 @@
 // Inspired by John Resig's "Simple Class Inheritence" -- http://ejohn.org/blog/simple-javascript-inheritance/
 
-var Y = require('Y').Y
-,   type = require('Y/type')
+var type      = require('Y/type')
+,   YFunction = require('Y/types/function').YFunction
+,   core      = require('Y/core')
+,   slice     = core.slice
+
 ,   KNOWN_CLASSES = type.type.KNOWN_CLASSES
 ,   classToString = function toString(){ return this.className+"()"; }
 ;
@@ -113,7 +116,7 @@ function Class(className, Parent, members) {
             prototype[k] = members[k];
     }
     
-    if (prototype.init) NewClass.init = Y(prototype.init);
+    if (prototype.init) NewClass.init = YFunction(prototype.init);
     
     KNOWN_CLASSES[className] = NewClass;
     
@@ -171,59 +174,9 @@ var YBase = new Class("YBase", {
 
 
 
-
-/// Other Class Utilities ///
-
-function bindName(v, k){
-    if ( isFunction(v) )
-        this[k] = Y(v).bind(this);
-}
-// bindName = Y(bindName).curry();
-
-function bindAll(o, names){
-    var names = new Y(arguments, 1);
-    Y(names.size() ? names.generate(Y.op.get(o)) : o).forEach( bindName, o );
-    return o;
-}
-
-// Y.chainDelegates = chainDelegates;
-function chainDelegates(type, name){
-    var names = Y(arguments, 1),
-        proto = type.prototype;
-    names.forEach(function(name){
-        proto[name] = function(){
-            var o = this._o || this;
-            o[name].apply(o, Y(arguments));
-            return this;
-        };
-    });
-    return type;
-}
-
-// Y.mixinNames = mixinNames;
-function mixinNames(o, Donor, names, override, yWrap){
-    var target = ( isFunction(o)     ? o.prototype     : o)
-    ,   proto  = ( isFunction(Donor) ? Donor.prototype : Donor);
-    
-    // Need a closure to capture the name
-    names.forEach(function(name){
-        if ( isFunction(proto[name]) && (override || !target[name]) )
-            target[name] = function(){
-                var r = proto[name].apply(this._o || target, arguments);
-                return (yWrap ? Y(r) : r);
-            };
-    });
-    
-    return o;
-}
-
 exports['Class'] =
 exports['subclass']    = Class;
 exports['instantiate'] = Class.instantiate.bind(Class);
 exports['fabricate']   = Class.fabricate.bind(Class);
-
-exports['YBase']          = YBase;
-exports['bindAll']        = bindAll;
-exports['chainDelegates'] = chainDelegates;
-exports['mixinNames']     = mixinNames;
+exports['YBase']       = YBase;
 
index 83f1594..0725a30 100644 (file)
@@ -1,4 +1,15 @@
 // Generic Collection Functions
+var undefined
+,   globals   = (function(){ return this; })()
+,   _Function = globals.Function
+,   _Array    = globals.Array
+,   PT = "prototype"
+,   slice = _Array[PT].slice
+;
+
+// function slice(a){
+//     return _asl.apply(a, _asl.call(arguments, 1));
+// }
 
 function notWrapped(fn){
     var self = arguments.callee.caller;
@@ -9,7 +20,7 @@ function reduce(o, fn, acc){
     if ( !o )
         return acc;
     
-    fn = Function.toFunction(fn);
+    fn = _Function.toFunction(fn);
     var cxt = arguments[3] || o;
     if ( notWrapped(o.reduce) )
         return o.reduce.apply(o, [fn, acc, cxt]);
@@ -24,7 +35,7 @@ function map(o, fn){
     if ( !o )
         return o;
     
-    fn = Function.toFunction(fn);
+    fn = _Function.toFunction(fn);
     var acc = {}, cxt = arguments[2] || o;
     if ( notWrapped(o.map) )
         return o.map.apply(o, [fn, cxt]);
@@ -44,7 +55,7 @@ function filter(o, fn){
     if ( !o )
         return o;
     
-    fn = Function.toFunction(fn);
+    fn = _Function.toFunction(fn);
     var acc = {}, cxt = arguments[2] || o;
     if ( notWrapped(o.filter) )
         return o.filter.apply(o, [fn, cxt]);
@@ -116,3 +127,4 @@ exports['extend']  = extend;
 exports['dset']    = dset;
 exports['dattr']   = dattr;
 exports['dextend'] = dextend;
+exports['slice']   = slice;
\ No newline at end of file
index bc8097e..cdfd44e 100644 (file)
@@ -1,7 +1,8 @@
+//  -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
 
 /// Import our external deps first ///
-// require('lessly/future');
-// require('functional/to-function');
+//@require('lessly/future');
+//@require('functional/to-function');
 
 /// Set up core and utilities ///
 var core = require('Y/core')
@@ -17,6 +18,7 @@ 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;
@@ -41,7 +43,7 @@ addNames('curry methodize genericize compose chain memoize', yfn);
 // Curry all operators
 var op = require('Y/op');
 core.forEach(op, YFunction);
-Y['op'] = op.extend({}, core.map(yfn.curry, op));
+Y['op'] = op['curried'] = op.extend({}, core.map(yfn.curry, op));
 // Y['op'] = core.reduce(op, function(Yop, fn, k){
 //     Yop[k] = yfn.curry(fn);
 //     return Yop;
similarity index 86%
rename from src/Y/modules/y.cookies.js
rename to src/Y/modules/y.cookies.cjs
index 2342220..b3aedac 100644 (file)
@@ -1,12 +1,12 @@
-(function(Y, undefined){ if (!Y) return;
-
 var _document = document
+,   Y   = require('Y').Y
 ,   enc = encodeURIComponent
 ,   dec = decodeURIComponent
-,   ns  = Y.cookies = {}
 ;
 
-ns.get =
+Y['cookies'] = exports;
+
+exports['get'] =
     function getCookie(k){
         var cookies = Y(_document.cookie+'').fromKV('; ');
         if (k !== undefined)
@@ -15,7 +15,7 @@ ns.get =
             return cookies;
     };
 
-ns.set = 
+exports['set'] = 
     function setCookie(k, v, expires, path){
         expires = 'expires='+(expires || "Sun, 24-Mar-2024 11:11:11 GMT");
         path = 'path='+(path || "/");
@@ -24,5 +24,3 @@ ns.set =
     };
 
 // TODO: YCollection methods on ns over kv pairs.
-
-})(this.Y);
similarity index 94%
rename from src/Y/modules/y.event.js
rename to src/Y/modules/y.event.cjs
index d3d0be5..577aa02 100644 (file)
@@ -1,7 +1,4 @@
-(function(Y, undefined){
-
-var 
-ns = Y.event = {}
+Y['event'] = exports;
 
 /**
  * A simple event.
@@ -9,7 +6,7 @@ ns = Y.event = {}
  * TODO: If DOM event, wrap with consistent API.
  * TODO: use jQuery if present to wrap events.
  */
-, YEvent = ns.YEvent = 
+var YEvent = exports['YEvent'] = 
 Y.YObject.subclass('YEvent', {
     init : function init( type, target, trigger, data ){
         data = data || {};
@@ -69,9 +66,9 @@ Y.YObject.subclass('YEvent', {
             delegate[k] = methods[k].bind(this);
         return delegate;
     }
-}
+},
 
-, Emitter = ns.Emitter =
+Emitter = exports['Emitter'] =
 Y.YObject.subclass('Emitter', 
     Y.extend({
         'init' : function(target, parent){
@@ -90,7 +87,4 @@ Emitter.methods = methods;
 
 // Global Event Hub
 Emitter.global = new Emitter()
-Emitter.global.decorate(Y.event);
-
-
-})(this.Y);
+Emitter.global.decorate(exports);
similarity index 62%
rename from src/Y/modules/y.json.js
rename to src/Y/modules/y.json.cjs
index ec4cde6..5d7f673 100644 (file)
@@ -1,4 +1,4 @@
-(function(Y){
+var Y = require('Y').Y;
 
 function toJSON(o, k){
     var prefix = typeof(k) === 'string' ? '"'+k+'":' : '',
@@ -7,9 +7,8 @@ function toJSON(o, k){
 }
 
 function install(json_fn){
-    var args = new Y(arguments),
-        tojson = args.shift();
-    args.each(function(YThing){
+    var args = Y(arguments,1);
+    args.forEach(function(YThing){
         YThing.prototype.toJSON = json_fn;
     });
 }
@@ -29,7 +28,7 @@ function quoteJSON(){
 // Collections
 
 function reducer(acc, v, k, o){
-    var json = toJSON(v, Y.is.array(o) ? 0 : k);
+    var json = toJSON(v, Y.isArray(o) ? 0 : k);
     return json ? (acc ? acc+','+json : json) : acc;
 }
 
@@ -40,13 +39,12 @@ var collectJSON = Y(function(a, z){
 
 // Public API
 
-Y.toJSON = toJSON;
+Y['toJSON'] = exports['toJSON'] = toJSON;
 
-install( yNoJSON, Y.YGeneric, Y.YFunction, Y.YRegExp );
-install( yToJSON, Y, Y.YBoolean, Y.YNumber );
+// install( yNoJSON, Y.YBase, Y.YFunction, Y.YRegExp );
+// install( yToJSON, Y, Y.YBoolean, Y.YNumber );
+install( yNoJSON, Y.YBase, Y.YFunction );
+install( yToJSON, Y, Y.YNumber );
 install( quoteJSON, Y.YString );
-install( collectJSON.partial('{', '}'), Y.YCollection );
+install( collectJSON.partial('{', '}'), Y.YCollection, Y.YObject );
 install( collectJSON.partial('[', ']'), Y.YArray );
-
-
-})(this.Y);
similarity index 88%
rename from src/Y/modules/y.kv.js
rename to src/Y/modules/y.kv.cjs
index f6c2c82..a05be23 100644 (file)
@@ -1,6 +1,5 @@
-(function(Y, undefined){ if (!Y) return;
-
-var enc = encodeURIComponent
+var Y   = require('Y').Y
+,   enc = encodeURIComponent
 ,   dec = decodeURIComponent
 ;
 
@@ -25,4 +24,3 @@ Y.YString.prototype.fromKV =
             }, {});
     };
 
-})(this.Y);
index 97ef023..e621efa 100644 (file)
@@ -1,7 +1,7 @@
 /* A subset of the functional operators, used in Y's core */
 
-var Y    = require('Y').Y
-,   core = require('Y/core')
+var core = require('Y/core')
+,   slice = core.slice
 ,   op = { // XXX: Make these function statements?
     
     // comparison
@@ -41,6 +41,7 @@ var Y    = require('Y').Y
     nop:    function(x){},
     I:      function(x){       return x; },
     K:      function(k){       return function(){ return k; }; },
+    nth:    function(n){       return function(){ return arguments[n]; }; },
     val:    function(def,o){   return o !== undefined ? o : def; },
     ok:     function(o){       return o !== undefined && o !== null; },
     
@@ -57,10 +58,10 @@ var Y    = require('Y').Y
     set:     core.set,  // set(  o, key, value, def )
     attr:    core.attr, // attr( o, key, value, def )
     method: function(name){
-        var args = Y(arguments,1);
+        var args = slice.call(arguments,1);
         return function(obj){
             if (obj && obj[name])
-                return obj[name].apply( obj, args.concat(Y(arguments)) );
+                return obj[name].apply( obj, args.concat(slice.call(arguments)) );
             else
                 return obj;
         };
index 18b50e3..c1f568b 100644 (file)
@@ -1,35 +1,35 @@
-var Y = require('Y').Y;
+var YCollection = require('Y/types/collection').YCollection
+,   mixin = require('Y/utils').mixin
+,   slice = require('Y/core').slice
+;
 
 exports['YArray'] =
-Y.YCollection.subclass('YArray', function(YArray){
-    var yclass = require('Y/class');
+YCollection.subclass('YArray', function(YArray){
     
-    yclass.chainDelegates(YArray, 'push', 'unshift', 'sort', 'splice', 'reverse');
-    yclass.mixinNames(YArray, Array, ['reduce', 'map', 'forEach', 'filter', 'slice', 'some', 'every'],    true, true);
-    yclass.mixinNames(YArray, Array, ['indexOf', 'lastIndexOf', 'shift', 'pop', 'join'], true, false);
+    mixin(YArray, { donor:Array, chain:true,
+        names:'push unshift sort splice reverse'.split(' ') });
+    mixin(YArray, { donor:Array, wrap:YArray,
+        names:'map forEach filter slice'.split(' ') });
+    mixin(YArray, { donor:Array,
+        names:'reduce some every indexOf lastIndexOf shift pop join'.split(' ') });
     
     
-    
-    
-    this.init = function(o){
-        // YCollection.init.call(this, o || []);
+    this.init = function initYArray(o){
         this._o = o || [];
     };
     
     this.merge  =
     this.concat =
     function concat( donor ){
-        var A = this._o;
-        new Y(arguments).forEach(function( donor ){
-            A = A.concat(donor instanceof YArray ? donor.end() : donor);
-        });
-        return Y(A);
+        return new YArray( slice.call(arguments).reduce(function(A, donor ){
+            return A.concat(donor instanceof YArray ? donor.end() : donor);
+        }, this._o) );
     };
     
     this.remove =
     function remove(v){
         if (arguments.length > 1)
-            Y(arguments).forEach(this.remove, this);
+            slice.call(arguments).forEach(this.remove, this);
         else {
             var idx = this.indexOf(v);
             if ( idx != -1 )
@@ -62,12 +62,20 @@ Y.YCollection.subclass('YArray', function(YArray){
         // });
     };
     
+    // this.zip =
+    // function zip(){
+    //     var sequences = new YArray(slice.call(arguments)).map( Y.limit(1) ).unshift(this);
+    //     return this.map(function(_, k){
+    //         return sequences.invoke('attr', k);
+    //     }).invoke('end');
+    // };
+    
     // Like map, but produces a dict
     // Y(["Foo?", "R&D"]).generate(encodeURIComponent)
     //  -> Y({"Foo?":"Foo%3F", "R&D":"R%26D"})
     this.generate =
     function generate(fn, acc){
-        var args = Y(arguments),
+        var args = slice.call(arguments),
             fn = args.shift(),
             acc = args.shift();
         return this.reduce(function(acc, v, i){
@@ -84,7 +92,7 @@ Y.YCollection.subclass('YArray', function(YArray){
     
     this.clone =
     function clone(){
-        return Y(this._o.slice(0));
+        return new YArray(this._o.slice(0));
     };
     
     this.size =
index 669f942..56eb0b9 100644 (file)
@@ -1,25 +1,29 @@
 /** YCollection is the core of Y. */
 
-var Y = require('Y').Y
+var YBase      = require('Y/class').YBase
 ,   isFunction = require('Y/type').isFunction
-,   extend     = require('Y/core').extend
-,   bool       = require('Y/op').bool
+,   core       = require('Y/core')
+,   op         = require('Y/op')
+,   slice      = core.slice
+,   extend     = core.extend
+,   attr       = core.attr
+,   bool       = op.bool
 ;
 
 
 function extendY(){
-    extend.apply(this, [this._o].concat(Y(arguments)));
+    extend.apply(this, [this._o].concat(slice.call(arguments)));
     return this;
 }
 
 exports['YCollection'] =
-Y.YBase.subclass('YCollection', {
+YBase.subclass('YCollection', {
     'init' : function(o){
         this._o = o || {};
     },
     
     'attr'   : function attr(k, v, def){
-        var r = Y.attr(this._o, k, v, def);
+        var r = attr(this._o, k, v, def);
         if (r === this._o)
             return this;
         else
@@ -73,19 +77,35 @@ Y.YBase.subclass('YCollection', {
     },
     
     'clone' : function clone(){
-        return Y({}).extend(this);
+        return new this.constructor().extend(this);
     },
     
+    // 'remove' : function remove(v){
+    //     var o = this._o
+    //     ,   toRemove = new Y(arguments);
+    //     
+    //     for (var k in o) {
+    //         var v = o[k];
+    //         if ( toRemove.has(v) ) {
+    //             delete o[k];
+    //             toRemove.remove(v);
+    //         }
+    //     }
+    //     return this;
+    // },
+    
     'remove' : function remove(v){
         var o = this._o
-        ,   toRemove = new Y(arguments);
+        ,   toRemove = slice.call(arguments);
         
         for (var k in o) {
-            var v = o[k];
-            if ( toRemove.has(v) ) {
+            var v = o[k], idx = toRemove.indexOf(v);
+            if ( idx !== -1 ) {
                 delete o[k];
-                toRemove.remove(v);
+                toRemove.splice(idx,1);
             }
+            if (!toRemove.length)
+                break;
         }
         return this;
     },
@@ -105,10 +125,11 @@ Y.YBase.subclass('YCollection', {
     },
     
     'zip' : function zip(){
-        var sequences = new Y(arguments).map( Y.limit(1) ).unshift(this);
+        var sequences = slice.call(arguments);
+        sequences.unshift(this);
         return this.map(function(_, k){
-            return sequences.invoke('attr', k);
-        }).invoke('end');
+            return sequences.map(op.curried.kget(k));
+        });
     },
     
     'pluck' : function pluck(key){
@@ -118,9 +139,8 @@ Y.YBase.subclass('YCollection', {
     },
     
     'invoke' : function invoke(name){
-        var args = Y(arguments),
-            name = args.shift();
-        return this.map(function(o){
+        var args = slice.call(arguments,1);
+        return core.map(this, function(o){
             return o && o[name].apply(o, args);
         });
     },
index f354cb3..88e81ba 100644 (file)
@@ -2,14 +2,11 @@ var undefined
 ,   WRAPS   = "__wraps__"
 ,   globals = (function(){ return this; })()
 
-,   Y    = require('Y').Y
-,   core = require('Y/core')
-,   type = require('Y/type')
+,   core   = require('Y/core')
+,   type   = require('Y/type')
 
-,   isNumber      = type.isNumber
 ,   isFunction    = type.isFunction
-,   isArray       = type.isArray
-,   isPlainObject = type.isPlainObject
+,   slice         = core.slice
 
 ,   _   = exports._ = YFunction._ = {}
 ,   YFP = YFunction.prototype
@@ -48,17 +45,17 @@ function unwrap(fn){
 
 function curry(fn){
     if (fn.__curried__)
-        return fn.apply(this, Y(arguments,1));
+        return fn.apply(this, slice.call(arguments,1));
     
     fn = Function.toFunction(fn);
-    var args = Y(arguments, 1)
+    var args = slice.call(arguments, 1)
     ,   L = unwrap(fn).length;
     
     if ( args.length >= L )
         return fn.apply(this, args);
     
     function curried(){
-        var _args = args.concat( Y(arguments) );
+        var _args = args.concat( slice.call(arguments) );
         if ( _args.length >= L )
             return fn.apply(this, _args);
         else
@@ -80,7 +77,7 @@ function methodize(fn) {
     
     m = fn.__methodized__ =
         function methodized(){
-            return fn.apply(this, [this].concat( Y(arguments) ));
+            return fn.apply(this, [this].concat( slice.call(arguments) ));
         };
     m[WRAPS] = fn;
     return m;
@@ -95,7 +92,7 @@ function genericize( fn ) {
     
     g = fn.__genericized__ =
         function genericized(){
-            var args = Y(arguments);
+            var args = slice.call(arguments);
             return fn.apply(args.shift(), args);
         };
     g[WRAPS] = fn;
@@ -106,20 +103,20 @@ function genericize( fn ) {
 
 function _composer(x,fn){ return fn.call(this, x); }
 function compose(f,g){
-    var fns = Y(arguments).map(Function.toFunction);
+    var fns = slice.call(arguments).map(Function.toFunction);
     return function(){
-        return fns.reduce(_composer, Y(arguments), this);
+        return fns.reduce(_composer, slice.call(arguments), this);
     };
 }
 
 function chain(f,g){
-    var fns = Y(arguments).map(Function.toFunction);
+    var fns = slice.call(arguments).map(Function.toFunction);
     
     if ( g.__sequence__ )
         fns = g.__sequence__.concat( fns.slice(1) );
     
     function chained(){
-        var args = Y(arguments)
+        var args = slice.call(arguments)
         ,   i = fns.length;
         while (i-- > 0) args = fns[i].call(this, x);
         return args;
@@ -131,10 +128,10 @@ function chain(f,g){
 
 // YFunction.prototype.lazy = methodize(lazy);
 // function lazy(fn){
-//     var args = Y(arguments, 1)
+//     var args = slice.call(arguments, 1)
 //     ,   L = unwrap(fn).length
 //     ,   lazied = function(){
-//             var _args = Y(arguments)
+//             var _args = slice.call(arguments)
 //             ,   f = _args[0];
 //             
 //             if ( isFunction(f) ) {
@@ -158,7 +155,7 @@ function chain(f,g){
 
 var _bind = _Function.prototype.bind;
 function bind(fn, context, args){
-    var bound = _bind.apply(fn, Y(arguments,1));
+    var bound = _bind.apply(fn, slice.call(arguments,1));
     bound[WRAPS] = fn;
     return YFunction(bound);
 }
@@ -166,10 +163,10 @@ function bind(fn, context, args){
 
 // Remembers arguments but obeys current context
 function partial(fn){
-    var args = Y(arguments,1)
+    var args = slice.call(arguments,1)
     ,   partially = 
         function partially(){
-            return fn.apply( this, args.concat(Y(arguments)) );
+            return fn.apply( this, args.concat(slice.call(arguments)) );
         };
     partially[WRAPS] = fn;
     return YFunction(partially);
@@ -192,7 +189,7 @@ function memoize(fn){
     fn.__memoized__ =
         function memorizer(){
             // toJSON would be a better alternative, but that won't work cross-browser
-            var key = Y(arguments).join('\0\0\0')
+            var key = slice.call(arguments).join('\0\0\0')
             ,   cache = arguments.callee.cache;
             if ( !(key in cache) )
                 cache[key] = fn.apply(this, arguments);
@@ -215,9 +212,12 @@ var
 _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('+Y.range(n).map( Y.op.add('$') ).join(',')+'){ '+
-                'return fn.apply(this,' + (limit ? 'Y(arguments).slice(0,'+n+')' : 'arguments')+ 
+            'return function('+args.join(',')+'){ '+
+                'return fn.apply(this,' + (limit ? 'slice.call(arguments, 0,'+n+')' : 'arguments')+ 
             '); }; })');
     });
 
@@ -265,9 +265,9 @@ function getName( fn ){
         return fn.className || fn.name || (fn+'').match( /function\s*([^\(]*)\(/ )[1] || '';
 }
 
-function splat(fn, x){
-    return fn[ isArray(x) ? "apply" : "call"](this, x);
-}
+// function splat(fn, x){
+//     return fn[ isArray(x) ? "apply" : "call"](this, x);
+// }
 
 
 
@@ -284,7 +284,6 @@ exports['memoize']    = memoize;
 exports['aritize']    = aritize;
 exports['limit']      = limit;
 exports['getName']    = getName;
-// exports['splat']      = splat;
 
 // Methodize and then attach to YFunction's prototype
 YFP.extend(core.map(exports, methodize));
index 875a641..6fb9bb5 100644 (file)
@@ -1,4 +1,4 @@
-var Y = require('Y').Y
+var YCollection = require('Y/types/collection').YCollection
 ,   op = require('Y/op')
 ;
 
@@ -38,7 +38,7 @@ function range(start, end, step){
 
 
 exports['YNumber'] =
-Y.YCollection.subclass('YNumber', {
+YCollection.subclass('YNumber', {
     init: function(o){
         this._o = o || 0;
     },
index 3aeec15..07db9d7 100644 (file)
@@ -1,10 +1,11 @@
-var Y = require('Y').Y
-,   isArray = Y.isArray
+var YCollection = require('Y/types/collection').YCollection
+,   type = require('Y/type')
+,   isArray = type.isArray
 ;
 
 
 exports['YObject'] =
-Y.YCollection.subclass('YObject', {
+YCollection.subclass('YObject', {
     
     'init': function initYObject(o){
         this._o = o || {};
index cff211f..f8f608f 100644 (file)
@@ -1,18 +1,17 @@
-var Y = require('Y').Y
-,   mixinNames = require('Y/class').mixinNames
-,   op = require('Y/op')
+var YCollection = require('Y/types/collection').YCollection
+,   mixin = require('Y/utils').mixin
+,   op    = require('Y/op')
+,   core  = require('Y/core')
+,   slice = core.slice
 ;
 
 exports['YString'] =
-Y.YCollection.subclass('YString', function(YString){
+YCollection.subclass('YString', function(YString){
     
-    mixinNames(YString, String, [
-            'slice', 'split',
-            'substr', 'substring',
-            'concat', 'replace',
-            'toLowerCase', 'toUpperCase'
-        ], true, true);
-    mixinNames(YString, String, [ 'indexOf', 'lastIndexOf', 'charAt', 'charCodeAt' ], true, false);
+    mixin(YString, { donor:String, wrap:YString,
+        names:'slice split substr substring concat replace toLowerCase toUpperCase'.split(' ') });
+    mixin(YString, { donor:String,
+        names:'indexOf lastIndexOf charAt charCodeAt'.split(' ') });
     
     function trim(val){
         var s = this._o+'';
@@ -46,7 +45,7 @@ Y.YCollection.subclass('YString', function(YString){
             howMany = Number(howMany > 0 ? howMany : 0);
             
             var prefix = s.slice(0, idx)
-            ,   insert = Y(arguments, 2).join('')
+            ,   insert = slice.call(arguments, 2).join('')
             ,   suffix = s.slice(idx+howMany)
             ;
             this._o = prefix + insert + suffix;
@@ -60,18 +59,9 @@ Y.YCollection.subclass('YString', function(YString){
          * Negative values for start and/or end are allowed.
          */
         mutate : function mutate(start, end){
-            return this.splice.apply(this, [start, end-start].concat(Y(arguments, 2)) );
-            // var s = this._o, len = s.length ;
-            // 
-            // if (start < 0) start += len;
-            // if (end < 0)   end   += len;
-            // 
-            // var prefix = s.slice(0, start)
-            // ,   insert = Y(arguments, 2).join('')
-            // ,   suffix = s.slice(end)
-            // ;
-            // this._o = prefix + insert + suffix;
-            // return this;
+            // var args = slice.call(arguments);
+            arguments[1] = end-start;
+            return this.splice.apply(this, arguments);
         },
         
         strip: function strip(){ 
@@ -116,9 +106,9 @@ Y.YCollection.subclass('YString', function(YString){
     this.set = function set(key, value, def){
         var s = this._o, _val = (value !== undefined ? value : def);
         
-        if ( Y.isNumber(key) )
+        if ( isNumber(key) )
             return this.splice(key, 1, _val);
-        if ( Y.isArray(key) )
+        if ( isArray(key) )
             return this.splice.apply(this, key.slice(0,2).concat([_val]) );
         
         // TODO: Should cache the new properties and re-applied them whenever we mutate _o,
@@ -131,19 +121,19 @@ Y.YCollection.subclass('YString', function(YString){
         var s = this._o;
         // set
         if ( value !== undefined || def !== undefined )
-            return Y.attr(this, key, value, def);
+            return core.dattr(this, key, value, def);
             
         // get
         else {
-            if ( Y.isNumber(key) )
+            if ( isNumber(key) )
                 return s.charAt(key);
-            if ( Y.isArray(key) )
+            if ( isArray(key) )
                 return s.slice.apply(s, key);
             
             return s[key];
         }
     };
-    this.attr.__wraps__ = Y.attr;
+    this.attr.__wraps__ = core.dattr;
     
     this.reduce = function reduce(fn, acc){
         fn = Function.toFunction(fn);
diff --git a/src/Y/utils.cjs b/src/Y/utils.cjs
new file mode 100644 (file)
index 0000000..9886733
--- /dev/null
@@ -0,0 +1,68 @@
+var YFunction  = require('Y/types/function').YFunction
+,   isFunction = require('Y/type').isFunction
+,   core       = require('Y/core')
+,   op         = require('Y/op')
+;
+
+
+function bindName(k){
+    var v = this[k];
+    if ( isFunction(v) )
+        this[k] = YFunction(v).bind(this);
+}
+
+function bindAll(o, names){
+    if (!o)
+        return o;
+    if (arguments.length === 1)
+        names = core.map(o, op.nth(1));
+    else
+        names = slice.call(arguments, 1);
+    names.forEach(bindName, o);
+    return o;
+}
+
+
+var defaults = {
+    'donor'    : null,
+    'names'    : null,
+    'override' : true,
+    'wrap'     : false,
+    'chain'    : false
+};
+function mixin(target, options){
+    var opt    = op.extend({}, defaults, options), Donor = opt.donor
+    ,   target = ( isFunction(target) ? target.prototype : target )
+    ,   proto  = ( isFunction(Donor)  ? Donor.prototype  : Donor  )
+    ,   names  = opt.names
+    ;
+    
+    // Need a closure to capture the name
+    names.forEach(function(name){
+        var fn = proto[name];
+        if ( isFunction(fn) && (opt.override || !(name in target)) )
+            target[name] = function(){
+                var r = fn.apply(this._o || target, arguments);
+                return (opt.chain ? this : (opt.wrap ? opt.wrap(r) : r));
+            };
+    });
+    
+    return o;
+}
+
+
+// function chainDelegates(type, names){
+//     var proto = type.prototype;
+//     names.forEach(function(name){
+//         proto[name] = function(){
+//             var o = this._o || this;
+//             o[name].apply(o, arguments);
+//             return this;
+//         };
+//     });
+//     return type;
+// }
+// exports['chainDelegates'] = chainDelegates;
+
+exports['bindAll'] = bindAll;
+exports['mixin']   = mixin;
index 3241611..a9018a8 100644 (file)
@@ -1,3 +1,4 @@
+//  -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*- 
 var undefined
 ,   globals   = (function(){ return this; })()
 ,   _Object   = globals.Object
index 07422ef..dfc3701 100644 (file)
@@ -1,4 +1,3 @@
-(function(undefined){
 // Inspired by John Resig's "Simple Class Inheritence" -- http://ejohn.org/blog/simple-javascript-inheritance/
 /*
 Metaprogramming API
@@ -24,11 +23,11 @@ Class Methods
 Note: Metaprogramming events cannot depend on Class.
 */
 
+var Y = require('Y').Y
+,   Emitter = require('Y/modules/y.event').Emitter
 
-
-var Evt = this.Evt  = (this.Evt || {})
-,   KNOWN_CLASSES   = Class.KNOWN_CLASSES = {}
 ,   isFunction      = Y.isFunction
+,   KNOWN_CLASSES   = Class.KNOWN_CLASSES = exports['KNOWN_CLASSES'] = {}
 ,   getProto        = Object.getPrototypeOf
 ,   hasOwn          = Object.prototype.hasOwnProperty
 ,   objToString     = Object.prototype.toString
@@ -38,13 +37,13 @@ var Evt = this.Evt  = (this.Evt || {})
 // Private delegating constructor -- must be defined for every
 // new class to prevent shared state. All construction is
 // actually done in the init method.
-Evt.ConstructorTemplate = ConstructorTemplate;
+exports['ConstructorTemplate'] = ConstructorTemplate;
 function ConstructorTemplate() {
     var cls = arguments.callee
     ,   instance = this;
     
     // Not subclassing
-    if ( cls.caller !== Evt.Class.fabricate ) {
+    if ( cls.caller !== Class.fabricate ) {
         
         cls.fire('create', instance, {
             'instance' : instance,
@@ -154,7 +153,7 @@ function Class(className, Parent, members){
             ,   init     = NewClass.prototype.init
             ;
             
-            instance.__emitter__ = new Y.event.Emitter(instance, NewClass);
+            instance.__emitter__ = new Emitter(instance, NewClass);
             
             if (init) {
                 var result = init.apply(instance, arguments);
@@ -172,7 +171,7 @@ function Class(className, Parent, members){
     
     // Add class emitter
     var ParentEmitter = (Parent.__emitter__ ? Parent : ClassFactory)
-    ,   ClassEmitter  = NewClass.__emitter__ = new Y.event.Emitter(NewClass, ParentEmitter)
+    ,   ClassEmitter  = NewClass.__emitter__ = new Emitter(NewClass, ParentEmitter)
     ;
     
     // Either invoke body constructor...
@@ -204,7 +203,7 @@ function Class(className, Parent, members){
 // Decorate with emitter methods and
 // add metaprogramming data to Class object
 Class.__super__ = Object;
-Class.__emitter__ = new Y.event.Emitter(Class);
+Class.__emitter__ = new Emitter(Class);
 Class.fn = Class.prototype;
 Class.fn.__class__ = Class;
 Class.className = Class.fn.className = "Class";
@@ -242,9 +241,6 @@ Class.fn.subclass =
 
 
 // Expose
-Evt.Class =
-Evt.subclass = Class;
-
-
+exports['Class'] =
+exports['subclass'] = Class;
 
-})();
\ No newline at end of file
diff --git a/src/ezl/index.cjs b/src/ezl/index.cjs
new file mode 100644 (file)
index 0000000..955dc17
--- /dev/null
@@ -0,0 +1,5 @@
+//  -*- mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; -*-
+//@require('jquery')
+//@require('lessly/future')
+//@require('Y')
+
similarity index 96%
rename from src/ezl/layer.js
rename to src/ezl/layer.cjs
index b6cd536..063a740 100644 (file)
@@ -1,16 +1,24 @@
-(function($, undefined){
+//@require('jquery')
 
-var CONTEXT_ATTRS = Y([
+var undefined
+,   Y   = require('Y').Y
+,   Vec = require('ezl/math/vec').Vec
+,   loc = require('ezl/loc')
+,   Loc = loc.Loc
+,   BoundingBox = loc.BoundingBox
+, 
+CONTEXT_ATTRS = Y([
     'globalAlpha', 'globalCompositeOperation',
     'strokeStyle', 'fillStyle',
     'lineWidth', 'lineCap', 'lineJoin', 'miterLimit',
     'shadowOffsetX', 'shadowOffsetY', 'shadowBlur', 'shadowColor'
-]);
+])
+,
 
-
-
-Layer = Y.subclass('Layer', {
-    _cssClasses : 'portal layer',
+Layer =
+exports['Layer'] =
+Y.subclass('Layer', {
+    _cssClasses : 'ezl layer',
     
     canvas   : null,
     
@@ -503,11 +511,9 @@ function makeDelegate(name, dirties, prop){
 $(function(){
     $('<style />')
         .text([
-            '.portal.layer { position:absolute; z-index:1; top:0; left:0; line-height:0; }',
-            // '.portal.layer { outline:1px solid #000000; }',
-            '.portal.layer canvas { z-index:0; }'
+            '.ezl.layer { position:absolute; z-index:1; top:0; left:0; line-height:0; }',
+            // '.ezl.layer { outline:1px solid #000000; }',
+            '.ezl.layer canvas { z-index:0; }'
         ].join('\n'))
         .appendTo('head');
 });
-
-})(jQuery);
diff --git a/src/ezl/loc/boundingbox.cjs b/src/ezl/loc/boundingbox.cjs
new file mode 100644 (file)
index 0000000..f7ae7d5
--- /dev/null
@@ -0,0 +1,74 @@
+var Y = require('Y').Y
+,   math = require('ezl/math')
+,   Vec  = math.Vec
+,   Line = math.Line
+,   Rect = math.Rect
+,
+
+BoundingBox =
+exports['BoundingBox'] =
+Rect.subclass('BoundingBox', {
+    init : function initBoundingBox(x1,y1, x2,y2){
+        Rect.init.call(this, x1,y1, x2,y2);
+        
+        this.sides = {
+            top    : new Line(x1,y1, x2,y1),
+            bottom : new Line(x1,y2, x2,y2),
+            left   : new Line(x1,y1, x1,y2),
+            right  : new Line(x2,y1, x2,y2)
+        };
+    },
+    
+    set : function set(k, v, def){
+        v = (v !== undefined ? v : def);
+        
+        switch (k) {
+            case 'x1': case 0: case 'x':    this.x1 = this[0] = this.x = v;     break;
+            case 'y1': case 1: case 'y':    this.y1 = this[1] = this.y = v;     break;
+            case 'x2': case 2:              this.x2 = this[2] = v;              break;
+            case 'y1': case 3:              this.y2 = this[3] = v;              break;
+            
+            default: this[k] = v;
+        }
+        
+        this.width  = this.x2 - this.x1;
+        this.height = this.y2 - this.y1;
+        
+        return this._updateSides();
+    },
+    
+    _updateSides : function _updateSides(){
+        var s = this.sides
+        ,   x1 = this.x1,           y1 = this.y1
+        ,   x2 = this.x2,           y2 = this.y2
+        ,   dx1 = x1 !== s.top.x1,  dy1 = y1 !== s.top.y1
+        ,   dx2 = x2 !== s.top.x2,  dy2 = y2 !== s.left.y2
+        ;
+        
+        if ( dx1 || dy1 ) this.p1 = new Vec(x1,y1);
+        if ( dx2 || dy2 ) this.p2 = new Vec(x2,y2);
+        
+        if ( dx1 || dy1 || dx2 ) s.top    = new Line(x1,y1, x2,y1);
+        if ( dx1 || dx2 || dy2 ) s.bottom = new Line(x1,y2, x2,y2);
+        if ( dx1 || dy1 || dy2 ) s.left   = new Line(x1,y1, x1,y2);
+        if ( dy1 || dy2 || dx2 ) s.right  = new Line(x2,y1, x2,y2);
+        
+        return this;
+    },
+    
+    attr : Y.attr.methodize(),
+    
+    add : function add(x,y){
+        return new BoundingBox(x,y, x+this.width,y+this.height);
+    },
+    
+    resize : function resize(w,h){
+        var x = this.x, y = this.y;
+        return new BoundingBox(x,y, x+w,y+h);
+    },
+    
+    clone : function clone(){
+        return new BoundingBox( this.p1.clone(), this.p2.clone() );
+    }
+    
+});
diff --git a/src/ezl/loc/index.cjs b/src/ezl/loc/index.cjs
new file mode 100644 (file)
index 0000000..c3f9253
--- /dev/null
@@ -0,0 +1,7 @@
+var Y = require('Y').Y;
+
+Y.extend(exports, {
+    'Loc'         : require('ezl/loc/loc').Loc,
+    'BoundingBox' : require('ezl/loc/boundingbox').BoundingBox,
+    'Square'      : require('ezl/loc/square').Square
+});
diff --git a/src/ezl/loc/loc.cjs b/src/ezl/loc/loc.cjs
new file mode 100644 (file)
index 0000000..edd623c
--- /dev/null
@@ -0,0 +1,114 @@
+var Y = require('Y').Y
+,   Vec = require('ezl/math/vec').Vec
+
+,   PI             = Math.PI
+,   QUARTER_PI     = PI/4
+,   HALF_PI        = PI/2
+,   PI_AND_HALF    = PI + HALF_PI
+,   TWO_PI         = PI*2
+,
+
+
+Loc =
+exports['Loc'] =
+Y.subclass('Loc', new Vec(0,0), {
+    
+    // init : function init(x,y){
+    //     Vec.init.call(this, x,y);
+    // },
+    
+    set : function set(k, v, def){
+        v = (v !== undefined ? v : def);
+        switch (k) {
+            case 'x': case 0:
+                this.x = this[0] = v; break;
+            case 'y': case 1:
+                this.y = this[1] = v; break;
+            default:
+                this[k] = v;
+        }
+        return this;
+    },
+    attr : Y.attr.methodize(),
+    
+    clone : function clone(){
+        return new Loc(this.x, this.y);
+    },
+    
+    moveBy : function moveBy(x,y){
+        return new Loc(this.x+x, this.y+y);
+    },
+    
+    moveByAngle : function moveByAngle(theta, v){
+        var x = this.x + v*Math.cos(theta)
+        ,   y = this.y + v*Math.sin(theta);
+        return new Loc(x,y);
+    },
+    
+    moveByDir : function moveByDir(dir, v){
+        return this.moveByAngle( Loc.dirToAngle(dir), v );
+    },
+    
+    toSquare : function toSquare(){
+        return Loc.Square.fromLoc(this.x, this.y);
+    },
+    
+    /**
+     * Converts relative locations like ('50%','50%') to a numeric location.
+     */
+    absolute : function absolute(w,h){
+        var x = this.x, y = this.y
+        return new Loc( Y.isString(x) ? parseFloat(x.slice(0,-1))/100 * w : x
+                      , Y.isString(y) ? parseFloat(y.slice(0,-1))/100 * h : y );
+    },
+    
+    toUnits : function toUnits(units){
+        units = units || 'px';
+        var x = this.x, y = this.y;
+        return { 'x' : Y.isNumber(x) ? x+units : x
+               , 'y' : Y.isNumber(y) ? y+units : y };
+    },
+    
+    toString : function toString(){
+        var x = this.x, y = this.y;
+        x = Y.isNumber(x) ? x.toFixed(2) : x;
+        y = Y.isNumber(y) ? y.toFixed(2) : y;
+        return '('+x+','+y+')';
+    }
+    
+});
+Y(Loc).extend({
+    UP    : 'up',    DOWN : 'down',
+    RIGHT : 'right', LEFT : 'left',
+    
+    UP_RIGHT   : 'right up',   UP_LEFT   : 'left up',
+    DOWN_RIGHT : 'down right', DOWN_LEFT : 'down left',
+    
+    dirToAngle : function dirToAngle(dir){
+        switch (dir) {
+            case Loc.RIGHT:         return 0;
+            case Loc.DOWN_RIGHT:    return QUARTER_PI;
+            case Loc.DOWN:          return HALF_PI;
+            case Loc.DOWN_LEFT:     return HALF_PI+QUARTER_PI;
+            case Loc.LEFT:          return PI;
+            case Loc.UP_LEFT:       return PI+QUARTER_PI;
+            case Loc.UP:            return PI_AND_HALF;
+            case Loc.UP_RIGHT:      return PI_AND_HALF+QUARTER_PI;
+            
+            default: throw new Error("wtf direction is "+dir+"??");
+        }
+    },
+    
+    fromSquare : function fromSquare(col, row){
+        return new Loc(
+            col * REF_SIZE,
+            row * REF_SIZE );
+    },
+    
+    // XXX: Probably wrong for negative locations
+    centerInSquare : function centerInSquare(v){
+        return Math.floor(v/REF_SIZE)*REF_SIZE + REF_SIZE/2;
+    }
+    
+});
+
diff --git a/src/ezl/loc/square.cjs b/src/ezl/loc/square.cjs
new file mode 100644 (file)
index 0000000..e91bc85
--- /dev/null
@@ -0,0 +1,40 @@
+var Loc = require('ezl/loc/loc').Loc
+,   BoundingBox = require('ezl/loc/boundingbox').BoundingBox
+,
+
+
+Square =
+exports['Square'] =
+BoundingBox.subclass('Square', {
+    init : function init(col, row){
+        this.col = col;
+        this.row = row;
+        
+        var x1 = col * REF_SIZE,   y1 = row * REF_SIZE
+        ,   x2 = x1  + REF_SIZE,   y2 = y1  + REF_SIZE
+        ;
+        
+        BoundingBox.init.call(this, x1,y1, x2,y2);
+    },
+    
+    clone : function clone(){
+        return new Square(this.col, this.row);
+    },
+    
+    toLoc : function toLoc(){
+        return Loc.fromSquare(this.col, this.row);
+    },
+    
+    toString : function toString(){
+        return this.col+'_'+this.row;
+    }
+    
+});
+
+// XXX: Negative grid positions don't round correctly
+Square.fromLoc = function(x, y){
+    return new Square(
+        Math.floor(x / REF_SIZE),
+        Math.floor(y / REF_SIZE) );
+};
+
similarity index 92%
rename from src/ezl/loop/cooldown.js
rename to src/ezl/loop/cooldown.cjs
index 1a61a37..ae6961c 100644 (file)
@@ -1,4 +1,9 @@
-Cooldown = Y.subclass('Cooldown', {
+var Y = require('Y').Y
+,
+
+Cooldown =
+exports['Cooldown'] =
+Y.subclass('Cooldown', {
     'init' : function(cooldown, isReady){
         this.cooldown = cooldown; // ms
         this.ready    = isReady || true;
similarity index 87%
rename from src/ezl/loop/eventloop.js
rename to src/ezl/loop/eventloop.cjs
index 84b8325..783a03c 100644 (file)
@@ -1,19 +1,9 @@
-(function(){
+var Y = require('Y').Y
+,   Emitter = require('Y/modules/y.event').Emitter
 
-function add(a,b){ return a+b; }
-
-function decorate(delegate){
-    if (!delegate) return;
-    Y.event.Emitter.prototype.decorate.call(this, delegate);
-    'start stop reset'.split(' ').forEach(function(k){
-        delegate[k] = methods[k].bind(this);
-    }, this);
-    return delegate;
-}
-
-var
-MIN_TICK_INTERVAL = 0, // ms
-NUM_SAMPLES = 33,
+,   MIN_TICK_INTERVAL = 0 // ms
+,   NUM_SAMPLES = 33
+,
 
 methods = {
     // framerate : 0, // Target framerate
@@ -30,7 +20,7 @@ methods = {
     
     
     init : function init(target, framerate, samples){
-        Y.event.Emitter.init.call(this, target);
+        Emitter.init.call(this, target);
         decorate.call(this, target);
         this.tick = this.tick.bind(this);
         this.decorate = decorate.bind(this);
@@ -116,7 +106,22 @@ methods = {
         return (this.realtimes.reduce(Y.op.add,0) / this.realtimes.length);
     }
     
-};
-this.EventLoop = new Y.Class('EventLoop', Y.event.Emitter, methods);
+}, 
+
+EventLoop =
+exports['EventLoop'] =
+Emitter.subclass('EventLoop', methods)
+;
+
+function decorate(delegate){
+    if (!delegate) return;
+    Emitter.prototype.decorate.call(this, delegate);
+    ['start', 'stop', 'reset']
+        .forEach(function(k){
+            delegate[k] = methods[k].bind(this);
+        }, this);
+    return delegate;
+}
+
 
 })();
similarity index 92%
rename from src/ezl/loop/fps.js
rename to src/ezl/loop/fps.cjs
index 9038237..7729159 100644 (file)
@@ -1,6 +1,13 @@
-FpsSparkline = Y.subclass('FpsSparkline', {
+//@require('jquery')
+//@require('jquery.sparkline.min')
+var Y = require('Y').Y
+,
+
+FpsSparkline =
+exports['FpsSparkline'] =
+Y.subclass('FpsSparkline', {
     
-    init : function init(loop, el, w,h, maxBuffer, interval){
+    init : function initFpsSparkline(loop, el, w,h, maxBuffer, interval){
         this.buffer    = [];
         
         this.el        = el;
diff --git a/src/ezl/loop/index.cjs b/src/ezl/loop/index.cjs
new file mode 100644 (file)
index 0000000..cd02e22
--- /dev/null
@@ -0,0 +1,7 @@
+var Y = require('Y').Y;
+
+Y.extend(exports, {
+    'EventLoop'    : require('ezl/loop/eventloop').EventLoop,
+    'Cooldown'     : require('ezl/loop/cooldown').Cooldown,
+    'FpsSparkline' : require('ezl/loop/fps').FpsSparkline
+});
diff --git a/src/ezl/math/index.cjs b/src/ezl/math/index.cjs
new file mode 100644 (file)
index 0000000..76587b5
--- /dev/null
@@ -0,0 +1,27 @@
+var Y = require('Y').Y
+,   Vec = require('ezl/math/vec').Vec
+;
+
+Y(exports, {
+    'Vec'  : Vec,
+    'Line' : require('ezl/math/line').Line,
+    'Rect' : require('ezl/math/rect').Rect,
+    
+    'clamp' : function clamp(value, min, max) {
+      return Math.min(Math.max(value, min), max);
+    },
+    
+    'lerp' : function lerp(x, a, b) {
+        return a + x*(b - a);
+    },
+    
+    'reflect' : function reflect(v, line){
+        var dot   = Vec.dot
+        ,   basev = Vec.difference(v, line.p1);
+        return line.vec()
+            .scale(2 * dot(basev,line) / dot(line,line))
+            .subtract(basev)
+            .add(line.p1);
+    }
+    
+});
similarity index 70%
rename from src/ezl/math/line.js
rename to src/ezl/math/line.cjs
index 3224e41..bdf54ee 100644 (file)
@@ -1,16 +1,16 @@
-(function(){
-
-var
-Vec = math.Vec,
-HALF_PI = Math.PI/2,
-SIN_HALF_PI = Math.sin(HALF_PI),
-COS_HALF_PI = Math.cos(HALF_PI);
-
-
 /**
  * A line in the cartesian plane.
  */
-math.Line = math.Vec.subclass('Line', {
+
+var Vec         = require('ezl/math/vec').Vec
+,   HALF_PI     = Math.PI/2
+,   SIN_HALF_PI = Math.sin(HALF_PI)
+,   COS_HALF_PI = Math.cos(HALF_PI)
+,
+
+Line =
+exports['Line'] =
+Vec.subclass('Line', {
     
     init : function initLine(x1,y1, x2,y2, tdist){
         this.x1 = x1; this.y1 = y1;
@@ -23,10 +23,10 @@ math.Line = math.Vec.subclass('Line', {
         ,   yi = this.yint   = -x1*m + y1
         ,   xi = this.xint   = -y1/m + x1
         ;
-        math.Vec.init.call(this, x0,y0);
+        Vec.init.call(this, x0,y0);
         
-        this.p1 = new math.Vec(x1,y1);
-        this.p2 = new math.Vec(x2,y2);
+        this.p1 = new Vec(x1,y1);
+        this.p2 = new Vec(x2,y2);
         
         this.theta = Math.atan2(y0, x0);
         this._cos  = Math.cos(this.theta);
@@ -36,7 +36,7 @@ math.Line = math.Vec.subclass('Line', {
     },
     
     clone : function clone(){
-        return new math.Line(this.x1,this.y1, this.x2,this.y2, this.tdist);
+        return new Line(this.x1,this.y1, this.x2,this.y2, this.tdist);
     },
     
     
@@ -55,17 +55,17 @@ math.Line = math.Vec.subclass('Line', {
     },
     
     parametric : function parametric(t){
-        return new math.Vec( this.x1 + t*this.pa ,
-                             this.y1 + t*this.pb );
+        return new Vec( this.x1 + t*this.pa ,
+                        this.y1 + t*this.pb );
     },
     
     iparametric : function iparametric(x,y){
-        return new math.Vec( (x-this.x1)/this.pa ,
-                             (y-this.y1)/this.pa );
+        return new Vec( (x-this.x1)/this.pa ,
+                        (y-this.y1)/this.pa );
     },
     
-    pointAtX : function pointAtX(x){ return new math.Vec(x, this.calcY(x)); },
-    pointAtY : function pointAtY(y){ return new math.Vec(this.calcX(y), y); },
+    pointAtX : function pointAtX(x){ return new Vec(x, this.calcY(x)); },
+    pointAtY : function pointAtY(y){ return new Vec(this.calcX(y), y); },
     calcY : function calcY(x){ return (x !== this.xint ? x*this.slope + this.yint : 0); },
     calcX : function calcX(y){ return (y !== this.yint ? y/this.slope + this.xint : 0); },
     
@@ -86,10 +86,10 @@ math.Line = math.Vec.subclass('Line', {
     
     intersects : function intersects(x,y){
         var o = x;
-        if (o instanceof math.Line)
+        if (o instanceof Line)
             return this.slope !== o.slope || this.equals(o);
         
-        if (o instanceof math.Vec) {
+        if (o instanceof Vec) {
             x = o.x;
             y = o.y;
         }
@@ -108,12 +108,12 @@ math.Line = math.Vec.subclass('Line', {
     
     
     vec : function vec(){
-        return new math.Vec(this.x, this.y); // reset to vector from origin
+        return new Vec(this.x, this.y); // reset to vector from origin
     },
     
     base : function base(){
         if (!this._base)
-            this._base = new math.Line(0,0, this.x,this.y);
+            this._base = new Line(0,0, this.x,this.y);
         return this._base;
     },
     
@@ -121,15 +121,15 @@ math.Line = math.Vec.subclass('Line', {
         var slope = this.slope;
         
         if ( slope === 0 )
-            return new math.Line(at.x,at.y, at.x,at.y+1, this.tdist);
+            return new Line(at.x,at.y, at.x,at.y+1, this.tdist);
         
         if ( !isFinite(slope) )
-            return new math.Line(at.x,at.y, at.x+1,at.y, this.tdist);
+            return new Line(at.x,at.y, at.x+1,at.y, this.tdist);
         
         var x1 = at.x, y1 = at.y
         ,   x2 = at.x - at.y + (at.y !== this.y1 ? this.y1 : this.y2)
         ,   y2 = at.y + at.x - (at.x !== this.x1 ? this.x1 : this.x2) ;
-        return new math.Line(x1,y1, x2,y2, this.tdist);
+        return new Line(x1,y1, x2,y2, this.tdist);
     },
     
     toString : function toString(){
@@ -137,5 +137,3 @@ math.Line = math.Vec.subclass('Line', {
     }
     
 });
-
-})();
\ No newline at end of file
diff --git a/src/ezl/math/math.js b/src/ezl/math/math.js
deleted file mode 100644 (file)
index 882cdbb..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-math = {
-    clamp : function clamp(value, min, max) {
-      return Math.min(Math.max(value, min), max);
-    },
-    
-    lerp : function lerp(x, a, b) {
-        return a + x*(b - a);
-    },
-    
-    reflect : function reflect(v, line){
-        var dot   = math.Vec.dot
-        ,   basev = math.Vec.difference(v, line.p1);
-        return line.vec()
-            .scale(2 * dot(basev,line) / dot(line,line))
-            .subtract(basev)
-            .add(line.p1);
-    }
-    
-};
\ No newline at end of file
index e69de29..6f278e2 100644 (file)
@@ -0,0 +1,62 @@
+var Vec = require('ezl/math/vec').Vec
+,
+
+Rect =
+exports['Rect'] =
+Y.subclass('Rect', [], {
+    
+    init : function initRect(x1,y1, x2,y2){
+        if (x1 instanceof Array && y1 instanceof Array) {
+            y2 = y1[1]; x2 = y1[0];
+            y1 = x1[1]; x1 = x1[0];
+        }
+    // init : function initRect(_x1,_y1, _x2,_y2){
+    //     if (_x1 instanceof Array && _y1 instanceof Array) {
+    //         _y2 = _y1[1]; _x2 = _y1[0];
+    //         _y1 = _x1[1]; _x1 = _x1[0];
+    //     }
+    //     var x1 = Math.min(_x1,_x2), x2 = Math.max(_x1,_x2)
+    //     ,   y1 = Math.min(_y1,_y2), y2 = Math.max(_y1,_y2);
+        
+        this.length = 4;
+        this.x1 = this[0] = this.x = x1;
+        this.y1 = this[1] = this.y = y1;
+        this.x2 = this[2] = x2;
+        this.y2 = this[3] = y2;
+        
+        this.width  = x2 - x1;
+        this.height = y2 - y1;
+        
+        this.p1 = new Vec(x1,y1);
+        this.p2 = new Vec(x2,y2);
+    },
+    
+    contains : function contains(x,y){
+        return ( x >= this.x1 && x <= this.x2  &&
+                 y >= this.y1 && y <= this.y2  );
+    },
+    
+    intersects : function intersects(line){
+        var x1 = Math.min(this.x1,this.x2), x2 = Math.max(this.x1,this.x2)
+        ,   y1 = Math.min(this.y1,this.y2), y2 = Math.max(this.y1,this.y2)
+        ,   cx1,cy1, cx2,cy2 ;
+        return (  ( (cx1 = line.calcX(y1)) >= x1 && cx1 <= x2 )
+               || ( (cy1 = line.calcY(x1)) >= y1 && cy1 <= y2 )
+               || ( (cx2 = line.calcX(y2)) >= x1 && cx2 <= x2 )
+               || ( (cy2 = line.calcY(x2)) >= y1 && cy2 <= y2 ) );
+    },
+    
+    midpoint : function midpoint(){
+        return new Vec( this.x1 + this.width /2
+                      , this.y1 + this.height/2 );
+    },
+    
+    clone : function clone(){
+        return new Rect( this.p1.clone()
+                       , this.p2.clone() );
+    },
+    
+    toString : function toString(){
+        return '['+this.p1+' '+this.p2+']';
+    }
+});
similarity index 78%
rename from src/ezl/math/vec.js
rename to src/ezl/math/vec.cjs
index d0035a0..68c9844 100644 (file)
@@ -1,7 +1,9 @@
 /**
  * A 2-dimensional vector.
  */
-math.Vec = new Y.Class('Vec', [], {
+var Vec =
+exports['Vec'] =
+new Y.Class('Vec', [], {
     
     init : function init(x, y){
         this.length = 2;
@@ -17,7 +19,7 @@ math.Vec = new Y.Class('Vec', [], {
     },
     
     clone : function clone(){
-        return new math.Vec(this.x, this.y);
+        return new Vec(this.x, this.y);
     },
     
     setXY : function setXY(x,y){
@@ -65,7 +67,7 @@ math.Vec = new Y.Class('Vec', [], {
     },
     
     manhattan: function manhattan(x2,y2) {
-        if (x2 instanceof math.Vec) {
+        if (x2 instanceof Vec) {
             y2 = x2.y; x2 = x2.x;
         }
         var d1 = Math.abs(x2 - this.x)
@@ -89,13 +91,13 @@ math.Vec = new Y.Class('Vec', [], {
     
 });
 
-Y.extend(math.Vec, {
+Y.extend(Vec, {
     sum : function sum(a, b) {
-        return new math.Vec(a.x+b.x, a.y+b.y);
+        return new Vec(a.x+b.x, a.y+b.y);
     },
     
     difference : function difference(a, b) {
-        return new math.Vec(a.x-b.x, a.y-b.y);
+        return new Vec(a.x-b.x, a.y-b.y);
     },
     
     dot : function dot(a, b) {
@@ -103,22 +105,10 @@ Y.extend(math.Vec, {
     },
     
     lerp : function lerp(x, a, b) {
-        return new math.Vec( math.lerp(a.x, b.x, x),
-                             math.lerp(a.y, b.y, x)  );
+        return new Vec( math.lerp(a.x, b.x, x),
+                        math.lerp(a.y, b.y, x)  );
     },
     
-    // manhattan: function manhattan(p1, p2) {
-    //     var d1 = Math.abs(p2.x - p1.x)
-    //     ,   d2 = Math.abs(p2.y - p1.y) ;
-    //     return d1 + d2;
-    // },
-    
-    // manhattan4: function manhattan4(x1,y1, x2,y2) {
-    //     var d1 = Math.abs(x2 - x1)
-    //     ,   d2 = Math.abs(y2 - y1) ;
-    //     return d1 + d2;
-    // },
-    
     manhattan: function manhattan(x1,y1, x2,y2) {
         if (x1 instanceof Array && y1 instanceof Array) {
             y2 = y1[1]; x2 = y1[0];
@@ -127,7 +117,6 @@ Y.extend(math.Vec, {
         var d1 = Math.abs(x2 - x1)
         ,   d2 = Math.abs(y2 - y1) ;
         return d1 + d2;
-    },
-    
+    }
     
 });
similarity index 92%
rename from src/ezl/shape/circle.js
rename to src/ezl/shape/circle.cjs
index 16c9c6a..4f28285 100644 (file)
@@ -1,6 +1,6 @@
 
 Circle = new Y.Class('Circle', Shape, {
-    _cssClasses : 'portal layer shape circle',
+    _cssClasses : 'ezl layer shape circle',
     
     init : function initCircle(radius, centerTL){
         Layer.init.call(this);
diff --git a/src/ezl/shape/index.cjs b/src/ezl/shape/index.cjs
new file mode 100644 (file)
index 0000000..79b499a
--- /dev/null
@@ -0,0 +1,11 @@
+exports['Shape']    = require('ezl/shape/shape').Shape;
+exports['Rect']     = require('ezl/shape/rect').Rect;
+exports['Circle']   = require('ezl/shape/circle').Circle;
+exports['Line']     = require('ezl/shape/line').Line;
+
+var polygon         = require('ezl/shape/polygon');
+exports['Polygon']  = polygon.Polygon;
+exports['Triangle'] = polygon.Triangle;
+exports['Quad']     = polygon.Quad;
+
+
similarity index 98%
rename from src/ezl/shape/line.js
rename to src/ezl/shape/line.cjs
index 504037a..956b521 100644 (file)
@@ -1,6 +1,6 @@
 
 Line = new Y.Class('Line', Shape, {
-    _cssClasses : 'portal layer shape line',
+    _cssClasses : 'ezl layer shape line',
     
     useCanvasScaling : true,
     fillStyle   : 'transparent',
similarity index 74%
rename from src/ezl/shape/polygon.js
rename to src/ezl/shape/polygon.cjs
index a2cf377..80254fb 100644 (file)
@@ -1,6 +1,12 @@
+var Y     = require('Y').Y
+,   Shape = require('ezl/shape/shape').Shape
+,   Loc   = require('ezl/loc').Loc
+,
 
-Polygon = new Y.Class('Polygon', Shape, {
-    _cssClasses : 'portal layer shape polygon',
+Polygon =
+exports['Polygon'] =
+Shape.subclass('Polygon', {
+    _cssClasses : 'ezl layer shape polygon',
     
     /**
      * Expects two arrays of coordinate-halfs, which could be zipped
@@ -8,7 +14,7 @@ Polygon = new Y.Class('Polygon', Shape, {
      * x0 and y0 will always be 0.
      */
     init : function initPolygon(xs, ys){
-        Layer.init.call(this);
+        Shape.init.call(this);
         
         var xs = this._calcDimension('x', xs)
         ,   ys = this._calcDimension('y', ys)
@@ -17,8 +23,7 @@ Polygon = new Y.Class('Polygon', Shape, {
         ;
         
         this.points = Y(xs).zip(ys).map(Loc.instantiate, Loc);
-        this.width(w)
-            .height(h);
+        this.width(w).height(h);
             // .origin(w/2, h/2);
     },
     
@@ -28,11 +33,14 @@ Polygon = new Y.Class('Polygon', Shape, {
         });
         ctx.fill();
     }
-});
+})
+,
 
 
-Triangle = new Y.Class('Triangle', Polygon, {
-    _cssClasses : 'portal layer shape polygon triangle',
+Triangle =
+exports['Triangle'] =
+Polygon.subclass('Triangle', {
+    _cssClasses : 'ezl layer shape polygon triangle',
     
     init : function initTriangle(x1,y1, x2,y2){
         Polygon.init.call(this, [x1,x2], [y1,y2]);
@@ -51,13 +59,17 @@ Triangle = new Y.Class('Triangle', Polygon, {
                , 'y' : offY + (x1*C - x2*B)/D * -1 // fix inverted Y-axis
                };
     },
-});
+})
+,
 
-Quad = new Y.Class('Quad', Polygon, {
-    _cssClasses : 'portal layer shape polygon quad',
+Quad =
+exports['Quad'] =
+Polygon.subclass('Quad', {
+    _cssClasses : 'ezl layer shape polygon quad',
     
     init : function initQuad(x1,y1, x2,y2, x3,y3){
         Polygon.init.call(this, [x1,x2,x3], [y1,y2,y3]);
     }
     
-});
+})
+;
similarity index 74%
rename from src/ezl/shape/rect.js
rename to src/ezl/shape/rect.cjs
index ea8ca8c..b61641b 100644 (file)
@@ -1,12 +1,14 @@
+var Shape = require('ezl/shape').Shape
+,
 
-Rect = Shape.subclass('Rect', {
-    _cssClasses : 'portal layer shape rect',
+Rect =
+exports['Rect'] =
+Shape.subclass('Rect', {
+    _cssClasses : 'ezl layer shape rect',
     
     init : function initRect(w,h){
-        Layer.init.call(this);
-        
-        this.width(w)
-            .height(h);
+        Shape.init.call(this);
+        this.width(w).height(h);
             // .origin(w/2, h/2);
     },
     
@@ -25,4 +27,4 @@ Rect = Shape.subclass('Rect', {
 });
 Rect.fromPoints = function(x1,y1, x2,y2){
     return new Rect(x2-x1, y2-y1).position(x1,y1);
-};
\ No newline at end of file
+};
similarity index 93%
rename from src/ezl/shape/shape.js
rename to src/ezl/shape/shape.cjs
index 609a74a..7b24a8d 100644 (file)
@@ -1,5 +1,5 @@
 Shape = new Y.Class('Shape', Layer, {
-    _cssClasses : 'portal layer shape',
+    _cssClasses : 'ezl layer shape',
     fillStyle   : 'rgba(231,48,117, 1)',
     strokeStyle : 'transparent',
     lineWidth   : 0,
diff --git a/src/ezl/util/astar.cjs b/src/ezl/util/astar.cjs
new file mode 100644 (file)
index 0000000..08e9885
--- /dev/null
@@ -0,0 +1,137 @@
+/*  astar.js http://github.com/bgrins/javascript-astar
+    MIT License
+    
+    Modified by David Schoonover -- dsc@less.ly
+    
+    Implements the astar search algorithm in javascript using a binary heap
+    **Requires graph.js**
+
+    Example Usage:
+        var graph = new Graph([
+            [0,0,0,0],
+            [1,0,0,1],
+            [1,1,0,0]
+        ]);
+        var start = graph.nodes[0][0];
+        var end = graph.nodes[1][2];
+        astar.search(graph.nodes, start, end);
+*/
+var BinaryHeap = require('ezl/util/binaryheap').BinaryHeap;
+
+exports['init'] = init;
+function init(grid) {
+    // var copy = [];
+    for(var x = 0, xl = grid.length; x < xl; x++) {
+        var yl = grid[x].length;
+        // copy[x] = new Array(yl);
+        for(var y = 0; y < yl; y++) {
+            // var node = grid[x][y].clone();
+            var node = grid[x][y];
+            node.f = 0;
+            node.g = 0;
+            node.h = 0;
+            node.visited = false;
+            node.closed = false;
+            node.parent = null;
+            // copy[x][y] = node;
+        }
+    }
+    // return copy;
+}
+
+exports['search'] = search;
+function search(grid, start, end, heuristic, ignore) {
+    init(grid);
+    heuristic = heuristic || manhattan;
+    
+    ignore = ignore || [];
+    ignore.push(start.value);
+    ignore.push(end.value);
+    
+    var open = new BinaryHeap('f');
+    open.push(start);
+    
+    while( open.length > 0 ) {
+        
+        // Grab the lowest f(x) to process next.  Heap keeps this sorted for us.
+        var current = open.pop();
+        
+        // End case -- result has been found, return the traced path
+        if(current === end) {
+            var path = []
+            ,   node = current;
+            while( node.parent ) {
+                path.push( node.clone() );
+                node = node.parent;
+            }
+            return path.reverse();
+        }
+        
+        // Normal case -- move current from open to closed, process each of its neighbors
+        current.closed = true;
+        
+        var neighbors = getNeighbors(grid, current);
+        for(var i=0, il = neighbors.length; i < il; i++) {
+            var neighbor = neighbors[i];
+            
+            // blocker
+            if( neighbor.closed || (neighbor.blocked && ignore.indexOf(neighbor.value) === -1) )
+                continue;
+            
+            // g score is the shortest distance from start to current node, we need to check if
+            //   the path we have arrived at this neighbor is the shortest one we have seen yet.
+            // We define the distance from a node to it's neighbor as 1, but this could be variable for weighted paths.
+            var g = current.g + 1;
+            
+            if( !neighbor.visited || g < neighbor.g ) {
+                
+                // Found an optimal (so far) path to this node.  Take score for node to see how good it is.
+                neighbor.parent = current;
+                neighbor.h = neighbor.h || heuristic(neighbor, end);
+                neighbor.g = g;
+                neighbor.f = g + neighbor.h;
+                
+                // New? Add to the set of nodes to process
+                if ( !neighbor.visited ) {
+                    neighbor.visited = true;
+                    open.push(neighbor);
+                
+                // Seen, but since it has been rescored we need to reorder it in the heap
+                } else
+                    open.rescore(neighbor);
+            }
+        }
+    }
+    
+    // No result was found -- empty array signifies failure to find path
+    return [];
+}
+
+exports['manhattan'] = manhattan;
+function manhattan(p1, p2) {
+    // See list of heuristics: http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
+    var d1 = Math.abs(p2.x - p1.x)
+    ,   d2 = Math.abs(p2.y - p1.y) ;
+    return d1 + d2;
+}
+
+exports['getNeighbors'] = getNeighbors;
+function getNeighbors(grid, node) {
+    var ret = [];
+    var x = node.x;
+    var y = node.y;
+    
+    if(grid[x-1] && grid[x-1][y]) {
+        ret.push(grid[x-1][y]);
+    }
+    if(grid[x+1] && grid[x+1][y]) {
+        ret.push(grid[x+1][y]);
+    }
+    if(grid[x] && grid[x][y-1]) {
+        ret.push(grid[x][y-1]);
+    }
+    if(grid[x] && grid[x][y+1]) {
+        ret.push(grid[x][y+1]);
+    }
+    return ret;
+}
diff --git a/src/ezl/util/astar.js b/src/ezl/util/astar.js
deleted file mode 100644 (file)
index 78f89ed..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/*  astar.js http://github.com/bgrins/javascript-astar
-    MIT License
-    
-    Implements the astar search algorithm in javascript using a binary heap
-    **Requires graph.js**
-
-    Example Usage:
-        var graph = new Graph([
-            [0,0,0,0],
-            [1,0,0,1],
-            [1,1,0,0]
-        ]);
-        var start = graph.nodes[0][0];
-        var end = graph.nodes[1][2];
-        astar.search(graph.nodes, start, end);
-*/
-
-var astar = {
-    
-    init: function initAStar(grid) {
-        // var copy = [];
-        for(var x = 0, xl = grid.length; x < xl; x++) {
-            var yl = grid[x].length;
-            // copy[x] = new Array(yl);
-            for(var y = 0; y < yl; y++) {
-                // var node = grid[x][y].clone();
-                var node = grid[x][y];
-                node.f = 0;
-                node.g = 0;
-                node.h = 0;
-                node.visited = false;
-                node.closed = false;
-                node.parent = null;
-                // copy[x][y] = node;
-            }
-        }
-        // return copy;
-    },
-    
-    search: function search(grid, start, end, heuristic, ignore) {
-        astar.init(grid);
-        heuristic = heuristic || astar.manhattan;
-        
-        ignore = ignore || [];
-        ignore.push(start.value);
-        ignore.push(end.value);
-        
-        var open = new BinaryHeap('f');
-        open.push(start);
-        
-        while( open.length > 0 ) {
-            
-            // Grab the lowest f(x) to process next.  Heap keeps this sorted for us.
-            var current = open.pop();
-            
-            // End case -- result has been found, return the traced path
-            if(current === end) {
-                var path = []
-                ,   node = current;
-                while( node.parent ) {
-                    path.push( node.clone() );
-                    node = node.parent;
-                }
-                return path.reverse();
-            }
-            
-            // Normal case -- move current from open to closed, process each of its neighbors
-            current.closed = true;
-            
-            var neighbors = astar.neighbors(grid, current);
-            for(var i=0, il = neighbors.length; i < il; i++) {
-                var neighbor = neighbors[i];
-                
-                // blocker
-                if( neighbor.closed || (neighbor.blocked && ignore.indexOf(neighbor.value) === -1) )
-                    continue;
-                
-                // g score is the shortest distance from start to current node, we need to check if
-                //   the path we have arrived at this neighbor is the shortest one we have seen yet.
-                // We define the distance from a node to it's neighbor as 1, but this could be variable for weighted paths.
-                var g = current.g + 1;
-                
-                if( !neighbor.visited || g < neighbor.g ) {
-                    
-                    // Found an optimal (so far) path to this node.  Take score for node to see how good it is.
-                    neighbor.parent = current;
-                    neighbor.h = neighbor.h || heuristic(neighbor, end);
-                    neighbor.g = g;
-                    neighbor.f = g + neighbor.h;
-                    
-                    // New? Add to the set of nodes to process
-                    if ( !neighbor.visited ) {
-                        neighbor.visited = true;
-                        open.push(neighbor);
-                    
-                    // Seen, but since it has been rescored we need to reorder it in the heap
-                    } else
-                        open.rescore(neighbor);
-                }
-            }
-        }
-        
-        // No result was found -- empty array signifies failure to find path
-        return [];
-    },
-    
-    manhattan: function manhattan(p1, p2) {
-        // See list of heuristics: http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
-        var d1 = Math.abs(p2.x - p1.x)
-        ,   d2 = Math.abs(p2.y - p1.y) ;
-        return d1 + d2;
-    },
-    
-    manhattan4: function manhattan(x1,y1, x2,y2) {
-        // See list of heuristics: http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
-        var d1 = Math.abs(x2 - x1)
-        ,   d2 = Math.abs(y2 - y1) ;
-        return d1 + d2;
-    },
-    
-    neighbors: function neighbors(grid, node) {
-        var ret = [];
-        var x = node.x;
-        var y = node.y;
-        
-        if(grid[x-1] && grid[x-1][y]) {
-            ret.push(grid[x-1][y]);
-        }
-        if(grid[x+1] && grid[x+1][y]) {
-            ret.push(grid[x+1][y]);
-        }
-        if(grid[x] && grid[x][y-1]) {
-            ret.push(grid[x][y-1]);
-        }
-        if(grid[x] && grid[x][y+1]) {
-            ret.push(grid[x][y+1]);
-        }
-        return ret;
-    }
-};
similarity index 98%
rename from src/ezl/util/binaryheap.js
rename to src/ezl/util/binaryheap.cjs
index cfecb3a..9ddb155 100644 (file)
@@ -1,4 +1,3 @@
-(function(){
 
 function BinaryHeap(score){
     if (typeof score === 'string')
@@ -141,6 +140,5 @@ var AP = Array.prototype
 // Add methods to prototype
 for (var k in methods) proto[k] = methods[k];
 
-this.BinaryHeap = BinaryHeap;
+exports['BinaryHeap'] = BinaryHeap;
 
-})();
\ No newline at end of file
similarity index 76%
rename from src/ezl/util/graph.js
rename to src/ezl/util/graph.cjs
index e85dc73..7cef268 100644 (file)
@@ -1,3 +1,6 @@
+var Vec = require('ezl/math/vec').Vec;
+
+exports['Graph'] =
 function Graph(grid) {
     this.grid = grid;
     this.nodes = [];
@@ -6,11 +9,11 @@ function Graph(grid) {
         var row = grid[x];
         this.nodes[x] = [];
         for (var y = 0; y < row.length; y++) {
-            var n = new math.Vec(x,y);
+            var n = new Vec(x,y);
             n.blocked = !!row[y];
             this.nodes[x].push(n);
         }
     }
-}
+};
 
 
similarity index 97%
rename from src/ezl/util/tree/quadtree.js
rename to src/ezl/util/tree/quadtree.cjs
index 5f92556..8ff0636 100644 (file)
@@ -1,31 +1,11 @@
-(function(){
+var CAPACITY  = 8
+,   REGION_ID = 0
+,
 
-function Rect(x1,y1, x2,y2){
-    var sm_x = Math.min(x1,x2), lg_x = Math.max(x1,x2)
-    ,   sm_y = Math.min(y1,y2), lg_y = Math.max(y1,y2);
-    this.x1 = this.x = sm_x;
-    this.y1 = this.y = sm_y;
-    this.x2 = lg_x;
-    this.y2 = lg_y;
-    this.width  = lg_x-sm_x;
-    this.height = lg_y-sm_y;
-}
-function rectToString(o){
-    var p = 2
-    ,   x1 = o.x1, y1 = o.y1
-    ,   x2 = o.x2, y2 = o.y2 ;
-    x1 = ((x1 % 1 !== 0) ? x1.toFixed(p) : x1);
-    y1 = ((y1 % 1 !== 0) ? y1.toFixed(p) : y1);
-    x2 = ((x2 % 1 !== 0) ? x2.toFixed(p) : x2);
-    y2 = ((y2 % 1 !== 0) ? y2.toFixed(p) : y2);
-    return '['+x1+','+y1+', '+x2+','+y2+']';
-}
 
-var
-CAPACITY  = 8,
-REGION_ID = 0,
-
-Region = Y.subclass('Region', {
+Region =
+exports['Region'] =
+Y.subclass('Region', {
     init : function init(x1,y1, x2,y2, value){
         Rect.call(this, x1,y1, x2,y2);
         this.id = REGION_ID++;
@@ -41,9 +21,13 @@ Region = Y.subclass('Region', {
     toString : function toString(){
         return this.className+'(id='+this.id+', rect='+rectToString(this)+', value='+this.value+')';
     }
-}),
+})
+,
+
 
-QuadTree = Y.subclass('QuadTree', {
+QuadTree =
+exports['QuadTree'] =
+Y.subclass('QuadTree', {
     depth    : 0,
     parent   : null,
     regions  : [],
@@ -235,7 +219,26 @@ QuadTree = Y.subclass('QuadTree', {
     }
 });
 
-QuadTree['Region'] = Region;
-this['QuadTree'] = QuadTree;
 
-})();
+
+function Rect(x1,y1, x2,y2){
+    var sm_x = Math.min(x1,x2), lg_x = Math.max(x1,x2)
+    ,   sm_y = Math.min(y1,y2), lg_y = Math.max(y1,y2);
+    this.x1 = this.x = sm_x;
+    this.y1 = this.y = sm_y;
+    this.x2 = lg_x;
+    this.y2 = lg_y;
+    this.width  = lg_x-sm_x;
+    this.height = lg_y-sm_y;
+}
+function rectToString(o){
+    var p = 2
+    ,   x1 = o.x1, y1 = o.y1
+    ,   x2 = o.x2, y2 = o.y2 ;
+    x1 = ((x1 % 1 !== 0) ? x1.toFixed(p) : x1);
+    y1 = ((y1 % 1 !== 0) ? y1.toFixed(p) : y1);
+    x2 = ((x2 % 1 !== 0) ? x2.toFixed(p) : x2);
+    y2 = ((y2 % 1 !== 0) ? y2.toFixed(p) : y2);
+    return '['+x1+','+y1+', '+x2+','+y2+']';
+}
+
similarity index 98%
rename from src/ezl/util/tree/rbtree.js
rename to src/ezl/util/tree/rbtree.cjs
index a5cb4e1..9656ec1 100644 (file)
@@ -1,39 +1,21 @@
-(function(){
-var RED        = "Red"
-,   BLACK      = "Black"
+var RED   = exports['RED']   = "Red"
+,   BLACK = exports['BLACK'] = "Black"
 ,   FLIP_COLOR = {};
+
 FLIP_COLOR[RED]   = BLACK;
 FLIP_COLOR[BLACK] = RED;
 
-
-function isRed(n)   { return n && (n.color == RED); }
-function isBlack(n) { return n && (n.color == BLACK); }
-function size(n)    { return (n && n.N) || 0; }
-
-
-function Node(key, val, color, N) {
-    this.key   = key;
-    this.val   = val;
-    this.color = color;
-    this.N     = N;
-    this.left  = null;
-    this.right = null;
-}
-Node.prototype.toString = function(){
-    var S = (this.color === RED ? '[' : '(')
-    ,   E = (this.color === RED ? ']' : ')');
-    return S+this.key+' '+this.val+E;
-};
-
-var
-RedBlackTree = Y.subclass('RedBlackTree', {
-    init : function init(key, value){
+RedBlackTree =
+exports['RedBlackTree'] =
+Y.subclass('RedBlackTree', {
+    _root : null,
+    
+    
+    init : function initRedBlackTree(key, value){
         if (this.key !== undefined)
             this.setKey(key, value);
     },
     
-    _root : null,
-
    /*************************************************************************
     *  Size methods
     *************************************************************************/
@@ -459,9 +441,23 @@ RedBlackTree = Y.subclass('RedBlackTree', {
 
 });
 
-RedBlackTree['RED']   = RED;
-RedBlackTree['BLACK'] = BLACK;
-RedBlackTree['Node']  = Node;
-this['RedBlackTree']  = RedBlackTree;
+function isRed(n)   { return n && (n.color == RED); }
+function isBlack(n) { return n && (n.color == BLACK); }
+function size(n)    { return (n && n.N) || 0; }
 
-})();
+var
+Node =
+exports['Node'] =
+function Node(key, val, color, N) {
+    this.key   = key;
+    this.val   = val;
+    this.color = color;
+    this.N     = N;
+    this.left  = null;
+    this.right = null;
+};
+Node.prototype.toString = function(){
+    var S = (this.color === RED ? '[' : '(')
+    ,   E = (this.color === RED ? ']' : ')');
+    return S+this.key+' '+this.val+E;
+};
index 2dc4857..12a6989 100644 (file)
@@ -1,5 +1,5 @@
 Level = Rect.subclass('Level', {
-    _cssClasses : 'portal layer level',
+    _cssClasses : 'ezl layer level',
     
     init : function init(game, w,h){
         Rect.init.call(this, w,h);
diff --git a/src/tanks/map/loc/bbox.cjs b/src/tanks/map/loc/bbox.cjs
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/tanks/map/loc/index.cjs b/src/tanks/map/loc/index.cjs
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/tanks/map/loc/loc.cjs b/src/tanks/map/loc/loc.cjs
deleted file mode 100644 (file)
index 3f65d91..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-// [x,y]
-Loc = new Y.Class('Loc', new math.Vec(0,0), {
-    
-    // init : function init(x,y){
-    //     math.Vec.init.call(this, x,y);
-    // },
-    
-    set : function set(k, v, def){
-        v = (v !== undefined ? v : def);
-        switch (k) {
-            case 'x': case 0:
-                this.x = this[0] = v; break;
-            case 'y': case 1:
-                this.y = this[1] = v; break;
-            default:
-                this[k] = v;
-        }
-        return this;
-    },
-    attr : Y.attr.methodize(),
-    
-    clone : function clone(){
-        return new Loc(this.x, this.y);
-    },
-    
-    moveBy : function moveBy(x,y){
-        return new Loc(this.x+x, this.y+y);
-    },
-    
-    moveByAngle : function moveByAngle(theta, v){
-        var x = this.x + v*Math.cos(theta)
-        ,   y = this.y + v*Math.sin(theta);
-        return new Loc(x,y);
-    },
-    
-    moveByDir : function moveByDir(dir, v){
-        return this.moveByAngle( Loc.dirToAngle(dir), v );
-    },
-    
-    toSquare : function toSquare(){
-        return Loc.Square.fromLoc(this.x, this.y);
-    },
-    
-    /**
-     * Converts relative locations like ('50%','50%') to a numeric location.
-     */
-    absolute : function absolute(w,h){
-        var x = this.x, y = this.y
-        return new Loc( Y.isString(x) ? parseFloat(x.slice(0,-1))/100 * w : x
-                      , Y.isString(y) ? parseFloat(y.slice(0,-1))/100 * h : y );
-    },
-    
-    toUnits : function toUnits(units){
-        units = units || 'px';
-        var x = this.x, y = this.y;
-        return { 'x' : Y.isNumber(x) ? x+units : x
-               , 'y' : Y.isNumber(y) ? y+units : y };
-    },
-    
-    toString : function toString(){
-        var x = this.x, y = this.y;
-        x = Y.isNumber(x) ? x.toFixed(2) : x;
-        y = Y.isNumber(y) ? y.toFixed(2) : y;
-        return '('+x+','+y+')';
-    }
-    
-});
-Y(Loc).extend({
-    UP    : 'up',    DOWN : 'down',
-    RIGHT : 'right', LEFT : 'left',
-    
-    UP_RIGHT   : 'right up',   UP_LEFT   : 'left up',
-    DOWN_RIGHT : 'down right', DOWN_LEFT : 'down left',
-    
-    dirToAngle : function dirToAngle(dir){
-        switch (dir) {
-            case Loc.RIGHT:         return 0;
-            case Loc.DOWN_RIGHT:    return QUARTER_PI;
-            case Loc.DOWN:          return HALF_PI;
-            case Loc.DOWN_LEFT:     return HALF_PI+QUARTER_PI;
-            case Loc.LEFT:          return PI;
-            case Loc.UP_LEFT:       return PI+QUARTER_PI;
-            case Loc.UP:            return PI_AND_HALF;
-            case Loc.UP_RIGHT:      return PI_AND_HALF+QUARTER_PI;
-            
-            default: throw new Error("wtf direction is "+dir+"??");
-        }
-    },
-    
-    fromSquare : function fromSquare(col, row){
-        return new Loc(
-            col * REF_SIZE,
-            row * REF_SIZE );
-    },
-    
-    // XXX: Probably wrong for negative locations
-    centerInSquare : function centerInSquare(v){
-        return Math.floor(v/REF_SIZE)*REF_SIZE + REF_SIZE/2;
-    }
-    
-});
-
-// [x1,y1, x2,y2]
-Loc.Rect = new Y.Class('Rect', [], {
-    
-    init : function initRect(x1,y1, x2,y2){
-        if (x1 instanceof Array && y1 instanceof Array) {
-            y2 = y1[1]; x2 = y1[0];
-            y1 = x1[1]; x1 = x1[0];
-        }
-    // init : function initRect(_x1,_y1, _x2,_y2){
-    //     if (_x1 instanceof Array && _y1 instanceof Array) {
-    //         _y2 = _y1[1]; _x2 = _y1[0];
-    //         _y1 = _x1[1]; _x1 = _x1[0];
-    //     }
-    //     var x1 = Math.min(_x1,_x2), x2 = Math.max(_x1,_x2)
-    //     ,   y1 = Math.min(_y1,_y2), y2 = Math.max(_y1,_y2);
-        
-        this.length = 4;
-        this.x1 = this[0] = this.x = x1;
-        this.y1 = this[1] = this.y = y1;
-        this.x2 = this[2] = x2;
-        this.y2 = this[3] = y2;
-        
-        this.width  = x2 - x1;
-        this.height = y2 - y1;
-        
-        this.p1 = new Loc(x1,y1);
-        this.p2 = new Loc(x2,y2);
-    },
-    
-    contains : function contains(x,y){
-        return ( x >= this.x1 && x <= this.x2  &&
-                 y >= this.y1 && y <= this.y2  );
-    },
-    
-    intersects : function intersects(line){
-        var x1 = Math.min(this.x1,this.x2), x2 = Math.max(this.x1,this.x2)
-        ,   y1 = Math.min(this.y1,this.y2), y2 = Math.max(this.y1,this.y2)
-        ,   cx1,cy1, cx2,cy2 ;
-        return (  ( (cx1 = line.calcX(y1)) >= x1 && cx1 <= x2 )
-               || ( (cy1 = line.calcY(x1)) >= y1 && cy1 <= y2 )
-               || ( (cx2 = line.calcX(y2)) >= x1 && cx2 <= x2 )
-               || ( (cy2 = line.calcY(x2)) >= y1 && cy2 <= y2 ) );
-    },
-    
-    midpoint : function midpoint(){
-        return new Loc( this.x1 + this.width /2
-                      , this.y1 + this.height/2 );
-    },
-    
-    clone : function clone(){
-        return new Loc.Rect( this.p1.clone()
-                           , this.p2.clone() );
-    },
-    
-    toString : function toString(){
-        return '['+this.p1+' '+this.p2+']';
-    }
-});
-
-Loc.BoundingBox = Loc.Rect.subclass('BoundingBox', {
-    init : function initBoundingBox(x1,y1, x2,y2){
-        Loc.Rect.init.call(this, x1,y1, x2,y2);
-        
-        this.sides = {
-            top    : new math.Line(x1,y1, x2,y1),
-            bottom : new math.Line(x1,y2, x2,y2),
-            left   : new math.Line(x1,y1, x1,y2),
-            right  : new math.Line(x2,y1, x2,y2)
-        };
-    },
-    
-    set : function set(k, v, def){
-        v = (v !== undefined ? v : def);
-        
-        switch (k) {
-            case 'x1': case 0: case 'x':    this.x1 = this[0] = this.x = v;     break;
-            case 'y1': case 1: case 'y':    this.y1 = this[1] = this.y = v;     break;
-            case 'x2': case 2:              this.x2 = this[2] = v;              break;
-            case 'y1': case 3:              this.y2 = this[3] = v;              break;
-            
-            default: this[k] = v;
-        }
-        
-        this.width  = this.x2 - this.x1;
-        this.height = this.y2 - this.y1;
-        
-        return this._updateSides();
-    },
-    
-    _updateSides : function _updateSides(){
-        var s = this.sides
-        ,   x1 = this.x1,           y1 = this.y1
-        ,   x2 = this.x2,           y2 = this.y2
-        ,   dx1 = x1 !== s.top.x1,  dy1 = y1 !== s.top.y1
-        ,   dx2 = x2 !== s.top.x2,  dy2 = y2 !== s.left.y2
-        ;
-        
-        if ( dx1 || dy1 ) this.p1 = new Loc(x1,y1);
-        if ( dx2 || dy2 ) this.p2 = new Loc(x2,y2);
-        
-        if ( dx1 || dy1 || dx2 ) s.top    = new math.Line(x1,y1, x2,y1);
-        if ( dx1 || dx2 || dy2 ) s.bottom = new math.Line(x1,y2, x2,y2);
-        if ( dx1 || dy1 || dy2 ) s.left   = new math.Line(x1,y1, x1,y2);
-        if ( dy1 || dy2 || dx2 ) s.right  = new math.Line(x2,y1, x2,y2);
-        
-        return this;
-    },
-    
-    attr : Y.attr.methodize(),
-    
-    add : function add(x,y){
-        return new Loc.BoundingBox(x,y, x+this.width,y+this.height);
-    },
-    
-    resize : function resize(w,h){
-        var x = this.x, y = this.y;
-        return new Loc.BoundingBox(x,y, x+w,y+h);
-    },
-    
-    clone : function clone(){
-        return new Loc.BoundingBox( this.p1.clone(), this.p2.clone() );
-    }
-    
-});
-
-Loc.Square = new Y.Class('Square', Loc.BoundingBox, {
-    init : function init(col, row){
-        this.col = col;
-        this.row = row;
-        
-        var x1 = col * REF_SIZE,   y1 = row * REF_SIZE
-        ,   x2 = x1  + REF_SIZE,   y2 = y1  + REF_SIZE
-        ;
-        
-        Loc.Rect.init.call(this, x1,y1, x2,y2);
-    },
-    
-    clone : function clone(){
-        return new Square(this.col, this.row);
-    },
-    
-    toLoc : function toLoc(){
-        return Loc.fromSquare(this.col, this.row);
-    },
-    
-    toString : function toString(){
-        return this.col+'_'+this.row;
-    }
-    
-});
-
-// XXX: Negative grid positions don't round correctly
-Loc.Square.fromLoc = function(x, y){
-    return new Loc.Square(
-        Math.floor(x / REF_SIZE),
-        Math.floor(y / REF_SIZE) );
-};
-
diff --git a/src/tanks/map/loc/rect.cjs b/src/tanks/map/loc/rect.cjs
deleted file mode 100644 (file)
index e69de29..0000000
index a055b95..55c391b 100644 (file)
@@ -1,5 +1,5 @@
 Grid = new Y.Class('Grid', Rect, {
-    _cssClasses : 'portal layer shape rect grid',
+    _cssClasses : 'ezl layer shape rect grid',
     
     lineWidth : 0.5,
     strokeStyle : '#6E6E6E',
index 7809517..e88b37d 100644 (file)
--- a/tanks.php
+++ b/tanks.php
@@ -9,17 +9,18 @@ class Tanks {
     const SRC_AND_LIB = 6; // LIB_SCRIPTS  | SRC_SCRIPTS;
     const ALL_SCRIPTS = 7; // MAIN_SCRIPTS | LIB_SCRIPTS | SRC_SCRIPTS;
     
+    const BUILD_DIR = "build";
     
-    static $mainCJS = array(
-        "src/tanks/ui/main.cjs"
+    static $modules = array(
+        array( "main" => "src/Y/index.cjs", "loader" => "y-loader.js" )
     );
     
+    
+    
     static $mainScripts = array(
         "src/tanks/ui/main.js"
     );
     
-    
-    
     static $srcScripts = array(
         "src/tanks/tanks.js",
         "src/tanks/globals.js",
@@ -93,19 +94,29 @@ class Tanks {
     static function writeTags($scripts=null, $prefix="", $recompile=true) {
         $scripts = $scripts ? $scripts : Tanks::SRC_AND_LIB;
         
-        if ($recompile) Tanks::compile();
-        
         if ($scripts & Tanks::LIB_SCRIPTS)  foreach (self::$libScripts  as $s) js($s, $prefix);
         if ($scripts & Tanks::SRC_SCRIPTS)  foreach (self::$srcScripts  as $s) js($s, $prefix);
         if ($scripts & Tanks::MAIN_SCRIPTS) foreach (self::$mainScripts as $s) js($s, $prefix);
     }
     
-    static function compile($main=null) {
-        $main = ($main ? $main : self::$mainCJS);
-        $scripts = join($main, " ");
-        shell_exec("cjs.py $scripts");
+    static function compile($modules=null) {
+        $modules = ($modules ? $modules : self::$modules);
+        $PYTHONPATH = "PYTHONPATH='/Users/dsc/.python/lib/python:/usr/local/lib/python2.7/site-packages:/usr/local/lib/python2.6/site-packages'";
+        // error_reporting(E_ALL);
+        // echo "<!--";
+        foreach ($modules as $module) {
+            $ret = shell_exec("$PYTHONPATH bin/cjs.py -s {$module['main']} -- src lib 2>&1");
+            echo "    ".trim(join("\n    ", split("\n", $ret)));
+        }
+        // echo "-->";
     }
     
+    static function writeLoaders($modules=null, $recompile=true){
+        $modules = ($modules ? $modules : self::$modules);
+        js('lib/cjs/require.js');
+        if ($recompile) Tanks::compile($modules);
+        // foreach ($modules as $module) js($module['loader'], Tanks::BUILD_DIR."/");
+    }
     
 }