mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-07-09 14:14:27 +02:00
BOOMMMMMM async error queues now done, this is so sexy
This commit is contained in:
parent
dbd7913803
commit
459d104fdb
5 changed files with 81 additions and 175 deletions
225
src/async.js
225
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);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
18
src/git.js
18
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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue