Store robots in an dict, rather than array

Also removes the find{Robot,RobotConnection,RobotDevice} methods. Additionally,
stops passing the Master through to the Robot constructor, we can just
require('./cylon') if we need to access anything in there.
This commit is contained in:
Andrew Stewart 2014-06-06 11:36:22 -07:00
parent 789347f6f8
commit 81fa260963
3 changed files with 18 additions and 258 deletions

View File

@ -26,7 +26,7 @@ var Cylon = module.exports = {
api_instance: null,
robots: []
robots: {}
};
// Public: Creates a new Robot
@ -42,9 +42,8 @@ var Cylon = module.exports = {
// work: (me) ->
// me.led.toggle()
Cylon.robot = function robot(opts) {
opts.master = this;
var robot = new Robot(opts);
this.robots.push(robot);
this.robots[robot.name] = robot;
return robot;
};
@ -62,83 +61,12 @@ Cylon.api = function api(opts) {
this.api_instance.listen();
};
// 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 + "." };
}
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
Cylon.findRobotConnection = function findRobotConnection(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
Cylon.start = function start() {
for (var i = 0; i < this.robots.length; i++) {
var robot = this.robots[i];
robot.start();
for (var bot in this.robots) {
this.robots[bot].start();
}
};
@ -146,9 +74,8 @@ Cylon.start = function start() {
//
// Returns nothing
Cylon.halt = function halt() {
for (var i = 0; i < this.robots.length; i++) {
var robot = this.robots[i];
robot.halt();
for (var bot in this.robots) {
this.robots[bot].halt();
}
};

View File

@ -26,7 +26,6 @@ var Robot;
//
// opts - object containing Robot options
// name - optional, string name of the robot
// master - Cylon.Master class that orchestrates robots
// connection/connections - object connections to connect to
// device/devices - object devices to connect to
// work - work to be performed when the Robot is started
@ -71,7 +70,6 @@ module.exports = Robot = function Robot(opts) {
this.robot = this;
this.name = opts.name || this.constructor.randomName();
this.master = opts.master;
this.connections = {};
this.devices = {};

View File

@ -26,13 +26,13 @@ describe("Cylon", function() {
expect(Cylon.api_instance).to.be.eql(null);
});
it("sets @robots to an empty array by default", function() {
expect(Cylon.robots).to.be.eql([]);
it("sets @robots to an empty object by default", function() {
expect(Cylon.robots).to.be.eql({});
});
describe("#robot", function() {
after(function() {
Cylon.robots = [];
Cylon.robots = {};
});
it("uses passed options to create a new Robot", function() {
@ -40,7 +40,7 @@ describe("Cylon", function() {
var robot = Cylon.robot(opts);
expect(robot.toString()).to.be.eql("[Robot name='Ultron']")
expect(Cylon.robots.pop()).to.be.eql(robot);
expect(Cylon.robots['Ultron']).to.be.eql(robot);
});
});
@ -64,179 +64,15 @@ describe("Cylon", function() {
})
});
describe("#findRobot", function() {
var bot;
before(function() {
bot = Cylon.robot({ name: "Robby" })
});
describe("async", function() {
context("looking for a robot that exists", function() {
it("calls the callback with the robot", function() {
var callback = spy();
Cylon.findRobot("Robby", callback);
expect(callback).to.be.calledWith(undefined, bot);
});
});
context("looking for a robot that does not exist", function(){
it("calls the callback with no robot and an error message", function() {
var callback = spy();
Cylon.findRobot("Ultron", callback);
var error = { error: "No Robot found with the name Ultron" };
expect(callback).to.be.calledWith(error, null);
});
});
});
describe("sync", function() {
context("looking for a robot that exists", function() {
it("returns the robot", function() {
expect(Cylon.findRobot("Robby")).to.be.eql(bot);
});
});
context("looking for a robot that does not exist", function(){
it("returns null", function() {
expect(Cylon.findRobot("Ultron")).to.be.eql(null);
});
});
});
});
describe("#findRobotDevice", function() {
var bot, device;
before(function() {
bot = Cylon.robot({
name: "Ultron",
device: { name: "ping", driver: "ping" }
});
device = bot.devices.ping;
});
describe("async", function() {
context("looking for a valid robot/device", function() {
it("calls the callback with the device and no error message", function() {
var callback = spy();
Cylon.findRobotDevice("Ultron", "ping", callback);
expect(callback).to.be.calledWith(undefined, device);
});
});
context("looking for a valid robot and invalid device", function() {
it("calls the callback with no device and an error message", function() {
var callback = spy();
Cylon.findRobotDevice("Ultron", "nope", callback);
var error = { error: "No device found with the name nope." };
expect(callback).to.be.calledWith(error, null);
});
});
context("looking for an invalid robot", function() {
it("calls the callback with no device and an error message", function() {
var callback = spy();
Cylon.findRobotDevice("Rob", "ping", callback);
var error = { error: "No Robot found with the name Rob" };
expect(callback).to.be.calledWith(error, null);
});
});
});
describe("synchronous", function() {
context("looking for a valid robot/device", function() {
it("returns the device", function() {
expect(Cylon.findRobotDevice("Ultron", "ping")).to.be.eql(device);
});
});
context("looking for a valid robot and invalid device", function() {
it("returns null", function() {
expect(Cylon.findRobotDevice("Ultron", "nope")).to.be.eql(null);
});
});
context("looking for an invalid robot", function() {
it("returns null", function() {
expect(Cylon.findRobotDevice("Rob", "ping")).to.be.eql(null);
});
});
});
});
describe("#findRobotConnection", function() {
var bot, conn;
before(function() {
bot = Cylon.robot({
name: "JARVIS",
connection: { name: "loopback", adaptor: "loopback" }
});
conn = bot.connections.loopback;
});
describe("async", function() {
context("looking for a valid robot/connection", function() {
it("calls the callback with the connection and no error message", function() {
var callback = spy();
Cylon.findRobotConnection("JARVIS", "loopback", callback);
expect(callback).to.be.calledWith(undefined, conn);
});
});
context("looking for a valid robot and invalid connection", function() {
it("calls the callback with no connection and an error message", function() {
var callback = spy();
Cylon.findRobotConnection("JARVIS", "nope", callback);
var error = { error: "No connection found with the name nope." };
expect(callback).to.be.calledWith(error, null);
});
});
context("looking for an invalid robot", function() {
it("calls the callback with no connection and an error message", function() {
var callback = spy();
Cylon.findRobotConnection("Rob", "loopback", callback);
var error = { error: "No Robot found with the name Rob" };
expect(callback).to.be.calledWith(error, null);
});
});
});
describe("synchronous", function() {
context("looking for a valid robot/connection", function() {
it("returns the connection", function() {
expect(Cylon.findRobotConnection("JARVIS", "loopback")).to.be.eql(conn);
});
});
context("looking for a valid robot and invalid connection", function() {
it("returns null", function() {
expect(Cylon.findRobotConnection("JARVIS", "nope")).to.be.eql(null);
});
});
context("looking for an invalid robot", function() {
it("returns null", function() {
expect(Cylon.findRobotConnection("Rob", "loopback")).to.be.eql(null);
});
});
});
});
describe("#start", function() {
before(function() {
Cylon.robots = [];
});
it("calls #start() on all robots", function() {
var bot1 = { start: spy() },
bot2 = { start: spy() };
Cylon.robots = [bot1, bot2];
Cylon.robots = {
'bot1': bot1,
'bot2': bot2
};
Cylon.start();
@ -246,15 +82,14 @@ describe("Cylon", function() {
});
describe("#halt", function() {
before(function() {
Cylon.robots = [];
});
it("calls #halt() on all robots", function() {
var bot1 = { halt: spy() },
bot2 = { halt: spy() };
Cylon.robots = [bot1, bot2];
Cylon.robots = {
'bot1': bot1,
'bot2': bot2
};
Cylon.halt();