diff --git a/lib/loop/userloop.js b/lib/loop/userloop.js index 5f40363..8c034f1 100644 --- a/lib/loop/userloop.js +++ b/lib/loop/userloop.js @@ -2,13 +2,11 @@ // UserLoop // ----------------------------------------- // -var BUILD_AS_SINGLE_FILE; -if (!BUILD_AS_SINGLE_FILE) { var util = require('../util'); var EventEmitter = require('events').EventEmitter; var Loop = require('./loop').Loop; var Program = require('../user/program').Program; -} +var _ = require('underscore'); var USER_LOOP_OPTIONS = exports.USER_LOOP_OPTIONS = { program: undefined, @@ -38,7 +36,7 @@ var UserLoop = exports.UserLoop = function UserLoop(programOrSpec, args, conditi this.id = util.uid(); this.programFn = programOrSpec; - this.programArgs = args; + this.programArgs = args || {}; this.restartProgram(); this.conditions = conditions || []; this.running = false; @@ -52,7 +50,8 @@ UserLoop.prototype.start = function() { var self = this, startLoop = function() { self.emit('start'); - self.loop_(); + console.log("Starting main program: " + self.programFn.program.name); + self.loop_(self.headProgram); }; if (self.running) { return; } @@ -65,31 +64,71 @@ UserLoop.prototype.stop = function() { this.running = false; }; +UserLoop.prototype.wireInDependentPrograms = function(parentProgram, dependents) { + var self = this; + _(dependents).each(function(dependent) { + parentProgram.on(dependent.onEvent, function(eventArgs) { + console.log('Starting dependent program: ' + dependent.program.name); + + // Creates and starts the child program + var startChild = function() { + var child = new Program(dependent.program.program, eventArgs); + if (dependent.dependents) { + self.wireInDependentPrograms(child, dependent.dependents); + } + + self.loop_(child); + }; + + if (!dependent.cardinality) + dependent.cardinality = 1; + + // Support only triggering dependent programs some of the time + if (dependent.cardinality < 1) { + if (Number.random() < dependent.cardinality) { + startChild(); + } + } else { + _(dependent.cardinality).times(function() { + startChild(); + }); + } + + }); + }); +}; + UserLoop.prototype.restartProgram = function() { - this.program = new Program(this.programFn, this.programArgs); + if (_(this.programFn).isFunction()) { + this.headProgram = new Program(this.programFn, this.programArgs); + } else { + this.headProgram = new Program(this.programFn.program.program, this.programArgs); + this.wireInDependentPrograms(this.headProgram, this.programFn.dependents); + } + }; /** Checks conditions and schedules the next loop iteration. 'startiteration' is emitted before each iteration and 'enditeration' is emitted after. */ -UserLoop.prototype.loop_ = function() { - +UserLoop.prototype.loop_ = function(program) { var self = this, result, active, callfun = function() { result = null; active = true; - if (self.program.finished()) { - self.restartProgram(); + if (program.finished()) { + // TODO: How's this gonna work with dependent programs? + // self.restartProgram(); + return; } - var isRequest = self.program.pendingIsRequest(); + var isRequest = program.pendingIsRequest(); if (isRequest) { self.emit('startiteration'); } - self.program.next(function(res) { + program.next(function(res) { if (isRequest) { - console.log('e'); self.emit('enditeration', res); } - self.loop_(); + self.loop_(program); }); }; diff --git a/lib/user/program.js b/lib/user/program.js index b99690a..f613918 100644 --- a/lib/user/program.js +++ b/lib/user/program.js @@ -1,7 +1,6 @@ -var BUILD_AS_SINGLE_FILE; -if (BUILD_AS_SINGLE_FILE === undefined) { -var util = require('../util'); -} +var util = require('../util'), + EventEmitter = require('events').EventEmitter; + var Program = exports.Program = function(fun, args) { this._plan = []; @@ -10,6 +9,8 @@ var Program = exports.Program = function(fun, args) { fun(this, args); }; +util.inherits(Program, EventEmitter); + // Registration Program.interpreters = {}; @@ -53,3 +54,4 @@ Program.prototype.finished = function() { Program.registerInterpreter('wait', function(duration, next) { setTimeout(next, duration); }); +