Extract out Connection/Device initialization

Simple extraction out of Connection/Device initialization code inside
Robot.

This yields an interesting boon, however - this is now a valid Cylon
program:

    var Cylon = require('cylon');

    Cylon
      .robot()
      .connection({ name: 'loopback', adaptor: 'loopback' })
      .device({ name: 'ping', driver: 'ping' })
      .on('ready', function(bot) {
        console.log("Bot working!");

        every(1000, function() {
          console.log(bot.ping.ping());
        })
      });

    Cylon.start();

For those that prefer imperative programs with Cylon, this is a nice
syntax addition.
This commit is contained in:
Andrew Stewart 2014-11-20 08:43:08 -08:00
parent 668acf1e18
commit 15c9b96333
3 changed files with 105 additions and 47 deletions

View File

@ -45,6 +45,8 @@ var Cylon = module.exports = {
// work: (me) -> // work: (me) ->
// me.led.toggle() // me.led.toggle()
Cylon.robot = function robot(opts) { Cylon.robot = function robot(opts) {
opts = opts || {};
// check if a robot with the same name exists already // check if a robot with the same name exists already
if (opts.name && this.robots[opts.name]) { if (opts.name && this.robots[opts.name]) {
var original = opts.name; var original = opts.name;

View File

@ -154,6 +154,20 @@ Robot.prototype.toJSON = function() {
}; };
}; };
Robot.prototype.connection = function(conn) {
conn.robot = this;
if (this.connections[conn.name]) {
var original = conn.name;
conn.name = Utils.makeUnique(original, Object.keys(this.connections));
Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'");
}
this.connections[conn.name] = Connection(conn);
return this;
};
// Public: Initializes all connections for the robot // Public: Initializes all connections for the robot
// //
// opts - options array passed to constructor // opts - options array passed to constructor
@ -164,24 +178,12 @@ Robot.prototype.initConnections = function(opts) {
var isArray = Array.isArray; var isArray = Array.isArray;
var addConnection = function(conn) {
conn.robot = this;
if (this.connections[conn.name]) {
var original = conn.name;
conn.name = Utils.makeUnique(original, Object.keys(this.connections));
Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'");
}
this.connections[conn.name] = Connection(conn);
}.bind(this);
if (opts.connection == null && opts.connections == null) { if (opts.connection == null && opts.connections == null) {
return this.connections; return this.connections;
} }
if (opts.connection) { if (opts.connection) {
addConnection(opts.connection); this.connection(opts.connection);
return this.connections; return this.connections;
} }
@ -189,20 +191,49 @@ Robot.prototype.initConnections = function(opts) {
for (var name in opts.connections) { for (var name in opts.connections) {
var conn = opts.connections[name]; var conn = opts.connections[name];
conn.name = name; conn.name = name;
addConnection(conn); this.connection(conn);
} }
} }
if (isArray(opts.connections)) { if (isArray(opts.connections)) {
Logger.warn("Specifying connections as an array is deprecated, and will be removed in 1.0.0."); Logger.warn("Specifying connections as an array is deprecated, and will be removed in 1.0.0.");
opts.connections.forEach(function(conn) { opts.connections.forEach(function(conn) {
addConnection(conn); this.connection(conn);
}); }.bind(this));
} }
return this.connections; return this.connections;
}; };
Robot.prototype.device = function(device) {
device.robot = this;
if (this.devices[device.name]) {
var original = device.name;
device.name = Utils.makeUnique(original, Object.keys(this.devices));
Logger.warn("Device names must be unique. Renaming '" + original + "' to '" + device.name + "'");
}
if (typeof device.connection === 'string') {
if (this.connections[device.connection] == null) {
var str = "No connection found with the name " + device.connection + ".\n";
Logger.fatal(str);
process.emit('SIGINT');
}
device.connection = this.connections[device.connection];
} else {
for (var conn in this.connections) {
device.connection = this.connections[conn];
break;
}
}
this.devices[device.name] = Device(device);
return this;
}
// Public: Initializes all devices for the robot // Public: Initializes all devices for the robot
// //
// opts - options array passed to constructor // opts - options array passed to constructor
@ -213,33 +244,6 @@ Robot.prototype.initDevices = function(opts) {
var isArray = Array.isArray; var isArray = Array.isArray;
var addDevice = function(device) {
device.robot = this;
if (this.devices[device.name]) {
var original = device.name;
device.name = Utils.makeUnique(original, Object.keys(this.devices));
Logger.warn("Device names must be unique. Renaming '" + original + "' to '" + device.name + "'");
}
if (typeof device.connection === 'string') {
if (this.connections[device.connection] == null) {
var str = "No connection found with the name " + device.connection + ".\n";
Logger.fatal(str);
process.emit('SIGINT');
}
device.connection = this.connections[device.connection];
} else {
for (var conn in this.connections) {
device.connection = this.connections[conn];
break;
}
}
this.devices[device.name] = Device(device);
}.bind(this);
if (opts.device == null && opts.devices == null) { if (opts.device == null && opts.devices == null) {
return this.devices; return this.devices;
} }
@ -250,7 +254,7 @@ Robot.prototype.initDevices = function(opts) {
} }
if (opts.device) { if (opts.device) {
addDevice(opts.device); this.device(opts.device);
return this.devices; return this.devices;
} }
@ -258,15 +262,15 @@ Robot.prototype.initDevices = function(opts) {
for (var name in opts.devices) { for (var name in opts.devices) {
var device = opts.devices[name]; var device = opts.devices[name];
device.name = name; device.name = name;
addDevice(device); this.device(device);
} }
} }
if (isArray(opts.devices)) { if (isArray(opts.devices)) {
Logger.warn("Specifying devices as an array is deprecated, and will be removed in 1.0.0."); Logger.warn("Specifying devices as an array is deprecated, and will be removed in 1.0.0.");
opts.devices.forEach(function(device) { opts.devices.forEach(function(device) {
addDevice(device); this.device(device);
}); }.bind(this));
} }
return this.devices; return this.devices;

