(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define([], factory); } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.uSim = factory(); } }(this, function () { function uSim() { this.time = -Infinity; this.simcal = []; } uSim.prototype.schedule = function (time, object) { this.simcal.push({time: time, object: object}); this.simcal.sort(function (a, b) { return a.time - b.time; }); }; var sentinel = {time: -Infinity, object: null}; uSim.prototype.peekUntil = function (limit, cb) { var record = this.simcal[0] || sentinel, recordTime = record.time; if (recordTime > limit) record = sentinel; else this.simcal.shift(); if (recordTime > this.time) this.time = recordTime; if (cb) cb(record.object); else return record.object; }; uSim.prototype.peek = function (cb) { return this.peekUntil(Infinity, cb); }; uSim.prototype.streamUntil = function (limit, cb) { while (true) { var lastObject = null; this.peekUntil(limit, function (object) { lastObject = object; cb(object); }); if (lastObject == null) break; } }; uSim.prototype.stream = function (cb) { this.streamUntil(Infinity, cb); }; uSim.prototype.run = function () { var self = this; this.stream(function (each) { each(self); }); }; return uSim; }));