Compare commits

...

3 Commits

Author SHA1 Message Date
Andrew Stewart 9d6a19507b Add methods to manipulate Repl context 2015-04-25 20:00:11 -07:00
Andrew Stewart 2ff7dc0866 Add Cylon.repl and Robot#repl methods
Each invokes a Repl with some necessary context
2015-04-25 19:37:26 -07:00
Andrew Stewart b2e8f57d24 Add a basic class wrapping Node's repl 2015-04-25 19:19:10 -07:00
3 changed files with 114 additions and 0 deletions

View File

@ -13,6 +13,7 @@ var Async = require("async");
var Logger = require("./logger"),
Robot = require("./robot"),
Config = require("./config"),
Repl = require("./repl"),
Utils = require("./utils"),
_ = require("./utils/helpers");
@ -143,6 +144,20 @@ Cylon.config = function(opts) {
return Config;
};
/**
* Starts a new REPL in the context of the MCP.
*
* @return {void}
*/
Cylon.repl = function repl() {
var instance = new Repl(
{ prompt: "mcp > " },
{ robots: this.robots }
);
instance.start();
};
// Public: Halts the API and the robots
//
// callback - callback to be triggered when Cylon is ready to shutdown

82
lib/repl.js Normal file
View File

@ -0,0 +1,82 @@
"use strict";
var util = require("util"),
createRepl = require("repl").start,
EventEmitter = require("events").EventEmitter;
var _ = require("./utils/helpers");
// asserts that a constructor was called with 'new'
function classCallCheck(instance, constructor) {
if (!instance instanceof constructor) {
throw new TypeError("Cannot call a class as a function");
}
}
var Repl = module.exports = function Repl(opts, context) {
classCallCheck(this, Repl);
opts = opts || {};
context = context || {};
opts.prompt = opts.prompt || "repl > ";
opts.stdin = opts.stdin || process.stdin;
opts.stdout = opts.stdout || process.stdout;
this.repl = null;
this.options = opts;
this.context = context;
};
Repl.active = false;
util.inherits(Repl, EventEmitter);
Repl.prototype.start = function() {
// don't try to start two repls at once
if (Repl.active) {
return false;
}
Repl.active = true;
this.repl = createRepl(this.options);
_.extend(this.repl.context, this.context);
this.repl.on("exit", function() {
Repl.active = false;
this.emit("exit");
}.bind(this));
this.repl.on("reset", function(context) {
_.extend(context, this.context);
this.emit("reset");
}.bind(this));
};
// add a value to the context
Repl.prototype.addContext = function(key, value) {
this.context[key] = value;
this.repl.context[key] = value;
};
// remove a value from the context
Repl.prototype.removeContext = function(key) {
delete this.context[key];
delete this.repl.context[key];
};
// set the context to the provided object
Repl.prototype.setContext = function(object) {
_.each(this.context, function(value, key) {
if (this.context.hasOwnProperty(key)) {
this.removeContext(key);
}
}.bind(this));
_.each(object, function(value, key) {
if (object.hasOwnProperty(key)) {
this.addContext(key, value);
}
}.bind(this));
};

View File

@ -11,6 +11,7 @@
var initializer = require("./initializer"),
Logger = require("./logger"),
Utils = require("./utils"),
Repl = require("./repl"),
Config = require("./config"),
_ = require("./utils/helpers");
@ -421,6 +422,22 @@ Robot.prototype.halt = function(callback) {
this.running = false;
};
/**
* Starts a new REPL in the context of the Robot.
*
* @return {void}
*/
Robot.prototype.repl = function() {
var context = {};
_.extend(context, this.connections);
_.extend(context, this.devices);
var repl = new Repl({ prompt: this.name + " > " }, context);
repl.start();
};
// Public: Returns basic info about the robot as a String
//
// Returns a String