command queue working

This commit is contained in:
Peter Cottle 2012-08-13 20:23:25 -07:00
parent 2a84ebe36d
commit 5ee115872d
6 changed files with 151 additions and 101 deletions

Binary file not shown.

View file

@ -3,67 +3,23 @@
*/ */
/** /*
* Particle System AsyncEngine
*
* Handles async stuff like adding the edges, etc
*/
function AsyncEngine() {
this.addEdgeTimeout = null;
this.edgeClosures = [];
}
AsyncEngine.prototype.addEdge = function(node1, node2) {
this.touchEdgeTimer();
this.edgeClosures.push(this.edgeClosureFactory(node1, node2));
};
AsyncEngine.prototype.edgeClosureFactory = function(node1, node2) {
var c = function() {
var e = sys.addEdge(node1, node2); var e = sys.addEdge(node1, node2);
}; */
return c;
};
AsyncEngine.prototype.touchEdgeTimer = function(key) { function Scheduler(closures, options) {
if (this.addEdgeTimeout) { if (!closures || !closures.length) {
return;
}
var _this = this;
this.addEdgeTimeout = setTimeout(function() {
_this.startEdgeScheduler();
}, 100);
};
AsyncEngine.prototype.startEdgeScheduler = function() {
// start scheduler
var s = new Scheduler(this.edgeClosures, time.edgeAddInterval, 'add_edge');
s.start();
this.resetEdges();
};
AsyncEngine.prototype.resetEdges = function() {
this.edgeClosures = [];
this.addEdgeTimeout = null;
};
function Scheduler(closures, interval, type) {
if (!closures || !closures.length || !interval || !type) {
throw new Error('invalid params'); throw new Error('invalid params');
} }
this.done = false;
this.closures = closures; this.closures = closures;
this.interval = interval;
this.type = type; this.options = options || {};
this.interval = this.options.interval || 400;
this.done = false;
this.timeOut = null; this.timeOut = null;
this.index = 0; this.index = 0;
ee.addListener('scheduler_stop', this.stopSchedule, this);
} }
Scheduler.prototype.start = function() { Scheduler.prototype.start = function() {
@ -80,12 +36,13 @@ Scheduler.prototype.setNext = function(interval) {
interval || this.interval); interval || this.interval);
}; };
Scheduler.prototype.stopSchedule = function(type) { Scheduler.prototype.finish = function() {
console.log('received event signal');
if (type == 'all' || type == this.type) {
// either of these should work...
this.done = true; this.done = true;
clearTimeout(this.timeOut); clearTimeout(this.timeOut);
this.timeOut = null;
if (this.options.callback) {
this.options.callback();
} }
}; };
@ -98,7 +55,7 @@ Scheduler.prototype.step = function() {
this.index++; this.index++;
if (results.done || this.index >= this.closures.length) { if (results.done || this.index >= this.closures.length) {
this.done = true; this.finish();
return; return;
} }
this.setNext(results.interval); this.setNext(results.interval);
@ -123,10 +80,9 @@ function Breather(closure, baseline, delta, period, wait) {
this.interpolationFunction = TWEEN.Easing.Cubic.EaseInOut; this.interpolationFunction = TWEEN.Easing.Cubic.EaseInOut;
if (wait) { if (wait) {
var _this = this; setTimeout(_.bind(function() {
setTimeout(function() { this.start();
_this.start(); }, this), wait);
}, wait);
} else { } else {
this.start(); this.start();
} }

View file

@ -3,7 +3,6 @@
* @desc A parser for commands given * @desc A parser for commands given
*/ */
function Command(str) { function Command(str) {
this.rawCommand = str;
this.results = { this.results = {
msgs: [] msgs: []
}; };
@ -14,26 +13,32 @@ function Command(str) {
Command.prototype.getShortcutMap = function() { Command.prototype.getShortcutMap = function() {
return { return {
gc: 'git commit', 'git commit': /^gc/,
ga: 'git add', 'git add': /^ga/,
gchk: 'git checkout', 'git checkout': /^gchk/,
gr: 'git rebase' 'git rebase': /^gr/
}; };
}; };
Command.prototype.getRegexMap = function() { Command.prototype.getRegexMap = function() {
return { return {
commit: /^commit /, commit: /^commit\s*/,
add: /^add /, add: /^add\s*/,
checkout: /^checkout /, checkout: /^checkout\s*/,
rebase: /^rebase /, rebase: /^rebase\s*/,
reset: /^reset / reset: /^reset\s*/
}; };
}; };
Command.prototype.parse = function(str) { Command.prototype.parse = function(str) {
// first check if shortcut exists, and replace // first check if shortcut exists, and replace, but
str = this.getShortcutMap()[str] || str; // preserve options
_.each(this.getShortcutMap(), function(regex, method) {
var results = regex.exec(str);
if (results) {
str = method + str.slice(results[0].length);
}
});
// see if begins with git // see if begins with git
if (str.slice(0,3) !== 'git') { if (str.slice(0,3) !== 'git') {
@ -43,18 +48,21 @@ Command.prototype.parse = function(str) {
// now slice off command part // now slice off command part
this.command = str.slice(4); this.command = str.slice(4);
//TODO: underscore.js here var matched = false;
_.each(this.getRegexMap(), function(regex, method) { _.each(this.getRegexMap(), function(regex, method) {
if (regex.exec(this.command)) { if (regex.exec(this.command)) {
this.options = this.command.slice(method.length + 1); this.options = this.command.slice(method.length + 1);
// break out here
this[method](); this[method]();
return false; // we should stop iterating, but the regex will only match
// one command in practice
matched = true;
} }
}, this); }, this);
if (!matched) {
this.results.msgs.push('The git command "' + this.command + this.results.msgs.push('The git command "' + this.command +
'" is not supported, sorry!'); '" is not supported, sorry!');
}
}; };
Command.prototype.nonGitCommand = function() { Command.prototype.nonGitCommand = function() {

View file

@ -6,6 +6,30 @@ GitEngine.prototype.commit = function() {
}; };
GitEngine.prototype.execute = function(command, callback) {
// execute command, and when it's finished, call the callback
// we still need to figure this out
var closures = this.getClosuresForCommand(command);
// make a scheduler based on all the closures, and pass in our callback
var s = new Scheduler(closures, {
callback: callback
});
s.start();
};
GitEngine.prototype.getClosuresForCommand = function(command) {
var numbers = [1,2,3,4,5,6,7,8,9,10];
var closures = [];
_.each(numbers, function(num) {
var c = function() {
console.log(num);
};
closures.push(c);
});
return closures;
};
var Commit = Backbone.Model.extend({ var Commit = Backbone.Model.extend({
initialize: function() { initialize: function() {
// validation / defaults // validation / defaults
@ -15,7 +39,76 @@ var Commit = Backbone.Model.extend({
if (!this.get('parent') && !this.get('rootCommit')) { if (!this.get('parent') && !this.get('rootCommit')) {
throw new Error('needs parent commit'); throw new Error('needs parent commit');
} }
// make a node and start drawing? this is a major TODO
},
draw: function() {
// make a node and start drawing?
} }
}); });
function CommandQueue() {
this.commands = [];
this.consumeTimeout = null;
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() {
this.next();
}, this), this.initialDelay);
};
CommandQueue.prototype.reset = function() {
this.consumeTimeout = null;
};
CommandQueue.prototype.next = function() {
if (this.commands.length == 0) {
this.reset();
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);
};
/******************
* 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)
*/

View file

@ -96,11 +96,7 @@ Renderer = function(canvas) {
return that; return that;
} }
var Maps = function(elt){ function addRandom() {
sys = arbor.ParticleSystem(4000, 500, 0.5, false, 55, 0.005, 'verlet');
sys.renderer = Renderer("#viewport");
// our newly created renderer will have its .init() method called shortly by sys...
// Add some random nodes and edges to the graph! // Add some random nodes and edges to the graph!
nodes = []; nodes = [];
for (var i = 0; i < 15; i++) { for (var i = 0; i < 15; i++) {
@ -123,13 +119,13 @@ var Maps = function(elt){
while (node1 === node2) { while (node1 === node2) {
node2 = randNode(); node2 = randNode();
} }
engine.addEdge(node1, node2); sys.addEdge(node1, node2);
} }
for (var i = 0; i < nodes.length; i++) { for (var i = 0; i < nodes.length; i++) {
var node2 = randNode(); var node2 = randNode();
while (nodes[i] === node2) { while (nodes[i] === node2) {
node2 = randNode(); node2 = randNode();
} }
engine.addEdge(nodes[i], node2); sys.addEdge(nodes[i], node2);
} }
} }

View file

@ -3,17 +3,15 @@
*/ */
var ee = null; var ee = null;
var sys = null; var sys = null;
var engine = null;
var graphicsEffects = {}; var graphicsEffects = {};
var gitEngine = null; var gitEngine = null;
$(document).ready(function(){ $(document).ready(function(){
if (false) {
engine = new AsyncEngine();
ee = new EventEmitter();
gitEngine = new GitEngine(); gitEngine = new GitEngine();
ee = new EventEmitter();
var mcp = Maps("#maps"); sys = arbor.ParticleSystem(4000, 500, 0.5, false, 55, 0.005, 'verlet');
sys.renderer = Renderer('#viewport');
var repulsionBreathe = function(r) { var repulsionBreathe = function(r) {
sys.parameters({repulsion: r}); sys.parameters({repulsion: r});
@ -21,7 +19,6 @@ $(document).ready(function(){
var b = new Breather(repulsionBreathe, 6050, 4000); var b = new Breather(repulsionBreathe, 6050, 4000);
graphicsEffects.edgeStrokeEffect = new GraphicsEffect('edgeStroke', {wait: 1000}); graphicsEffects.edgeStrokeEffect = new GraphicsEffect('edgeStroke', {wait: 1000});
}
}); });