Convert Cylon.Master to a plain JS object
Acts exactly the same with much, much less code complexity. This also introduces a pattern for providing core modules to external libraries. Whereas previously Cylon modules were able to rely on Cylon.Adaptor or Cylon.Driver being present in the namespace (due to being required in ./lib/cylon), they will now need to require Cylon first, like this: var Cylon = require('cylon'); var Driver = Cylon.Driver, Adaptor = Cylon.Adaptor, DigitalPin = Cylon.IO.DigitalPin;
This commit is contained in:
parent
90e6ab5564
commit
43a9351921
357
lib/cylon.js
357
lib/cylon.js
|
@ -8,225 +8,196 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
require('./config');
|
||||
require('./utils');
|
||||
var Robot = require('./robot'),
|
||||
Utils = require('./utils');
|
||||
|
||||
require('./logger');
|
||||
require('./driver');
|
||||
require('./adaptor');
|
||||
|
||||
Logger.setup();
|
||||
|
||||
// Cylon is the global namespace for the project, and also in charge of
|
||||
// maintaining the Master singleton that controls all the robots.
|
||||
var Cylon = (function() {
|
||||
function Cylon() {}
|
||||
var Cylon = module.exports = {
|
||||
Driver: require('./driver'),
|
||||
Adaptor: require('./adaptor'),
|
||||
|
||||
var instance = null;
|
||||
IO: {
|
||||
DigitalPin: require('./io/digital-pin')
|
||||
},
|
||||
|
||||
// Public: Fetches singleton instance of Master, or creates a new one if it
|
||||
// doesn't already exist
|
||||
//
|
||||
// Returns a Master instance
|
||||
Cylon.getInstance = function() {
|
||||
return new Master();
|
||||
};
|
||||
api_instance: null,
|
||||
|
||||
// The Master class is our puppeteer that manages all the robots, as well as
|
||||
// starting them and the API.
|
||||
var Master = (function() {
|
||||
// Public: Creates a new Master
|
||||
//
|
||||
// Returns a Master instance
|
||||
function Master() {
|
||||
var _this = this;
|
||||
robots: [],
|
||||
|
||||
this.api_instance = null;
|
||||
this.robots = [];
|
||||
api_config: {
|
||||
host: '127.0.0.1',
|
||||
port: '3000',
|
||||
auth: {},
|
||||
CORS: null,
|
||||
ssl: {}
|
||||
}
|
||||
};
|
||||
|
||||
this.api_config = {
|
||||
host: '127.0.0.1',
|
||||
port: '3000',
|
||||
auth: {},
|
||||
CORS: null,
|
||||
ssl: {}
|
||||
};
|
||||
// Public: Creates a new Robot
|
||||
//
|
||||
// opts - hash of Robot attributes
|
||||
//
|
||||
// Returns a shiny new Robot
|
||||
// Examples:
|
||||
// Cylon.robot
|
||||
// connection: { name: 'arduino', adaptor: 'firmata' }
|
||||
// device: { name: 'led', driver: 'led', pin: 13 }
|
||||
//
|
||||
// work: (me) ->
|
||||
// me.led.toggle()
|
||||
Cylon.robot = function robot(opts) {
|
||||
opts.master = this;
|
||||
var robot = new Robot(opts);
|
||||
this.robots.push(robot);
|
||||
return robot;
|
||||
};
|
||||
|
||||
this.robot = bind(this.robot, this);
|
||||
// Public: Configures the API host and port based on passed options
|
||||
//
|
||||
// opts - object containing API options
|
||||
// host - host address API should serve from
|
||||
// port - port API should listen for requests on
|
||||
//
|
||||
// Returns the API configuration
|
||||
Cylon.api = function api(opts) {
|
||||
if (opts == null) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
if (process.platform === "win32") {
|
||||
var readline = require("readline"),
|
||||
io = { input: process.stdin, output: process.stdout };
|
||||
var keys = ['host', 'port', 'auth', 'CORS', 'ssl'];
|
||||
|
||||
readline.createInterface(io).on("SIGINT", function() {
|
||||
process.emit("SIGINT");
|
||||
});
|
||||
}
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
if (typeof opts[key] !== "undefined") {
|
||||
this.api_config[key] = opts[key];
|
||||
}
|
||||
}
|
||||
|
||||
process.on("SIGINT", function() {
|
||||
_this.halt();
|
||||
process.kill(process.pid);
|
||||
});
|
||||
return this.api_config;
|
||||
};
|
||||
|
||||
// Public: Finds a particular robot by name
|
||||
//
|
||||
// name - name of the robot to find
|
||||
// callback - optional callback to be executed
|
||||
//
|
||||
// Returns the found Robot or result of the callback if it's supplied
|
||||
Cylon.findRobot = function findRobot(name, callback) {
|
||||
var error,
|
||||
robot = null;
|
||||
|
||||
for (var i = 0; i < this.robots.length; i++) {
|
||||
var bot = this.robots[i];
|
||||
if (bot.name === name) { robot = bot; }
|
||||
}
|
||||
|
||||
if (robot == null) {
|
||||
error = { error: "No Robot found with the name " + name };
|
||||
}
|
||||
|
||||
return callback ? callback(error, robot) : robot;
|
||||
};
|
||||
|
||||
// Public: Finds a particular Robot's device by name
|
||||
//
|
||||
// robotid - name of the robot to find
|
||||
// deviceid - name of the device to find
|
||||
// callback - optional callback to be executed
|
||||
//
|
||||
// Returns the found Device or result of the callback if it's supplied
|
||||
Cylon.findRobotDevice = function findRobotDevice(robotid, deviceid, callback) {
|
||||
return this.findRobot(robotid, function(err, robot) {
|
||||
var error,
|
||||
device = null;
|
||||
|
||||
if (err) { return callback ? callback(err, robot) : robot }
|
||||
|
||||
if (robot.devices[deviceid]) { device = robot.devices[deviceid]; }
|
||||
|
||||
if (device == null) {
|
||||
error = { error: "No device found with the name " + deviceid + "." };
|
||||
}
|
||||
|
||||
// Public: Creates a new Robot
|
||||
//
|
||||
// opts - hash of Robot attributes
|
||||
//
|
||||
// Returns a shiny new Robot
|
||||
// Examples:
|
||||
// Cylon.robot
|
||||
// connection: { name: 'arduino', adaptor: 'firmata' }
|
||||
// device: { name: 'led', driver: 'led', pin: 13 }
|
||||
//
|
||||
// work: (me) ->
|
||||
// me.led.toggle()
|
||||
Master.prototype.robot = function(opts) {
|
||||
var Robot = require("./robot");
|
||||
opts.master = this;
|
||||
return callback ? callback(error, device) : device;
|
||||
});
|
||||
};
|
||||
|
||||
var robot = new Robot(opts);
|
||||
// Public: Finds a particular Robot's connection by name
|
||||
//
|
||||
// robotid - name of the robot to find
|
||||
// connid - name of the device to find
|
||||
// callback - optional callback to be executed
|
||||
//
|
||||
// Returns the found Connection or result of the callback if it's supplied
|
||||
Cylon.findRobotConnection = function findRobotConnection(robotid, connid, callback) {
|
||||
return this.findRobot(robotid, function(err, robot) {
|
||||
var error,
|
||||
connection = null;
|
||||
|
||||
this.robots.push(robot);
|
||||
return robot;
|
||||
};
|
||||
if (err) { return callback ? callback(err, robot) : robot }
|
||||
|
||||
// Public: Configures the API host and port based on passed options
|
||||
//
|
||||
// opts - object containing API options
|
||||
// host - host address API should serve from
|
||||
// port - port API should listen for requests on
|
||||
//
|
||||
// Returns the API configuration
|
||||
Master.prototype.api = function(opts) {
|
||||
if (opts == null) { opts = {}; }
|
||||
if (robot.connections[connid]) { connection = robot.connections[connid]; }
|
||||
|
||||
var keys = ['host', 'port', 'auth', 'CORS', 'ssl'];
|
||||
if (connection == null) {
|
||||
error = { error: "No connection found with the name " + connid + "." };
|
||||
}
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
if (typeof opts[key] !== "undefined") {
|
||||
this.api_config[key] = opts[key];
|
||||
}
|
||||
}
|
||||
return callback ? callback(error, connection) : connection;
|
||||
});
|
||||
};
|
||||
|
||||
return this.api_config;
|
||||
};
|
||||
// Public: Starts up the API and the robots
|
||||
//
|
||||
// Returns nothing
|
||||
Cylon.start = function start() {
|
||||
this.startAPI();
|
||||
|
||||
// Public: Finds a particular robot by name
|
||||
//
|
||||
// name - name of the robot to find
|
||||
// callback - optional callback to be executed
|
||||
//
|
||||
// Returns the found Robot or result of the callback if it's supplied
|
||||
Master.prototype.findRobot = function(name, callback) {
|
||||
var error,
|
||||
robot = null;
|
||||
for (var i = 0; i < this.robots.length; i++) {
|
||||
var robot = this.robots[i];
|
||||
robot.start();
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < this.robots.length; i++) {
|
||||
var bot = this.robots[i];
|
||||
if (bot.name === name) { robot = bot; }
|
||||
}
|
||||
// Public: Halts the API and the robots
|
||||
//
|
||||
// Returns nothing
|
||||
Cylon.halt = function halt() {
|
||||
for (var i = 0; i < this.robots.length; i++) {
|
||||
var robot = this.robots[i];
|
||||
robot.halt();
|
||||
}
|
||||
};
|
||||
|
||||
if (robot == null) {
|
||||
error = { error: "No Robot found with the name " + name };
|
||||
}
|
||||
// Creates a new instance of the Cylon API server, or returns the
|
||||
// already-existing one.
|
||||
//
|
||||
// Returns an Cylon.ApiServer instance
|
||||
Cylon.startAPI = function startAPI() {
|
||||
var API = require('./api');
|
||||
this.api_config.master = this;
|
||||
|
||||
return callback ? callback(error, robot) : robot;
|
||||
};
|
||||
if (this.api_instance === null) {
|
||||
this.api_instance = new API(this.api_config);
|
||||
this.api_instance.configureRoutes();
|
||||
this.api_instance.listen();
|
||||
}
|
||||
|
||||
// Public: Finds a particular Robot's device by name
|
||||
//
|
||||
// robotid - name of the robot to find
|
||||
// deviceid - name of the device to find
|
||||
// callback - optional callback to be executed
|
||||
//
|
||||
// Returns the found Device or result of the callback if it's supplied
|
||||
Master.prototype.findRobotDevice = function(robotid, deviceid, callback) {
|
||||
return this.findRobot(robotid, function(err, robot) {
|
||||
var error,
|
||||
device = null;
|
||||
return this.api_instance;
|
||||
};
|
||||
|
||||
if (err) { return callback ? callback(err, robot) : robot }
|
||||
if (process.platform === "win32") {
|
||||
var readline = require("readline"),
|
||||
io = { input: process.stdin, output: process.stdout };
|
||||
|
||||
if (robot.devices[deviceid]) { device = robot.devices[deviceid]; }
|
||||
readline.createInterface(io).on("SIGINT", function() {
|
||||
process.emit("SIGINT");
|
||||
});
|
||||
};
|
||||
|
||||
if (device == null) {
|
||||
error = { error: "No device found with the name " + deviceid + "." };
|
||||
}
|
||||
|
||||
return callback ? callback(error, device) : device;
|
||||
});
|
||||
};
|
||||
|
||||
// Public: Finds a particular Robot's connection by name
|
||||
//
|
||||
// robotid - name of the robot to find
|
||||
// connid - name of the device to find
|
||||
// callback - optional callback to be executed
|
||||
//
|
||||
// Returns the found Connection or result of the callback if it's supplied
|
||||
Master.prototype.findRobotConnection = function(robotid, connid, callback) {
|
||||
return this.findRobot(robotid, function(err, robot) {
|
||||
var error,
|
||||
connection = null;
|
||||
|
||||
if (err) { return callback ? callback(err, robot) : robot }
|
||||
|
||||
if (robot.connections[connid]) { connection = robot.connections[connid]; }
|
||||
|
||||
if (connection == null) {
|
||||
error = { error: "No connection found with the name " + connid + "." };
|
||||
}
|
||||
|
||||
return callback ? callback(error, connection) : connection;
|
||||
});
|
||||
};
|
||||
|
||||
// Public: Starts up the API and the robots
|
||||
//
|
||||
// Returns nothing
|
||||
Master.prototype.start = function() {
|
||||
this.startAPI();
|
||||
|
||||
for (var i = 0; i < this.robots.length; i++) {
|
||||
var robot = this.robots[i];
|
||||
robot.start();
|
||||
}
|
||||
};
|
||||
|
||||
// Public: Halts the API and the robots
|
||||
//
|
||||
// Returns nothing
|
||||
Master.prototype.halt = function() {
|
||||
for (var i = 0; i < this.robots.length; i++) {
|
||||
var robot = this.robots[i];
|
||||
robot.halt();
|
||||
}
|
||||
};
|
||||
|
||||
// Creates a new instance of the Cylon API server, or returns the
|
||||
// already-existing one.
|
||||
//
|
||||
// Returns an Cylon.ApiServer instance
|
||||
Master.prototype.startAPI = function() {
|
||||
var API = require('./api');
|
||||
this.api_config.master = this;
|
||||
|
||||
if (this.api_instance === null) {
|
||||
this.api_instance = new API(this.api_config);
|
||||
this.api_instance.configureRoutes();
|
||||
this.api_instance.listen();
|
||||
}
|
||||
|
||||
return this.api_instance;
|
||||
};
|
||||
|
||||
return Master;
|
||||
|
||||
})();
|
||||
|
||||
return Cylon;
|
||||
|
||||
}).call(this);
|
||||
|
||||
module.exports = Cylon.getInstance();
|
||||
process.on("SIGINT", function() {
|
||||
Cylon.halt();
|
||||
process.kill(process.pid);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue