From e67ae198826aefc636ea44ebc55de5ee567352a5 Mon Sep 17 00:00:00 2001 From: Andrew Stewart Date: Mon, 10 Nov 2014 15:56:25 -0800 Subject: [PATCH] Remove Connection and Device classes They are now functions that return instances of Adaptors and Drivers respectively. --- lib/adaptor.js | 28 ++++++++++++++- lib/api/routes.js | 8 ++--- lib/basestar.js | 11 +++--- lib/connection.js | 89 +++-------------------------------------------- lib/cylon.js | 2 +- lib/device.js | 84 ++------------------------------------------ lib/driver.js | 31 +++++++++++++---- lib/robot.js | 22 ++++++------ lib/test/ping.js | 2 +- 9 files changed, 80 insertions(+), 197 deletions(-) diff --git a/lib/adaptor.js b/lib/adaptor.js index 6706305..96e48f0 100644 --- a/lib/adaptor.js +++ b/lib/adaptor.js @@ -23,7 +23,33 @@ var Adaptor = module.exports = function Adaptor(opts) { opts = opts || {}; this.name = opts.name; - this.connection = opts.connection; + + // the Robot the adaptor belongs to + this.robot = opts.robot; + + // some default options + this.host = opts.host; + this.port = opts.port; + + // misc. details provided in args hash + this.details = {}; + + for (var opt in opts) { + if (['robot', 'name', 'adaptor'].indexOf(opt) < 0) { + this.details[opt] = opts[opt]; + } + } }; Utils.subclass(Adaptor, Basestar); + +// Public: Expresses the Connection in JSON format +// +// Returns an Object containing Connection data +Adaptor.prototype.toJSON = function() { + return { + name: this.name, + adaptor: this.constructor.name || this.name, + details: this.details + }; +}; diff --git a/lib/api/routes.js b/lib/api/routes.js index f4e100a..7c55bd8 100644 --- a/lib/api/routes.js +++ b/lib/api/routes.js @@ -42,7 +42,7 @@ var load = function load(req, res, next) { }; router.get("/", function(req, res) { - res.json({ MCP: Cylon }); + res.json({ MCP: Cylon.toJSON() }); }); router.get("/commands", function(req, res) { @@ -102,12 +102,12 @@ router.get("/robots/:robot/devices/:device/events/:event", load, function(req, r }); router.get("/robots/:robot/devices/:device/commands", load, function(req, res) { - res.json({ commands: Object.keys(req.device.driver.commands) }); + res.json({ commands: Object.keys(req.device.commands) }); }); router.all("/robots/:robot/devices/:device/commands/:command", load, function(req, res) { - var command = req.device.driver.commands[req.params.command]; - var result = command.apply(req.device.driver, req.commandParams); + var command = req.device.commands[req.params.command]; + var result = command.apply(req.device, req.commandParams); res.json({ result: result }); }); diff --git a/lib/basestar.js b/lib/basestar.js index 129aa74..6d8f83f 100644 --- a/lib/basestar.js +++ b/lib/basestar.js @@ -69,24 +69,23 @@ Basestar.prototype.defineEvent = function(opts) { // Public: Creates an event handler that proxies events from an adaptor's // 'connector' (reference to whatever module is actually talking to the hw) -// to the adaptor's associated connection. +// to the adaptor // // opts - hash of opts to be passed to defineEvent() // // Returns this.connector Basestar.prototype.defineAdaptorEvent = function(opts) { - return this._proxyEvents(opts, this.connector, this.connection); + return this._proxyEvents(opts, this.connector, this); }; -// Public: Creates an event handler that proxies events from an device's -// 'connector' (reference to whatever module is actually talking to the hw) -// to the device's associated connection. +// Public: Creates an event handler that proxies events from an driver's +// adaptor to the driver // // opts - hash of opts to be passed to defineEvent() // // Returns this.connection Basestar.prototype.defineDriverEvent = function(opts) { - return this._proxyEvents(opts, this.connection, this.device); + return this._proxyEvents(opts, this.adaptor, this); }; Basestar.prototype._proxyEvents = function(opts, source, target) { diff --git a/lib/connection.js b/lib/connection.js index 94291d6..33a4af2 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -8,18 +8,15 @@ 'use strict'; -var EventEmitter = require('events').EventEmitter; - var Registry = require('./registry'), Config = require('./config'), - Logger = require('./logger'), - Utils = require('./utils'); + Logger = require('./logger'); var testMode = function() { return process.env.NODE_ENV === 'test' && Config.testMode; }; -// Public: Creates a new Connection +// Public: Creates a new Adaptor and returns it. // // opts - hash of acceptable params: // robot - Robot the Connection belongs to @@ -28,81 +25,17 @@ var testMode = function() { // port - string port to use for the Connection // // Returns the newly set-up connection -var Connection = module.exports = function Connection(opts) { - opts = opts || {}; - - this.connect = this.connect.bind(this); - - this.robot = opts.robot; - this.name = opts.name; - this.port = opts.port; - this.adaptor = this.initAdaptor(opts); - - this.details = {}; - - for (var opt in opts) { - if (['robot', 'name', 'adaptor', 'connection'].indexOf(opt) < 0) { - this.details[opt] = opts[opt]; - } - } -}; - -Utils.subclass(Connection, EventEmitter); - -// Public: Expresses the Connection in JSON format -// -// Returns an Object containing Connection data -Connection.prototype.toJSON = function() { - return { - name: this.name, - adaptor: this.adaptor.constructor.name || this.adaptor.name, - details: this.details - }; -}; - -// Public: Connect the adaptor's connection -// -// callback - callback function to run when the adaptor is connected -// -// Returns nothing -Connection.prototype.connect = function(callback) { - var msg = this._logstring("Connecting to"); - Logger.info(msg); - this.adaptor.connect(function() { - Utils.proxyFunctions(this.adaptor, this) - callback.apply(this, arguments); - }.bind(this)); -}; - -// Public: Disconnect the adaptor's connection -// -// callback - function to be triggered then the adaptor has disconnected -// -// Returns nothing -Connection.prototype.disconnect = function(callback) { - var msg = this._logstring("Disconnecting from"); - Logger.info(msg); - this.removeAllListeners(); - this.adaptor.disconnect(callback); -}; - -// Public: sets up adaptor with @robot -// -// opts - options for adaptor being initialized -// adaptor - name of the adaptor -// -// Returns the set-up adaptor -Connection.prototype.initAdaptor = function(opts) { +module.exports = function Connection(opts) { var module; + opts = opts || {}; + if (opts.module) { module = Registry.register(opts.module); } else { module = Registry.findByAdaptor(opts.adaptor); } - opts.connection = this; - if (!module) { Registry.register('cylon-' + opts.adaptor); module = Registry.findByAdaptor(opts.adaptor); @@ -124,15 +57,3 @@ Connection.prototype.initAdaptor = function(opts) { return adaptor; }; - -Connection.prototype._logstring = function _logstring(action) { - var msg = action + " '" + this.name + "'"; - - if (this.port != null) { - msg += " on port " + this.port; - } - - msg += "."; - - return msg; -}; diff --git a/lib/cylon.js b/lib/cylon.js index 9e7cb9a..33c9636 100644 --- a/lib/cylon.js +++ b/lib/cylon.js @@ -133,7 +133,7 @@ Cylon.toJSON = function() { var robots = []; for (var bot in this.robots) { - robots.push(this.robots[bot]); + robots.push(this.robots[bot].toJSON()); } return { diff --git a/lib/device.js b/lib/device.js index 2475f99..4d0f0dc 100644 --- a/lib/device.js +++ b/lib/device.js @@ -8,12 +8,8 @@ 'use strict'; -var EventEmitter = require('events').EventEmitter; - var Registry = require('./registry'), - Config = require('./config'), - Logger = require('./logger'), - Utils = require('./utils'); + Config = require('./config'); var testMode = function() { return process.env.NODE_ENV === 'test' && Config.testMode; @@ -29,83 +25,7 @@ var testMode = function() { // driver - string name of the module the device driver logic lives in // // Returns a new Device -var Device = module.exports = function Device(opts) { - if (opts == null) { - opts = {}; - } - - this.halt = this.halt.bind(this); - this.start = this.start.bind(this); - - this.robot = opts.robot; - this.name = opts.name; - this.pin = opts.pin; - this.connection = opts.connection; - this.driver = this.initDriver(opts); - - this.details = {}; - - for (var opt in opts) { - if (['robot', 'name', 'connection', 'driver', 'device', 'adaptor'].indexOf(opt) < 0) { - this.details[opt] = opts[opt]; - } - } -}; - -Utils.subclass(Device, EventEmitter); - -// Public: Starts the device driver -// -// callback - callback function to be executed by the driver start -// -// Returns nothing -Device.prototype.start = function(callback) { - var msg = "Starting device '" + this.name + "'"; - - if (this.pin != null) { - msg += " on pin " + this.pin; - } - - msg += "."; - - Logger.info(msg); - this.driver.start(function() { - Utils.proxyFunctions(this.driver, this) - callback.apply(this, arguments); - }.bind(this)); -}; - -// Public: Halt the device driver -// -// callback - function to trigger when the device has been halted -// -// Returns nothing -Device.prototype.halt = function(callback) { - Logger.info("Halting device '" + this.name + "'."); - this.removeAllListeners(); - this.driver.halt(callback); -}; - -// Public: Expresses the Device in JSON format -// -// Returns an Object containing Connection data -Device.prototype.toJSON = function() { - return { - name: this.name, - driver: this.driver.constructor.name || this.driver.name, - connection: this.connection.name, - commands: Object.keys(this.driver.commands), - details: this.details - }; -}; - -// Public: sets up driver with @robot -// -// opts - object containing options when initializing driver -// driver - name of the driver to intt() -// -// Returns the set-up driver -Device.prototype.initDriver = function(opts) { +module.exports = function Device(opts) { var module; if (opts.module) { diff --git a/lib/driver.js b/lib/driver.js index 472f9f6..615df9d 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -23,21 +23,30 @@ var Driver = module.exports = function Driver(opts) { opts = opts || {}; this.name = opts.name; + this.robot = opts.robot - this.device = opts.device; - this.connection = opts.device.connection; - this.adaptor = this.connection.adaptor; - - this.interval = opts.interval || 10; + this.adaptor = opts.adaptor this.commands = {}; + + // some default options + this.pin = opts.pin; + this.interval = opts.interval || 10; + + this.details = {}; + + for (var opt in opts) { + if (['robot', 'name', 'adaptor', 'driver'].indexOf(opt) < 0) { + this.details[opt] = opts[opt]; + } + } }; Utils.subclass(Driver, Basestar); Driver.prototype.setupCommands = function(commands, proxy) { if (proxy == null) { - proxy = this.connection; + proxy = this.adaptor; } this.proxyMethods(commands, proxy, this); @@ -58,3 +67,13 @@ Driver.prototype.setupCommands = function(commands, proxy) { this.commands[snake_case] = this[command]; } } + +Driver.prototype.toJSON = function() { + return { + name: this.name, + driver: this.constructor.name || this.name, + connection: this.adaptor.name, + commands: Object.keys(this.commands), + details: this.details + }; +}; diff --git a/lib/robot.js b/lib/robot.js index a527847..168b06b 100644 --- a/lib/robot.js +++ b/lib/robot.js @@ -139,11 +139,11 @@ Robot.prototype.toJSON = function() { n; for (n in this.connections) { - connections.push(this.connections[n]); + connections.push(this.connections[n].toJSON()); } for (n in this.devices) { - devices.push(this.devices[n]); + devices.push(this.devices[n].toJSON()); } return { @@ -173,7 +173,7 @@ Robot.prototype.initConnections = function(opts) { Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'"); } - this.connections[conn.name] = new Connection(conn); + this.connections[conn.name] = Connection(conn); }.bind(this); if (opts.connection == null && opts.connections == null) { @@ -229,15 +229,15 @@ Robot.prototype.initDevices = function(opts) { process.emit('SIGINT'); } - device.connection = this.connections[device.connection]; + device.adaptor = this.connections[device.connection]; } else { for (var conn in this.connections) { - device.connection = this.connections[conn]; + device.adaptor = this.connections[conn]; break; } } - this.devices[device.name] = new Device(device); + this.devices[device.name] = Device(device); }.bind(this); if (opts.device == null && opts.devices == null) { @@ -334,9 +334,8 @@ Robot.prototype.startConnections = function(callback) { Logger.info("Starting connections."); for (var n in this.connections) { - var connection = this.connections[n]; - this[n] = connection; - starters[n] = connection.connect; + this[n] = this.connections[n]; + starters[n] = this.connections[n].connect; } return Async.parallel(starters, callback); @@ -353,9 +352,8 @@ Robot.prototype.startDevices = function(callback) { Logger.info("Starting devices."); for (var n in this.devices) { - var device = this.devices[n]; - this[n] = device; - starters[n] = device.start; + this[n] = this.devices[n]; + starters[n] = this.devices[n].start; } return Async.parallel(starters, callback); diff --git a/lib/test/ping.js b/lib/test/ping.js index 47564e3..c9348a9 100644 --- a/lib/test/ping.js +++ b/lib/test/ping.js @@ -22,7 +22,7 @@ var Ping = module.exports = function Ping() { Utils.subclass(Ping, Driver); Ping.prototype.ping = function() { - this.device.emit('ping', 'ping'); + this.emit('ping', 'ping'); return "pong"; };