View File

@ -225,6 +225,32 @@ describe("Robot", function() {
}); });
}); });
describe("#connection", function() {
var opts, bot;
beforeEach(function() {
bot = new Robot();
opts = { name: 'loopback', adaptor: 'loopback' };
});
it("creates and adds a new Connection", function() {
expect(bot.connections.loopback).to.be.eql(undefined);
bot.connection(opts);
expect(bot.connections.loopback).to.be.an.instanceOf(Adaptor);
})
it("sets @robot on the Connection to be the Robot initializing it", function() {
bot.connection(opts);
expect(bot.connections.loopback.robot).to.be.eql(bot);
})
it("avoids name collisions", function() {
bot.connection(opts);
bot.connection(opts);
expect(Object.keys(bot.connections)).to.be.eql(['loopback', 'loopback-1']);
});
});
describe("initConnections", function() { describe("initConnections", function() {
var bot; var bot;
@ -270,6 +296,32 @@ describe("Robot", function() {
}); });
}); });
describe("#device", function() {
var opts, bot;
beforeEach(function() {
bot = new Robot();
opts = { name: 'ping', driver: 'ping' };
});
it("creates and adds a new Device", function() {
expect(bot.devices.ping).to.be.eql(undefined);
bot.device(opts);
expect(bot.devices.ping).to.be.an.instanceOf(Driver);
})
it("sets @robot on the Device to be the Robot initializing it", function() {
bot.device(opts);
expect(bot.devices.ping.robot).to.be.eql(bot);
})
it("avoids name collisions", function() {
bot.device(opts);
bot.device(opts);
expect(Object.keys(bot.devices)).to.be.eql(['ping', 'ping-1']);
});
});
describe("initDevices", function() { describe("initDevices", function() {
var bot; var bot;