diff options
author | Wilson Page <wilsonpage@me.com> | 2013-08-26 17:53:53 +0100 |
---|---|---|
committer | Wilson Page <wilsonpage@me.com> | 2013-08-26 17:53:53 +0100 |
commit | 5504e35eb21e9e347f8a63d59acd2cc5e7e22478 (patch) | |
tree | 086a63bac10e877d4fbf6e6176690dcfa2d866ea /lib/dom-batch.js | |
parent | 97445e07ae04a76285c954707b3add78f3a88d63 (diff) | |
download | fastdom-5504e35eb21e9e347f8a63d59acd2cc5e7e22478.zip fastdom-5504e35eb21e9e347f8a63d59acd2cc5e7e22478.tar.gz fastdom-5504e35eb21e9e347f8a63d59acd2cc5e7e22478.tar.bz2 |
Re-write
Diffstat (limited to 'lib/dom-batch.js')
-rw-r--r-- | lib/dom-batch.js | 113 |
1 files changed, 78 insertions, 35 deletions
diff --git a/lib/dom-batch.js b/lib/dom-batch.js index 903033e..62e1972 100644 --- a/lib/dom-batch.js +++ b/lib/dom-batch.js @@ -1,38 +1,81 @@ -(function() { - var domBatch = {}; - var reads = []; - var writes = []; - var batch; - - function call(fns) { - var fn; - while (fn = fns.shift()) fn(); - } +function DomBatch() { + this.reads = []; + this.writes = []; - domBatch.read = function(fn) { - batch = batch || setBatch(); - reads.push(fn); - }; - - domBatch.write = function(fn) { - batch = batch || setBatch(); - writes.push(fn); - }; - - function setBatch() { - return setTimeout(function() { - call(reads); - call(writes); - batch = null; - }, 0); - } + this.mode = null; + this.pending = false; + + // Bind context + this.run = this.run.bind(this); + this.frame = this.frame.bind(this); +} + +DomBatch.prototype.read = function(fn) { + this.reads.push(fn); + this.request('read'); +}; + +DomBatch.prototype.write = function(fn) { + this.writes.push(fn); + this.request('write'); +}; + +DomBatch.prototype.request = function(type) { + + // If we are currently writing, we don't + // need to scedule a new frame as this + // job will be emptied from the write queue + if (this.mode === 'writing' && type === 'write') return; + + // If we are reading we don't need to schedule + // a new frame as this read will be emptied + // in the currently active read queue + if (this.mode === 'reading' && type === 'read') return; + + // If we are reading we don't need to schedule + // a new frame and this write job will be run + // after the read queue has been emptied in the + // currently active frame. + if (this.mode === 'reading' && type === 'write') return; - // Expose the library - if (typeof exports === "object") { - module.exports = domBatch; - } else if (typeof define === "function" && define.amd) { - define(domBatch); - } else { - window['domBatch'] = domBatch; + // If there is already a frame + // scheduled, don't schedule another one + if (this.pending) return; + + // Schedule frame + requestAnimationFrame(this.frame); + + // Set flag to indicate + // a frame has been scheduled + this.pending = true; +}; + +DomBatch.prototype.run = function(q) { + while (q.length) { + q.shift().call(this); } -}());
\ No newline at end of file +}; + +// How can a request be made if the +// emptying of the queue is in progress????? + +DomBatch.prototype.frame = function() { + + // Set the pending flag to + // false so that any new requests + // that come in will schedule a new frame + this.pending = false; + + // Set the mode to 'reading' so + // that we know we can add more + // reads to the queue instead of + // scheduling a new frame. + this.mode = 'reading'; + this.run(this.reads); + + // Set + this.mode = 'writing'; + this.run(this.writes); + + this.mode = null; +}; |