pcottle.learnGitBranching/src/js/models/collections.js
2013-01-11 12:35:42 -08:00

130 lines
3.3 KiB
JavaScript

var _ = require('underscore');
var Q = require('q');
// horrible hack to get localStorage Backbone plugin
var Backbone = (!require('../util').isBrowser()) ? Backbone = require('backbone') : Backbone = window.Backbone;
var Commit = require('../git').Commit;
var Branch = require('../git').Branch;
var Command = require('../models/commandModel').Command;
var CommandEntry = require('../models/commandModel').CommandEntry;
var TIME = require('../util/constants').TIME;
var CommitCollection = Backbone.Collection.extend({
model: Commit
});
var CommandCollection = Backbone.Collection.extend({
model: Command
});
var BranchCollection = Backbone.Collection.extend({
model: Branch
});
var CommandEntryCollection = Backbone.Collection.extend({
model: CommandEntry,
localStorage: (Backbone.LocalStorage) ? new Backbone.LocalStorage('CommandEntries') : null
});
var CommandBuffer = Backbone.Model.extend({
defaults: {
collection: null
},
initialize: function(options) {
options.collection.bind('add', this.addCommand, this);
this.buffer = [];
this.timeout = null;
},
addCommand: function(command) {
this.buffer.push(command);
this.touchBuffer();
},
touchBuffer: function() {
// touch buffer just essentially means we just check if our buffer is being
// processed. if it's not, we immediately process the first item
// and then set the timeout.
if (this.timeout) {
// timeout existence implies its being processed
return;
}
this.setTimeout();
},
setTimeout: function() {
this.timeout = setTimeout(_.bind(function() {
this.sipFromBuffer();
}, this), TIME.betweenCommandsDelay);
},
popAndProcess: function() {
var popped = this.buffer.shift(0);
// find a command with no error (aka unprocessed)
while (popped.get('error') && this.buffer.length) {
popped = this.buffer.shift(0);
}
if (!popped.get('error')) {
this.processCommand(popped);
} else {
// no more commands to process
this.clear();
}
},
processCommand: function(command) {
command.set('status', 'processing');
var deferred = Q.defer();
deferred.promise.then(_.bind(function() {
this.setTimeout();
}, this));
var eventName = command.get('eventName');
if (!eventName) {
throw new Error('I need an event to trigger when this guy is parsed and ready');
}
var Main = require('../app');
var eventBaton = Main.getEventBaton();
var numListeners = eventBaton.getNumListeners(eventName);
if (!numListeners) {
var Errors = require('../util/errors');
command.set('error', new Errors.GitError({
msg: 'That command is valid, but not supported in this current environment!' +
' Try entering a level or level builder to use that command'
}));
deferred.resolve();
return;
}
Main.getEventBaton().trigger(eventName, command, deferred);
},
clear: function() {
clearTimeout(this.timeout);
this.timeout = null;
},
sipFromBuffer: function() {
if (!this.buffer.length) {
this.clear();
return;
}
this.popAndProcess();
}
});
exports.CommitCollection = CommitCollection;
exports.CommandCollection = CommandCollection;
exports.BranchCollection = BranchCollection;
exports.CommandEntryCollection = CommandEntryCollection;
exports.CommandBuffer = CommandBuffer;