This commit is contained in:
Andrew Sliwinski 2016-04-18 18:03:18 -04:00
parent 14b92f8a99
commit 53779220b7
4 changed files with 147 additions and 221 deletions

View file

@ -1,3 +1,6 @@
var EventEmitter = require('events');
var util = require('util');
var Primitives = require('./primatives'); var Primitives = require('./primatives');
var Sequencer = require('./sequencer'); var Sequencer = require('./sequencer');
var Thread = require('./thread'); var Thread = require('./thread');
@ -8,6 +11,10 @@ var STEP_THREADS_INTERVAL = 1000 / 30;
* A simple runtime for blocks. * A simple runtime for blocks.
*/ */
function Runtime () { function Runtime () {
// Bind event emitter
EventEmitter.call(instance);
// Instantiate sequencer and primitives
this.sequencer = new Sequencer(this); this.sequencer = new Sequencer(this);
this.primitives = new Primitives(); this.primitives = new Primitives();
@ -16,6 +23,11 @@ function Runtime () {
this.stacks = []; this.stacks = [];
} }
/**
* Inherit from EventEmitter
*/
util.inherits(Runtime, EventEmitter);
Runtime.prototype.createBlock = function (e) { Runtime.prototype.createBlock = function (e) {
// Create new block // Create new block
this.blocks[e.id] = { this.blocks[e.id] = {
@ -90,8 +102,9 @@ Runtime.prototype.runAllStacks = function () {
// @todo // @todo
}; };
Runtime.prototype.runStack = function () { Runtime.prototype.runStack = function (e) {
// @todo // @todo
console.dir(e);
}; };
Runtime.prototype.stopAllStacks = function () { Runtime.prototype.stopAllStacks = function () {

View file

@ -12,11 +12,12 @@ function VirtualMachine () {
var instance = this; var instance = this;
// Bind event emitter and runtime to VM instance // Bind event emitter and runtime to VM instance
// @todo Post message (Web Worker) polyfill
EventEmitter.call(instance); EventEmitter.call(instance);
instance.runtime = new Runtime(); instance.runtime = new Runtime();
/** /**
* Event listener for blockly. Handles validation and serves as a generic * Event listener for blocks. Handles validation and serves as a generic
* adapter between the blocks and the runtime interface. * adapter between the blocks and the runtime interface.
* *
* @param {Object} Blockly "block" event * @param {Object} Blockly "block" event
@ -54,42 +55,19 @@ function VirtualMachine () {
}); });
break; break;
} }
// UI
if (typeof e.element === 'undefined') return;
switch (e.element) {
case 'click':
instance.runtime.runStack({
id: e.blockId
});
break;
}
}; };
// @todo UI listener
// @todo Forward runtime events // @todo Forward runtime events
// Event dispatcher
// this.types = keymirror({
// // Messages to runtime
// CREATE_BLOCK: null,
// MOVE_BLOCK: null,
// CHANGE_BLOCK: null,
// DELETE_BLOCK: null,
//
// ADD_DEVICE: null,
// REMOVE_DEVICE: null,
//
// RUN_STRIP: null,
// RUN_ALL_STRIPS: null,
// STOP_ALL_STRIPS: null,
// RUN_PALETTE_BLOCK: null,
//
// // Messages from runtime - subscribe to these
// FEEDBACK_EXECUTING_BLOCK: null,
// FEEDBACK_STOPPED_EXECUTING_BLOCK: null,
// DEVICE_RUN_OP: null,
// DEVICE_STOP_OP: null,
//
// // Tell back the interpreter device has finished an op
// DEVICE_FINISHED_OP: null
// });
// Bind block event stream
// setTimeout(function () {
// _this.emit('foo', 'bar');
// }, 1000);
} }
/** /**
@ -97,40 +75,12 @@ function VirtualMachine () {
*/ */
util.inherits(VirtualMachine, EventEmitter); util.inherits(VirtualMachine, EventEmitter);
// VirtualMachine.prototype.changeListener = function (e) {
// var _this = this;
// console.dir(this);
//
// switch (e.type) {
// case 'create':
// console.dir(e);
// _this.runtime.createBlock(
// e.blockId,
// event.xml.attributes.type.value
// );
// break;
// case 'change':
// // @todo
// break;
// case 'move':
// // @todo
// break;
// case 'delete':
// // @todo
// break;
// }
// };
//
// VirtualMachine.prototype.tapListener = function (e) {
// // @todo
// };
VirtualMachine.prototype.start = function () { VirtualMachine.prototype.start = function () {
this.runtime.runAllGreenFlags(); // @todo Run all green flags
}; };
VirtualMachine.prototype.stop = function () { VirtualMachine.prototype.stop = function () {
this.runtime.stop(); // @todo Stop all threads
}; };
VirtualMachine.prototype.save = function () { VirtualMachine.prototype.save = function () {

273
vm.js
View file

@ -58,11 +58,12 @@
var instance = this; var instance = this;
// Bind event emitter and runtime to VM instance // Bind event emitter and runtime to VM instance
// @todo Post message (Web Worker) polyfill
EventEmitter.call(instance); EventEmitter.call(instance);
instance.runtime = new Runtime(); instance.runtime = new Runtime();
/** /**
* Event listener for blockly. Handles validation and serves as a generic * Event listener for blocks. Handles validation and serves as a generic
* adapter between the blocks and the runtime interface. * adapter between the blocks and the runtime interface.
* *
* @param {Object} Blockly "block" event * @param {Object} Blockly "block" event
@ -100,42 +101,19 @@
}); });
break; break;
} }
// UI
if (typeof e.element === 'undefined') return;
switch (e.element) {
case 'click':
instance.runtime.runStack({
id: e.blockId
});
break;
}
}; };
// @todo UI listener
// @todo Forward runtime events // @todo Forward runtime events
// Event dispatcher
// this.types = keymirror({
// // Messages to runtime
// CREATE_BLOCK: null,
// MOVE_BLOCK: null,
// CHANGE_BLOCK: null,
// DELETE_BLOCK: null,
//
// ADD_DEVICE: null,
// REMOVE_DEVICE: null,
//
// RUN_STRIP: null,
// RUN_ALL_STRIPS: null,
// STOP_ALL_STRIPS: null,
// RUN_PALETTE_BLOCK: null,
//
// // Messages from runtime - subscribe to these
// FEEDBACK_EXECUTING_BLOCK: null,
// FEEDBACK_STOPPED_EXECUTING_BLOCK: null,
// DEVICE_RUN_OP: null,
// DEVICE_STOP_OP: null,
//
// // Tell back the interpreter device has finished an op
// DEVICE_FINISHED_OP: null
// });
// Bind block event stream
// setTimeout(function () {
// _this.emit('foo', 'bar');
// }, 1000);
} }
/** /**
@ -143,40 +121,12 @@
*/ */
util.inherits(VirtualMachine, EventEmitter); util.inherits(VirtualMachine, EventEmitter);
// VirtualMachine.prototype.changeListener = function (e) {
// var _this = this;
// console.dir(this);
//
// switch (e.type) {
// case 'create':
// console.dir(e);
// _this.runtime.createBlock(
// e.blockId,
// event.xml.attributes.type.value
// );
// break;
// case 'change':
// // @todo
// break;
// case 'move':
// // @todo
// break;
// case 'delete':
// // @todo
// break;
// }
// };
//
// VirtualMachine.prototype.tapListener = function (e) {
// // @todo
// };
VirtualMachine.prototype.start = function () { VirtualMachine.prototype.start = function () {
this.runtime.runAllGreenFlags(); // @todo Run all green flags
}; };
VirtualMachine.prototype.stop = function () { VirtualMachine.prototype.stop = function () {
this.runtime.stop(); // @todo Stop all threads
}; };
VirtualMachine.prototype.save = function () { VirtualMachine.prototype.save = function () {
@ -1232,9 +1182,12 @@
/* 6 */ /* 6 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
var Primitives = __webpack_require__(10); var EventEmitter = __webpack_require__(1);
var Sequencer = __webpack_require__(7); var util = __webpack_require__(2);
var Thread = __webpack_require__(9);
var Primitives = __webpack_require__(7);
var Sequencer = __webpack_require__(8);
var Thread = __webpack_require__(10);
var STEP_THREADS_INTERVAL = 1000 / 30; var STEP_THREADS_INTERVAL = 1000 / 30;
@ -1242,6 +1195,10 @@
* A simple runtime for blocks. * A simple runtime for blocks.
*/ */
function Runtime () { function Runtime () {
// Bind event emitter
EventEmitter.call(instance);
// Instantiate sequencer and primitives
this.sequencer = new Sequencer(this); this.sequencer = new Sequencer(this);
this.primitives = new Primitives(); this.primitives = new Primitives();
@ -1250,6 +1207,11 @@
this.stacks = []; this.stacks = [];
} }
/**
* Inherit from EventEmitter
*/
util.inherits(Runtime, EventEmitter);
Runtime.prototype.createBlock = function (e) { Runtime.prototype.createBlock = function (e) {
// Create new block // Create new block
this.blocks[e.id] = { this.blocks[e.id] = {
@ -1324,8 +1286,9 @@
// @todo // @todo
}; };
Runtime.prototype.runStack = function () { Runtime.prototype.runStack = function (e) {
// @todo // @todo
console.dir(e);
}; };
Runtime.prototype.stopAllStacks = function () { Runtime.prototype.stopAllStacks = function () {
@ -1355,93 +1318,6 @@
/***/ }, /***/ },
/* 7 */ /* 7 */
/***/ function(module, exports, __webpack_require__) {
var Timer = __webpack_require__(8);
/**
* Constructor
*/
function Sequencer (runtime) {
// Bi-directional binding for runtime
this.runtime = runtime;
// State
this.runningThreads = [];
this.workTime = 30;
this.timer = new Timer();
this.currentTime = 0;
}
Sequencer.prototype.stepAllThreads = function () {
};
Sequencer.prototype.stepThread = function (thread) {
};
Sequencer.prototype.startSubstack = function (thread) {
};
module.exports = Sequencer;
/***/ },
/* 8 */
/***/ function(module, exports) {
/**
* Constructor
* @todo Swap out Date.now() with microtime module that works in node & browsers
*/
function Timer () {
this.startTime = 0;
}
Timer.prototype.time = function () {
return Date.now();
};
Timer.prototype.start = function () {
this.startTime = this.time();
};
Timer.prototype.stop = function () {
return this.startTime - this.time();
};
module.exports = Timer;
/***/ },
/* 9 */
/***/ function(module, exports) {
/**
* Thread is an internal data structure used by the interpreter. It holds the
* state of a thread so it can continue from where it left off, and it has
* a stack to support nested control structures and procedure calls.
*
* @param {String} Unique block identifier
*/
function Thread (id) {
this.topBlockId = id;
this.blockPointer = id;
this.blockFirstTime = -1;
this.nextBlock = null;
this.waiting = null;
this.runningDeviceBlock = false;
this.stack = [];
this.repeatCounter = -1;
}
module.exports = Thread;
/***/ },
/* 10 */
/***/ function(module, exports) { /***/ function(module, exports) {
function Primitives () { function Primitives () {
@ -1487,5 +1363,92 @@
module.exports = Primitives; module.exports = Primitives;
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
var Timer = __webpack_require__(9);
/**
* Constructor
*/
function Sequencer (runtime) {
// Bi-directional binding for runtime
this.runtime = runtime;
// State
this.runningThreads = [];
this.workTime = 30;
this.timer = new Timer();
this.currentTime = 0;
}
Sequencer.prototype.stepAllThreads = function () {
};
Sequencer.prototype.stepThread = function (thread) {
};
Sequencer.prototype.startSubstack = function (thread) {
};
module.exports = Sequencer;
/***/ },
/* 9 */
/***/ function(module, exports) {
/**
* Constructor
* @todo Swap out Date.now() with microtime module that works in node & browsers
*/
function Timer () {
this.startTime = 0;
}
Timer.prototype.time = function () {
return Date.now();
};
Timer.prototype.start = function () {
this.startTime = this.time();
};
Timer.prototype.stop = function () {
return this.startTime - this.time();
};
module.exports = Timer;
/***/ },
/* 10 */
/***/ function(module, exports) {
/**
* Thread is an internal data structure used by the interpreter. It holds the
* state of a thread so it can continue from where it left off, and it has
* a stack to support nested control structures and procedure calls.
*
* @param {String} Unique block identifier
*/
function Thread (id) {
this.topBlockId = id;
this.blockPointer = id;
this.blockFirstTime = -1;
this.nextBlock = null;
this.waiting = null;
this.runningDeviceBlock = false;
this.stack = [];
this.repeatCounter = -1;
}
module.exports = Thread;
/***/ } /***/ }
/******/ ]); /******/ ]);

2
vm.min.js vendored

File diff suppressed because one or more lines are too long