[Pkg-javascript-commits] [backbone] 56/281: implement callbacks as linked list

Jonas Smedegaard js at moszumanska.debian.org
Sat May 3 17:01:56 UTC 2014


This is an automated email from the git hooks/post-receive script.

js pushed a commit to tag 0.9.0
in repository backbone.

commit de2430554ee197fdb0645f198fd9bc23214a832c
Author: Brad Dunbar <dunbarb2 at gmail.com>
Date:   Mon Oct 31 07:15:03 2011 -0400

    implement callbacks as linked list
---
 backbone.js    | 46 ++++++++++++++++++++--------------------------
 test/events.js | 26 +++++++++++++++++++-------
 2 files changed, 39 insertions(+), 33 deletions(-)

diff --git a/backbone.js b/backbone.js
index 8e0df5b..74f2a77 100644
--- a/backbone.js
+++ b/backbone.js
@@ -15,6 +15,9 @@
   // Save the previous value of the `Backbone` variable.
   var previousBackbone = root.Backbone;
 
+  // Create a local reference to slice.
+  var slice = Array.prototype.slice;
+
   // The top-level namespace. All public Backbone classes and modules will
   // be attached to this. Exported for both CommonJS and the browser.
   var Backbone;
@@ -70,8 +73,9 @@
     // Passing `"all"` will bind the callback to all events fired.
     bind : function(ev, callback, context) {
       var calls = this._callbacks || (this._callbacks = {});
-      var list  = calls[ev] || (calls[ev] = []);
-      list.push([callback, context]);
+      var list  = calls[ev] || (calls[ev] = {});
+      var tail = list.tail || list;
+      list.tail = tail.next = {callback: callback, context: context};
       return this;
     },
 
@@ -79,20 +83,19 @@
     // callbacks for the event. If `ev` is null, removes all bound callbacks
     // for all events.
     unbind : function(ev, callback) {
-      var calls;
+      var calls, list, node, prev;
       if (!ev) {
         this._callbacks = {};
       } else if (calls = this._callbacks) {
         if (!callback) {
-          calls[ev] = [];
-        } else {
-          var list = calls[ev];
-          if (!list) return this;
-          for (var i = 0, l = list.length; i < l; i++) {
-            if (list[i] && callback === list[i][0]) {
-              list[i] = null;
-              break;
-            }
+          calls[ev] = {};
+        } else if (list = node = calls[ev]) {
+          while (prev = node, node = node.next) {
+            if (node.callback !== callback) continue;
+            prev.next = node.next;
+            if (list.tail === node) list.tail = prev;
+            node.context = node.callback = null;
+            break;
           }
         }
       }
@@ -103,21 +106,12 @@
     // same arguments as `trigger` is, apart from the event name.
     // Listening for `"all"` passes the true event name as the first argument.
     trigger : function(eventName) {
-      var list, calls, ev, callback, args;
-      var both = 2;
+      var node, calls, callback, args, ev, events = ['all', eventName];
       if (!(calls = this._callbacks)) return this;
-      while (both--) {
-        ev = both ? eventName : 'all';
-        if (list = calls[ev]) {
-          for (var i = 0, l = list.length; i < l; i++) {
-            if (!(callback = list[i])) {
-              list.splice(i, 1); i--; l--;
-            } else {
-              args = both ? Array.prototype.slice.call(arguments, 1) : arguments;
-              callback[0].apply(callback[1] || this, args);
-            }
-          }
-        }
+      while (ev = events.pop()) {
+        if (!(node = calls[ev])) continue;
+        args = ev == 'all' ? arguments : slice.call(arguments, 1);
+        while (node = node.next) if (callback = node.callback) callback.apply(node.context || this, args);
       }
       return this;
     }
diff --git a/test/events.js b/test/events.js
index 3b41310..a8235ef 100644
--- a/test/events.js
+++ b/test/events.js
@@ -66,21 +66,33 @@ $(document).ready(function() {
     equals(obj.counterA, 1, 'counterA should have only been incremented once.');
     equals(obj.counterB, 1, 'counterB should have only been incremented once.');
   });
-  
+
   test("Events: bind a callback with a supplied context", function () {
     expect(1);
-    
+
     var TestClass = function () { return this; }
     TestClass.prototype.assertTrue = function () {
       ok(true, '`this` was bound to the callback')
     };
-    
+
     var obj = _.extend({},Backbone.Events);
-    
+
     obj.bind('event', function () { this.assertTrue(); }, (new TestClass));
-    
+
+    obj.trigger('event');
+
+  });
+
+  test("Events: nested trigger with unbind", function () {
+    expect(1);
+    var obj = { counter: 0 };
+    _.extend(obj, Backbone.Events);
+    var incr1 = function(){ obj.counter += 1; obj.unbind('event', incr1); obj.trigger('event'); };
+    var incr2 = function(){ obj.counter += 1; };
+    obj.bind('event', incr1);
+    obj.bind('event', incr2);
     obj.trigger('event');
-    
+    equals(obj.counter, 3, 'counter should have been incremented three times');
   });
 
-});
\ No newline at end of file
+});

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/backbone.git



More information about the Pkg-javascript-commits mailing list