diff --git a/src/async.js b/src/async.js index 025e75df..3553d153 100644 --- a/src/async.js +++ b/src/async.js @@ -1,175 +1,72 @@ -/** - * Util classes - */ +var Animation = Backbone.Model.extend({ + defaults: { + duration: 300, + closure: null + }, -function CommandQueue() { - this.commands = []; - this.consumeTimeout = null; + validateAtInit: function() { + if (!this.get('closure')) { + throw new Error('give me a closure!'); + } + }, - this.initialDelay = 400; -} + initialize: function(options) { + this.validateAtInit(); + }, -CommandQueue.prototype.add = function(command) { - this.commands.push(command); - this.touchTimer(); -}; - -CommandQueue.prototype.touchTimer = function() { - if (this.consumeTimeout) { - return; + run: function() { + this.get('closure')(); } - this.consumeTimeout = setTimeout(_.bind(function() { +}); + +var AnimationQueue = Backbone.Model.extend({ + defaults: { + animations: [], + index: 0, + callback: null + }, + + initialize: function(options) { + if (!options.callback) { + console.warn('no callback'); + } + }, + + add: function(animation) { + if (!animation instanceof Animation) { + throw new Error("Need animation not something else"); + } + + this.get('animations').push(animation); + }, + + start: function() { + this.set('index', 0); this.next(); - }, this), this.initialDelay); -}; + }, -CommandQueue.prototype.reset = function() { - this.consumeTimeout = null; -}; + finish: function() { + this.get('callback')(); + }, -CommandQueue.prototype.next = function() { - if (this.commands.length == 0) { - this.reset(); - return; - } + next: function() { + // ok so call the first animation, and then set a timeout to call the next + // TODO: animations with callbacks!! + var animations = this.get('animations'); + var index = this.get('index'); + if (index >= animations.length) { + this.finish(); + return; + } - // execute the top command by passing it into the engine - var toExecute = this.commands.shift(0); - var callback = _.bind(function() { - this.next(); - }, this); - gitEngine.execute(toExecute, callback); -}; + var next = animations[index]; + var duration = next.get('duration'); + next.run(); - -/****************** - * Planning: - - here is the major flow: - - someone types in a command -> - make a new command object. if error, give immediate feedback, dont append to queue - if not error -> - append command object to queue - - - Command Queue -> - consume commands at a certain rate (either instantly if just added, or with an interval - Execute command -> (usually a git engine thing) - Wait for git engine command to finish - when done, execute next command (if more) - - so two levels of Async-ness: - command queue slowly consumes commands - - GitEngine executes commands, which will have async bits to them (such as popping off commits for a - rebase) -*/ - -function Scheduler(closures, options) { - if (!closures || !closures.length) { - throw new Error('invalid params'); - } - - this.closures = closures; - - this.options = options || {}; - this.interval = this.options.interval || 400; - - this.done = false; - this.timeOut = null; - this.index = 0; -} - -Scheduler.prototype.start = function() { - // set the first interval - this.index = 0; - this.done = false; - this.setNext(); -}; - -Scheduler.prototype.setNext = function(interval) { - this.timeOut = setTimeout(_.bind(function() { - this.step(); - }, this), - interval || this.interval); -}; - -Scheduler.prototype.finish = function() { - this.done = true; - clearTimeout(this.timeOut); - this.timeOut = null; - - if (this.options.callback) { - this.options.callback(); - } -}; - -Scheduler.prototype.step = function() { - if (this.done) { - return; - } - - var results = this.closures[this.index]() || {}; - this.index++; - - if (results.done || this.index >= this.closures.length) { - this.finish(); - return; - } - this.setNext(results.interval); -}; - - - -/** - * class Breather - */ -function Breather(closure, baseline, delta, period, wait) { - this.delta = delta; - this.baseline = baseline; - this.closure = closure; - - this.t = 0; - this.interval = 1/40 * 1000; // 40fps - - var period_in_seconds = period || time.breathePeriod; - this.period = 2 * Math.PI * 1000 * period_in_seconds; - - this.interpolationFunction = TWEEN.Easing.Cubic.EaseInOut; - - if (wait) { + this.set('index', index + 1); setTimeout(_.bind(function() { - this.start(); - }, this), wait); - } else { - this.start(); - } -} - -Breather.prototype.start = function() { - this.t = 0; - this.next(); -}; - -Breather.prototype.next = function() { - this.timeout = setTimeout( - _.bind(function() { - this.breathe(); - }, this), - this.interval); -}; - -Breather.prototype.stop = function() { - clearTimeout(this.timeout); -}; - -Breather.prototype.breathe = function() { - this.t += this.interval; - - var value = Math.sin(this.t / this.period) * this.delta + this.baseline; - this.closure(value); - - this.next(); -}; + this.next(); + }, this), duration); + }, +}); diff --git a/src/collections.js b/src/collections.js index 9c27dbd9..d8448664 100644 --- a/src/collections.js +++ b/src/collections.js @@ -3,7 +3,7 @@ var CommitCollection = Backbone.Collection.extend({ }); var CommandCollection = Backbone.Collection.extend({ - model: Command + model: Command, }); var CommandBuffer = Backbone.Model.extend({ @@ -36,10 +36,6 @@ var CommandBuffer = Backbone.Model.extend({ // timeout existence implies its being processed return; } - - // process first element now - this.popAndProcess(); - // always set the timeout, regardless of buffer size this.setTimeout(); }, @@ -51,7 +47,7 @@ var CommandBuffer = Backbone.Model.extend({ }, popAndProcess: function() { - var popped = this.buffer.pop(); + var popped = this.buffer.shift(0); var callback = _.bind(function() { this.setTimeout(); }, this); diff --git a/src/commandline.js b/src/commandline.js index 50dc6b24..ff77e82e 100644 --- a/src/commandline.js +++ b/src/commandline.js @@ -33,6 +33,7 @@ var Command = Backbone.Model.extend({ err instanceof CommandResult || err instanceof GitError) { this.set('error', err); + this.set('status', 'error'); } else { throw err; } diff --git a/src/git.js b/src/git.js index 09dd9e69..6db5187a 100644 --- a/src/git.js +++ b/src/git.js @@ -682,16 +682,24 @@ GitEngine.prototype.dispatch = function(command, callback) { this.commandOptions = command.get('supportedMap'); this.generalArgs = command.get('generalArgs'); - command.set('status', 'processing'); - this[command.get('method') + 'Starter'](); - - // TODO: move into animation thing + // set up the animation queue var whenDone = _.bind(function() { command.set('status', 'finished'); callback(); }, this); - whenDone(); + this.animationQueue = new AnimationQueue({ + callback: whenDone + }); + command.set('status', 'processing'); + this[command.get('method') + 'Starter'](); + + // TODO (get rid of) + for (var i = 0; i < 10; i++) { + this.animationQueue.add(new Animation({closure: function() { console.log(Math.random()); }})); + } + + this.animationQueue.start(); }; GitEngine.prototype.addStarter = function() { diff --git a/src/style/main.css b/src/style/main.css index 0c6610c4..10e9f024 100644 --- a/src/style/main.css +++ b/src/style/main.css @@ -45,6 +45,10 @@ p.commandLine, p.commandLineResult { background-color: black; } +p.commandLine.error { + background-color: red; +} + p.commandLine.inqueue { background-color: yellow; color: black;