mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-07-01 18:24:28 +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
221
src/async.js
221
src/async.js
|
@ -1,175 +1,72 @@
|
||||||
/**
|
var Animation = Backbone.Model.extend({
|
||||||
* Util classes
|
defaults: {
|
||||||
*/
|
duration: 300,
|
||||||
|
closure: null
|
||||||
|
},
|
||||||
|
|
||||||
function CommandQueue() {
|
validateAtInit: function() {
|
||||||
this.commands = [];
|
if (!this.get('closure')) {
|
||||||
this.consumeTimeout = null;
|
throw new Error('give me a closure!');
|
||||||
|
|
||||||
this.initialDelay = 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandQueue.prototype.add = function(command) {
|
|
||||||
this.commands.push(command);
|
|
||||||
this.touchTimer();
|
|
||||||
};
|
|
||||||
|
|
||||||
CommandQueue.prototype.touchTimer = function() {
|
|
||||||
if (this.consumeTimeout) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
this.consumeTimeout = setTimeout(_.bind(function() {
|
},
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
this.validateAtInit();
|
||||||
|
},
|
||||||
|
|
||||||
|
run: function() {
|
||||||
|
this.get('closure')();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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.next();
|
||||||
}, this), this.initialDelay);
|
},
|
||||||
};
|
|
||||||
|
|
||||||
CommandQueue.prototype.reset = function() {
|
finish: function() {
|
||||||
this.consumeTimeout = null;
|
this.get('callback')();
|
||||||
};
|
},
|
||||||
|
|
||||||
CommandQueue.prototype.next = function() {
|
next: function() {
|
||||||
if (this.commands.length == 0) {
|
// ok so call the first animation, and then set a timeout to call the next
|
||||||
this.reset();
|
// TODO: animations with callbacks!!
|
||||||
return;
|
var animations = this.get('animations');
|
||||||
}
|
var index = this.get('index');
|
||||||
|
if (index >= animations.length) {
|
||||||
// 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);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************
|
|
||||||
* 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();
|
this.finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setNext(results.interval);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
var next = animations[index];
|
||||||
|
var duration = next.get('duration');
|
||||||
|
|
||||||
|
next.run();
|
||||||
|
|
||||||
/**
|
this.set('index', index + 1);
|
||||||
* 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) {
|
|
||||||
setTimeout(_.bind(function() {
|
setTimeout(_.bind(function() {
|
||||||
this.start();
|
|
||||||
}, this), wait);
|
|
||||||
} else {
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Breather.prototype.start = function() {
|
|
||||||
this.t = 0;
|
|
||||||
this.next();
|
this.next();
|
||||||
};
|
}, this), duration);
|
||||||
|
},
|
||||||
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();
|
|
||||||
};
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ var CommitCollection = Backbone.Collection.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
var CommandCollection = Backbone.Collection.extend({
|
var CommandCollection = Backbone.Collection.extend({
|
||||||
model: Command
|
model: Command,
|
||||||
});
|
});
|
||||||
|
|
||||||
var CommandBuffer = Backbone.Model.extend({
|
var CommandBuffer = Backbone.Model.extend({
|
||||||
|
@ -36,10 +36,6 @@ var CommandBuffer = Backbone.Model.extend({
|
||||||
// timeout existence implies its being processed
|
// timeout existence implies its being processed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process first element now
|
|
||||||
this.popAndProcess();
|
|
||||||
// always set the timeout, regardless of buffer size
|
|
||||||
this.setTimeout();
|
this.setTimeout();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -51,7 +47,7 @@ var CommandBuffer = Backbone.Model.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
popAndProcess: function() {
|
popAndProcess: function() {
|
||||||
var popped = this.buffer.pop();
|
var popped = this.buffer.shift(0);
|
||||||
var callback = _.bind(function() {
|
var callback = _.bind(function() {
|
||||||
this.setTimeout();
|
this.setTimeout();
|
||||||
}, this);
|
}, this);
|
||||||
|
|
|
@ -33,6 +33,7 @@ var Command = Backbone.Model.extend({
|
||||||
err instanceof CommandResult ||
|
err instanceof CommandResult ||
|
||||||
err instanceof GitError) {
|
err instanceof GitError) {
|
||||||
this.set('error', err);
|
this.set('error', err);
|
||||||
|
this.set('status', 'error');
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
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.commandOptions = command.get('supportedMap');
|
||||||
this.generalArgs = command.get('generalArgs');
|
this.generalArgs = command.get('generalArgs');
|
||||||
|
|
||||||
command.set('status', 'processing');
|
// set up the animation queue
|
||||||
this[command.get('method') + 'Starter']();
|
|
||||||
|
|
||||||
// TODO: move into animation thing
|
|
||||||
var whenDone = _.bind(function() {
|
var whenDone = _.bind(function() {
|
||||||
command.set('status', 'finished');
|
command.set('status', 'finished');
|
||||||
callback();
|
callback();
|
||||||
}, this);
|
}, 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() {
|
GitEngine.prototype.addStarter = function() {
|
||||||
|
|
|
@ -45,6 +45,10 @@ p.commandLine, p.commandLineResult {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.commandLine.error {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
p.commandLine.inqueue {
|
p.commandLine.inqueue {
|
||||||
background-color: yellow;
|
background-color: yellow;
|
||||||
color: black;
|
color: black;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue