Clean up lib for JSHint
This commit is contained in:
parent
e2bec78de7
commit
ac6b09fe50
|
@ -8,9 +8,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Basestar = require('./basestar'),
|
||||
Logger = require('./logger'),
|
||||
Utils = require('./utils');
|
||||
var Basestar = require("./basestar"),
|
||||
Utils = require("./utils");
|
||||
|
||||
// Public: Creates a new Adaptor
|
||||
//
|
||||
|
@ -35,7 +34,7 @@ var Adaptor = module.exports = function Adaptor(opts) {
|
|||
this.details = {};
|
||||
|
||||
for (var opt in opts) {
|
||||
if (['robot', 'name', 'adaptor'].indexOf(opt) < 0) {
|
||||
if (["robot", "name", "adaptor"].indexOf(opt) < 0) {
|
||||
this.details[opt] = opts[opt];
|
||||
}
|
||||
}
|
||||
|
|
48
lib/api.js
48
lib/api.js
|
@ -8,13 +8,13 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var fs = require('fs'),
|
||||
path = require('path');
|
||||
var fs = require("fs"),
|
||||
path = require("path");
|
||||
|
||||
var express = require('express'),
|
||||
bodyParser = require('body-parser');
|
||||
var express = require("express"),
|
||||
bodyParser = require("body-parser");
|
||||
|
||||
var Logger = require('./logger');
|
||||
var Logger = require("./logger");
|
||||
|
||||
var API = module.exports = function API(opts) {
|
||||
if (opts == null) {
|
||||
|
@ -27,7 +27,7 @@ var API = module.exports = function API(opts) {
|
|||
|
||||
this.createServer();
|
||||
|
||||
this.express.set('title', 'Cylon API Server');
|
||||
this.express.set("title", "Cylon API Server");
|
||||
|
||||
this.express.use(this.setupAuth());
|
||||
|
||||
|
@ -40,7 +40,7 @@ var API = module.exports = function API(opts) {
|
|||
this.express.use(function(req, res, next) {
|
||||
res.set("Access-Control-Allow-Origin", this.CORS || "*");
|
||||
res.set("Access-Control-Allow-Headers", "Content-Type");
|
||||
res.set('Content-Type', 'application/json');
|
||||
res.set("Content-Type", "application/json");
|
||||
return next();
|
||||
}.bind(this));
|
||||
|
||||
|
@ -56,19 +56,19 @@ var API = module.exports = function API(opts) {
|
|||
});
|
||||
|
||||
// load route definitions
|
||||
this.express.use('/api', require('./api/routes'));
|
||||
this.express.use("/api", require("./api/routes"));
|
||||
|
||||
// error handling
|
||||
this.express.use(function(err, req, res, next) {
|
||||
res.status(500).json({ error: err.message || "An error occured."})
|
||||
this.express.use(function(err, req, res) {
|
||||
res.status(500).json({ error: err.message || "An error occured."});
|
||||
});
|
||||
};
|
||||
|
||||
API.prototype.defaults = {
|
||||
host: '127.0.0.1',
|
||||
port: '3000',
|
||||
host: "127.0.0.1",
|
||||
port: "3000",
|
||||
auth: false,
|
||||
CORS: '',
|
||||
CORS: "",
|
||||
ssl: {
|
||||
key: path.normalize(__dirname + "/api/ssl/server.key"),
|
||||
cert: path.normalize(__dirname + "/api/ssl/server.crt")
|
||||
|
@ -79,15 +79,18 @@ API.prototype.createServer = function createServer() {
|
|||
this.express = express();
|
||||
|
||||
//configure ssl if requested
|
||||
if (this.ssl && typeof(this.ssl) === 'object') {
|
||||
var https = require('https');
|
||||
if (this.ssl && typeof(this.ssl) === "object") {
|
||||
var https = require("https");
|
||||
|
||||
this.server = https.createServer({
|
||||
key: fs.readFileSync(this.ssl.key),
|
||||
cert: fs.readFileSync(this.ssl.cert)
|
||||
}, this.express);
|
||||
} else {
|
||||
Logger.warn("API using insecure connection. We recommend using an SSL certificate with Cylon.");
|
||||
var str = "API using insecure connection. ";
|
||||
str += "We recommend using an SSL certificate with Cylon.";
|
||||
|
||||
Logger.warn(str);
|
||||
this.server = this.express;
|
||||
}
|
||||
};
|
||||
|
@ -95,7 +98,7 @@ API.prototype.createServer = function createServer() {
|
|||
API.prototype.setupAuth = function setupAuth() {
|
||||
var authfn = function auth(req, res, next) { next(); };
|
||||
|
||||
if (!!this.auth && typeof(this.auth) === 'object' && this.auth.type) {
|
||||
if (!!this.auth && typeof(this.auth) === "object" && this.auth.type) {
|
||||
var type = this.auth.type,
|
||||
module = "./api/auth/" + type,
|
||||
filename = path.normalize(__dirname + "/" + module + ".js"),
|
||||
|
@ -104,17 +107,20 @@ API.prototype.setupAuth = function setupAuth() {
|
|||
if (exists) {
|
||||
authfn = require(filename)(this.auth);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return authfn;
|
||||
};
|
||||
|
||||
API.prototype.listen = function() {
|
||||
this.server.listen(this.port, this.host, null, function() {
|
||||
var title = this.express.get('title');
|
||||
var protocol = this.ssl ? "https" : "http";
|
||||
var title = this.express.get("title");
|
||||
var protocol = this.ssl ? "https" : "http",
|
||||
str;
|
||||
|
||||
str = "Listening at " + protocol + "://" + this.host + ":" + this.port;
|
||||
|
||||
Logger.info(title + " is now online.");
|
||||
Logger.info("Listening at " + protocol + "://" + this.host + ":" + this.port);
|
||||
Logger.info(str);
|
||||
}.bind(this));
|
||||
};
|
||||
|
|
|
@ -6,48 +6,14 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
var http = require('http');
|
||||
"use strict";
|
||||
|
||||
module.exports = function(config) {
|
||||
var user = config.user,
|
||||
pass = config.pass;
|
||||
|
||||
return function auth(req, res, next) {
|
||||
var auth = req.headers.authorization;
|
||||
|
||||
if (!auth) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
// malformed
|
||||
var parts = auth.split(' ');
|
||||
|
||||
if ('basic' != parts[0].toLowerCase() || !parts[1]) {
|
||||
return next(error(400));
|
||||
}
|
||||
|
||||
auth = parts[1];
|
||||
|
||||
// credentials
|
||||
auth = new Buffer(auth, 'base64').toString();
|
||||
auth = auth.match(/^([^:]+):(.+)$/);
|
||||
|
||||
if (!auth) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
if (auth[1] === user && auth[2] === pass) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return unauthorized(res);
|
||||
};
|
||||
};
|
||||
var http = require("http");
|
||||
|
||||
var unauthorized = function unauthorized(res) {
|
||||
res.statusCode = 401;
|
||||
res.setHeader('WWW-Authenticate', 'Basic realm="Authorization Required"');
|
||||
res.end('Unauthorized');
|
||||
res.setHeader("WWW-Authenticate", "Basic realm=\"Authorization Required\"");
|
||||
res.end("Unauthorized");
|
||||
};
|
||||
|
||||
var error = function error(code, msg){
|
||||
|
@ -55,3 +21,39 @@ var error = function error(code, msg){
|
|||
err.status = code;
|
||||
return err;
|
||||
};
|
||||
|
||||
module.exports = function(config) {
|
||||
var user = config.user,
|
||||
pass = config.pass;
|
||||
|
||||
return function auth(req, res, next) {
|
||||
var authorization = req.headers.authorization;
|
||||
|
||||
if (!authorization) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
// malformed
|
||||
var parts = authorization.split(" ");
|
||||
|
||||
if ("basic" !== parts[0].toLowerCase() || !parts[1]) {
|
||||
return next(error(400));
|
||||
}
|
||||
|
||||
authorization = parts[1];
|
||||
|
||||
// credentials
|
||||
authorization = new Buffer(authorization, "base64").toString();
|
||||
authorization = authorization.match(/^([^:]+):(.+)$/);
|
||||
|
||||
if (!authorization) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
if (authorization[1] === user && authorization[2] === pass) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return unauthorized(res);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* jshint maxlen: false */
|
||||
|
||||
/*
|
||||
* Cylon API - Route Definitions
|
||||
* cylonjs.com
|
||||
|
@ -6,9 +8,11 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
var Cylon = require('../cylon');
|
||||
"use strict";
|
||||
|
||||
var router = module.exports = require('express').Router();
|
||||
var Cylon = require("../cylon");
|
||||
|
||||
var router = module.exports = require("express").Router();
|
||||
|
||||
// Loads up the appropriate Robot/Device/Connection instances, if they are
|
||||
// present in the route params.
|
||||
|
@ -20,21 +24,27 @@ var load = function load(req, res, next) {
|
|||
if (robot) {
|
||||
req.robot = Cylon.robots[robot];
|
||||
if (!req.robot) {
|
||||
return res.status(404).json({ error: "No Robot found with the name " + robot });
|
||||
return res.status(404).json({
|
||||
error: "No Robot found with the name " + robot
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (device) {
|
||||
req.device = req.robot.devices[device];
|
||||
if (!req.device) {
|
||||
return res.status(404).json({ error: "No device found with the name " + device });
|
||||
return res.status(404).json({
|
||||
error: "No device found with the name " + device
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (connection) {
|
||||
req.connection = req.robot.connections[connection];
|
||||
if (!req.connection) {
|
||||
return res.status(404).json({ error: "No connection found with the name " + connection });
|
||||
return res.status(404).json({
|
||||
error: "No connection found with the name " + connection
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,9 +95,9 @@ router.get("/robots/:robot/devices/:device/events/:event", load, function(req, r
|
|||
var event = req.params.event;
|
||||
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'text/event-stream',
|
||||
'Connection': 'keep-alive',
|
||||
'Cache-Control': 'no-cache'
|
||||
"Content-Type": "text/event-stream",
|
||||
"Connection": "keep-alive",
|
||||
"Cache-Control": "no-cache"
|
||||
});
|
||||
|
||||
var writeData = function(data) {
|
||||
|
@ -96,7 +106,7 @@ router.get("/robots/:robot/devices/:device/events/:event", load, function(req, r
|
|||
|
||||
req.device.on(event, writeData);
|
||||
|
||||
res.on('close', function() {
|
||||
res.on("close", function() {
|
||||
req.device.removeListener(event, writeData);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var EventEmitter = require("events").EventEmitter;
|
||||
|
||||
var Utils = require('./utils');
|
||||
var Utils = require("./utils");
|
||||
|
||||
// Basestar is a base class to be used when writing external Cylon adaptors and
|
||||
// drivers. It provides some useful base methods and functionality
|
||||
|
@ -46,7 +46,7 @@ Basestar.prototype.proxyMethods = function(methods, target, source, force) {
|
|||
// target
|
||||
// - target - object to proxy event to
|
||||
// - source - object to proxy event from
|
||||
// - sendUpdate - whether or not to send an 'update' event
|
||||
// - sendUpdate - whether or not to send an "update" event
|
||||
//
|
||||
// Returns the source
|
||||
Basestar.prototype.defineEvent = function(opts) {
|
||||
|
@ -59,7 +59,7 @@ Basestar.prototype.defineEvent = function(opts) {
|
|||
opts.target.emit.apply(opts.target, args);
|
||||
|
||||
if (opts.sendUpdate) {
|
||||
args.unshift('update');
|
||||
args.unshift("update");
|
||||
opts.target.emit.apply(opts.target, args);
|
||||
}
|
||||
});
|
||||
|
@ -67,8 +67,8 @@ Basestar.prototype.defineEvent = function(opts) {
|
|||
return opts.source;
|
||||
};
|
||||
|
||||
// Public: Creates an event handler that proxies events from an adaptor's
|
||||
// 'connector' (reference to whatever module is actually talking to the hw)
|
||||
// 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
|
||||
//
|
||||
// opts - hash of opts to be passed to defineEvent()
|
||||
|
@ -78,7 +78,7 @@ Basestar.prototype.defineAdaptorEvent = function(opts) {
|
|||
return this._proxyEvents(opts, this.connector, this);
|
||||
};
|
||||
|
||||
// Public: Creates an event handler that proxies events from a driver's
|
||||
// Public: Creates an event handler that proxies events from a driver"s
|
||||
// connection to the driver
|
||||
//
|
||||
// opts - hash of opts to be passed to defineEvent()
|
||||
|
@ -89,10 +89,10 @@ Basestar.prototype.defineDriverEvent = function(opts) {
|
|||
};
|
||||
|
||||
Basestar.prototype._proxyEvents = function(opts, source, target) {
|
||||
opts = (typeof opts === 'string') ? { eventName: opts } : opts;
|
||||
opts = (typeof opts === "string") ? { eventName: opts } : opts;
|
||||
|
||||
opts.source = source;
|
||||
opts.target = target
|
||||
opts.target = target;
|
||||
|
||||
return this.defineEvent(opts);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
logging: {},
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var Registry = require('./registry'),
|
||||
Config = require('./config'),
|
||||
Logger = require('./logger');
|
||||
var Registry = require("./registry"),
|
||||
Config = require("./config");
|
||||
|
||||
var testMode = function() {
|
||||
return process.env.NODE_ENV === 'test' && Config.testMode;
|
||||
return process.env.NODE_ENV === "test" && Config.testMode;
|
||||
};
|
||||
|
||||
// Public: Creates a new Adaptor and returns it.
|
||||
|
@ -26,7 +25,8 @@ var testMode = function() {
|
|||
//
|
||||
// Returns the newly set-up connection
|
||||
module.exports = function Connection(opts) {
|
||||
var module;
|
||||
var module,
|
||||
prop;
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
|
@ -37,27 +37,27 @@ module.exports = function Connection(opts) {
|
|||
}
|
||||
|
||||
if (!module) {
|
||||
Registry.register('cylon-' + opts.adaptor);
|
||||
Registry.register("cylon-" + opts.adaptor);
|
||||
module = Registry.findByAdaptor(opts.adaptor);
|
||||
}
|
||||
|
||||
var adaptor = module.adaptor(opts);
|
||||
|
||||
for (var prop in adaptor) {
|
||||
if (~['constructor'].indexOf(prop)) {
|
||||
for (prop in adaptor) {
|
||||
if (~["constructor"].indexOf(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof adaptor[prop] === 'function') {
|
||||
if (typeof adaptor[prop] === "function") {
|
||||
adaptor[prop] = adaptor[prop].bind(adaptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (testMode()) {
|
||||
var testAdaptor = Registry.findByAdaptor('test').adaptor(opts);
|
||||
var testAdaptor = Registry.findByAdaptor("test").adaptor(opts);
|
||||
|
||||
for (var prop in adaptor) {
|
||||
if (typeof adaptor[prop] === 'function' && !testAdaptor[prop]) {
|
||||
for (prop in adaptor) {
|
||||
if (typeof adaptor[prop] === "function" && !testAdaptor[prop]) {
|
||||
testAdaptor[prop] = function() { return true; };
|
||||
}
|
||||
}
|
||||
|
|
59
lib/cylon.js
59
lib/cylon.js
|
@ -8,22 +8,22 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Async = require('async');
|
||||
var Async = require("async");
|
||||
|
||||
var Logger = require('./logger'),
|
||||
Robot = require('./robot'),
|
||||
Config = require('./config'),
|
||||
Utils = require('./utils');
|
||||
var Logger = require("./logger"),
|
||||
Robot = require("./robot"),
|
||||
Config = require("./config"),
|
||||
Utils = require("./utils");
|
||||
|
||||
var Cylon = module.exports = {
|
||||
Logger: Logger,
|
||||
Driver: require('./driver'),
|
||||
Adaptor: require('./adaptor'),
|
||||
Driver: require("./driver"),
|
||||
Adaptor: require("./adaptor"),
|
||||
Utils: Utils,
|
||||
|
||||
IO: {
|
||||
DigitalPin: require('./io/digital-pin'),
|
||||
Utils: require('./io/utils')
|
||||
DigitalPin: require("./io/digital-pin"),
|
||||
Utils: require("./io/utils")
|
||||
},
|
||||
|
||||
api_instance: null,
|
||||
|
@ -39,8 +39,8 @@ var Cylon = module.exports = {
|
|||
// Returns a shiny new Robot
|
||||
// Examples:
|
||||
// Cylon.robot
|
||||
// connection: { name: 'arduino', adaptor: 'firmata' }
|
||||
// device: { name: 'led', driver: 'led', pin: 13 }
|
||||
// connection: { name: "arduino", adaptor: "firmata" }
|
||||
// device: { name: "led", driver: "led", pin: 13 }
|
||||
//
|
||||
// work: (me) ->
|
||||
// me.led.toggle()
|
||||
|
@ -51,25 +51,29 @@ Cylon.robot = function robot(opts) {
|
|||
if (opts.name && this.robots[opts.name]) {
|
||||
var original = opts.name;
|
||||
opts.name = Utils.makeUnique(original, Object.keys(this.robots));
|
||||
Logger.warn("Robot names must be unique. Renaming '" + original + "' to '" + opts.name + "'");
|
||||
|
||||
var str = "Robot names must be unique. Renaming '";
|
||||
str += original + "' to '" + opts.name + "'";
|
||||
|
||||
Logger.warn(str);
|
||||
}
|
||||
|
||||
var robot = new Robot(opts);
|
||||
this.robots[robot.name] = robot;
|
||||
return robot;
|
||||
var bot = new Robot(opts);
|
||||
this.robots[bot.name] = bot;
|
||||
return bot;
|
||||
};
|
||||
|
||||
// Public: Creates a new API based on passed options
|
||||
//
|
||||
// Returns nothing
|
||||
Cylon.api = function api(opts) {
|
||||
if (typeof opts === 'object') {
|
||||
if (typeof opts === "object") {
|
||||
this.config({ api: opts });
|
||||
}
|
||||
|
||||
var API = require('./api');
|
||||
var API = require("./api");
|
||||
|
||||
var config = Utils.fetch(Config, 'api', {});
|
||||
var config = Utils.fetch(Config, "api", {});
|
||||
|
||||
this.api_instance = new API(config);
|
||||
this.api_instance.listen();
|
||||
|
@ -83,13 +87,14 @@ Cylon.start = function start() {
|
|||
for (var bot in this.robots) {
|
||||
starters.push(this.robots[bot].start);
|
||||
}
|
||||
Async.parallel(starters, function(err, results) {
|
||||
var mode = Utils.fetch(Config, 'workMode', 'async');
|
||||
if (mode === 'sync') {
|
||||
Async.parallel(starters, function() {
|
||||
var mode = Utils.fetch(Config, "workMode", "async");
|
||||
|
||||
if (mode === "sync") {
|
||||
for (var bot in this.robots) {
|
||||
this.robots[bot].startWork();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
@ -101,7 +106,7 @@ Cylon.start = function start() {
|
|||
Cylon.config = function(opts) {
|
||||
var loggingChanged = (opts.logging && Config.logging !== opts.logging);
|
||||
|
||||
if (opts && typeof(opts) === 'object' && !Array.isArray(opts)) {
|
||||
if (opts && typeof(opts) === "object" && !Array.isArray(opts)) {
|
||||
for (var o in opts) {
|
||||
Config[o] = opts[o];
|
||||
}
|
||||
|
@ -120,9 +125,9 @@ Cylon.config = function(opts) {
|
|||
//
|
||||
// Returns nothing
|
||||
Cylon.halt = function halt(callback) {
|
||||
callback = callback || function() {}
|
||||
// if robots can't shut down quickly enough, forcefully self-terminate
|
||||
var timeout = Config.haltTimeout || 3000
|
||||
callback = callback || function() {};
|
||||
// if robots can"t shut down quickly enough, forcefully self-terminate
|
||||
var timeout = Config.haltTimeout || 3000;
|
||||
Utils.after(timeout, callback);
|
||||
|
||||
var fns = [];
|
||||
|
@ -145,7 +150,7 @@ Cylon.toJSON = function() {
|
|||
return {
|
||||
robots: robots,
|
||||
commands: Object.keys(this.commands)
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if (process.platform === "win32") {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var Registry = require('./registry'),
|
||||
Config = require('./config');
|
||||
var Registry = require("./registry"),
|
||||
Config = require("./config");
|
||||
|
||||
var testMode = function() {
|
||||
return process.env.NODE_ENV === 'test' && Config.testMode;
|
||||
return process.env.NODE_ENV === "test" && Config.testMode;
|
||||
};
|
||||
|
||||
// Public: Creates a new Device
|
||||
|
@ -26,7 +26,8 @@ var testMode = function() {
|
|||
//
|
||||
// Returns a new Device
|
||||
module.exports = function Device(opts) {
|
||||
var module;
|
||||
var module,
|
||||
prop;
|
||||
|
||||
if (opts.module) {
|
||||
module = Registry.register(opts.module);
|
||||
|
@ -37,27 +38,27 @@ module.exports = function Device(opts) {
|
|||
opts.device = this;
|
||||
|
||||
if (!module) {
|
||||
Registry.register('cylon-' + opts.driver);
|
||||
Registry.register("cylon-" + opts.driver);
|
||||
module = Registry.findByDriver(opts.driver);
|
||||
}
|
||||
|
||||
var driver = module.driver(opts);
|
||||
|
||||
for (var prop in driver) {
|
||||
if (~['constructor'].indexOf(prop)) {
|
||||
for (prop in driver) {
|
||||
if (~["constructor"].indexOf(prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof driver[prop] === 'function') {
|
||||
if (typeof driver[prop] === "function") {
|
||||
driver[prop] = driver[prop].bind(driver);
|
||||
}
|
||||
}
|
||||
|
||||
if (testMode()) {
|
||||
var testDriver = Registry.findByDriver('test').driver(opts);
|
||||
var testDriver = Registry.findByDriver("test").driver(opts);
|
||||
|
||||
for (var prop in driver) {
|
||||
if (typeof driver[prop] === 'function' && !testDriver[prop]) {
|
||||
for (prop in driver) {
|
||||
if (typeof driver[prop] === "function" && !testDriver[prop]) {
|
||||
testDriver[prop] = function() { return true; };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,10 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var Basestar = require('./basestar'),
|
||||
Logger = require('./logger'),
|
||||
Utils = require('./utils');
|
||||
var Basestar = require("./basestar"),
|
||||
Utils = require("./utils");
|
||||
|
||||
// Public: Creates a new Driver
|
||||
//
|
||||
|
@ -23,7 +22,7 @@ var Driver = module.exports = function Driver(opts) {
|
|||
opts = opts || {};
|
||||
|
||||
this.name = opts.name;
|
||||
this.robot = opts.robot
|
||||
this.robot = opts.robot;
|
||||
|
||||
this.connection = opts.connection;
|
||||
|
||||
|
@ -36,7 +35,7 @@ var Driver = module.exports = function Driver(opts) {
|
|||
this.details = {};
|
||||
|
||||
for (var opt in opts) {
|
||||
if (['robot', 'name', 'connection', 'driver'].indexOf(opt) < 0) {
|
||||
if (["robot", "name", "connection", "driver"].indexOf(opt) < 0) {
|
||||
this.details[opt] = opts[opt];
|
||||
}
|
||||
}
|
||||
|
@ -62,11 +61,11 @@ Driver.prototype.setupCommands = function(commands, proxy) {
|
|||
}
|
||||
|
||||
return "_" + match.toLowerCase();
|
||||
}).replace(/^_/, '');
|
||||
}).replace(/^_/, "");
|
||||
|
||||
this.commands[snake_case] = this[command];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Driver.prototype.toJSON = function() {
|
||||
return {
|
||||
|
|
|
@ -8,24 +8,21 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var FS = require('fs'),
|
||||
EventEmitter = require('events').EventEmitter;
|
||||
var FS = require("fs"),
|
||||
EventEmitter = require("events").EventEmitter;
|
||||
|
||||
var Utils = require('../utils');
|
||||
var Utils = require("../utils");
|
||||
|
||||
var GPIO_PATH = "/sys/class/gpio";
|
||||
|
||||
var GPIO_READ = "in";
|
||||
var GPIO_WRITE = "out";
|
||||
|
||||
var HIGH = 1;
|
||||
var LOW = 0;
|
||||
|
||||
// DigitalPin class offers an interface with the Linux GPIO system present in
|
||||
// single-board computers such as a Raspberry Pi, or a BeagleBone
|
||||
var DigitalPin = module.exports = function DigitalPin(opts) {
|
||||
this.pinNum = opts.pin.toString();
|
||||
this.status = 'low';
|
||||
this.status = "low";
|
||||
this.ready = false;
|
||||
this.mode = opts.mode;
|
||||
};
|
||||
|
@ -38,7 +35,11 @@ DigitalPin.prototype.connect = function(mode) {
|
|||
}
|
||||
|
||||
FS.exists(this._pinPath(), function(exists) {
|
||||
exists ? this._openPin() : this._createGPIOPin();
|
||||
if (exists) {
|
||||
this._openPin();
|
||||
} else {
|
||||
this._createGPIOPin();
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
|
@ -54,40 +55,43 @@ DigitalPin.prototype.closeSync = function() {
|
|||
};
|
||||
|
||||
DigitalPin.prototype.digitalWrite = function(value) {
|
||||
if (this.mode !== 'w') {
|
||||
this._setMode('w');
|
||||
if (this.mode !== "w") {
|
||||
this._setMode("w");
|
||||
}
|
||||
|
||||
this.status = value === 1 ? 'high' : 'low';
|
||||
this.status = value === 1 ? "high" : "low";
|
||||
|
||||
FS.writeFile(this._valuePath(), value, function(err) {
|
||||
if (err) {
|
||||
this.emit('error', "Error occurred while writing value " + value + " to pin " + this.pinNum);
|
||||
var str = "Error occurred while writing value ";
|
||||
str += value + " to pin " + this.pinNum;
|
||||
|
||||
this.emit("error", str);
|
||||
} else {
|
||||
this.emit('digitalWrite', value);
|
||||
this.emit("digitalWrite", value);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
// Public: Reads the digial pin's value periodicly on a supplied interval,
|
||||
// Public: Reads the digial pin"s value periodicly on a supplied interval,
|
||||
// and emits the result or an error
|
||||
//
|
||||
// interval - time (in milliseconds) to read from the pin at
|
||||
//
|
||||
// Returns the defined interval
|
||||
DigitalPin.prototype.digitalRead = function(interval) {
|
||||
if (this.mode !== 'r') { this._setMode('r'); }
|
||||
if (this.mode !== "r") { this._setMode("r"); }
|
||||
|
||||
Utils.every(interval, function() {
|
||||
FS.readFile(this._valuePath(), function(err, data) {
|
||||
if (err) {
|
||||
var error = "Error occurred while reading from pin " + this.pinNum;
|
||||
this.emit('error', error);
|
||||
this.emit("error", error);
|
||||
} else {
|
||||
var readData = parseInt(data.toString());
|
||||
this.emit('digitalRead', readData);
|
||||
this.emit("digitalRead", readData);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
|
@ -102,14 +106,14 @@ DigitalPin.prototype.setLow = function() {
|
|||
};
|
||||
|
||||
DigitalPin.prototype.toggle = function() {
|
||||
return (this.status === 'low') ? this.setHigh() : this.setLow();
|
||||
return (this.status === "low") ? this.setHigh() : this.setLow();
|
||||
};
|
||||
|
||||
// Creates the GPIO file to read/write from
|
||||
DigitalPin.prototype._createGPIOPin = function() {
|
||||
FS.writeFile(this._exportPath(), this.pinNum, function(err) {
|
||||
if (err) {
|
||||
this.emit('error', 'Error while creating pin files');
|
||||
this.emit("error", "Error while creating pin files");
|
||||
} else {
|
||||
this._openPin();
|
||||
}
|
||||
|
@ -118,24 +122,24 @@ DigitalPin.prototype._createGPIOPin = function() {
|
|||
|
||||
DigitalPin.prototype._openPin = function() {
|
||||
this._setMode(this.mode, true);
|
||||
this.emit('open');
|
||||
this.emit("open");
|
||||
};
|
||||
|
||||
DigitalPin.prototype._closeCallback = function(err) {
|
||||
if (err) {
|
||||
this.emit('error', 'Error while closing pin files');
|
||||
this.emit("error", "Error while closing pin files");
|
||||
} else {
|
||||
this.emit('close', this.pinNum);
|
||||
this.emit("close", this.pinNum);
|
||||
}
|
||||
};
|
||||
|
||||
// Sets the mode for the GPIO pin by writing the correct values to the pin reference files
|
||||
// Sets the mode for the pin by writing the values to the pin reference files
|
||||
DigitalPin.prototype._setMode = function(mode, emitConnect) {
|
||||
if (emitConnect == null) { emitConnect = false; }
|
||||
|
||||
this.mode = mode;
|
||||
|
||||
var data = (mode === 'w') ? GPIO_WRITE : GPIO_READ;
|
||||
var data = (mode === "w") ? GPIO_WRITE : GPIO_READ;
|
||||
|
||||
FS.writeFile(this._directionPath(), data, function(err) {
|
||||
this._setModeCallback(err, emitConnect);
|
||||
|
@ -144,13 +148,13 @@ DigitalPin.prototype._setMode = function(mode, emitConnect) {
|
|||
|
||||
DigitalPin.prototype._setModeCallback = function(err, emitConnect) {
|
||||
if (err) {
|
||||
return this.emit('error', "Setting up pin direction failed");
|
||||
return this.emit("error", "Setting up pin direction failed");
|
||||
}
|
||||
|
||||
this.ready = true;
|
||||
|
||||
if (emitConnect) {
|
||||
this.emit('connect', this.mode);
|
||||
this.emit("connect", this.mode);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
Utils = {
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Returns { period: int, duty: int }
|
||||
// Calculated based on params value, freq, pulseWidth = { min: int, max: int }
|
||||
// pulseWidth min and max need to be specified in microseconds
|
||||
periodAndDuty: function(scaledDuty, freq, pulseWidth, polarity) {
|
||||
var period, duty, maxDuty;
|
||||
|
||||
polarity = polarity || 'high';
|
||||
polarity = polarity || "high";
|
||||
period = Math.round(1.0e9 / freq);
|
||||
|
||||
if (pulseWidth != null) {
|
||||
|
@ -18,12 +20,10 @@ Utils = {
|
|||
duty = Math.round(period * scaledDuty);
|
||||
}
|
||||
|
||||
if (polarity == 'low') {
|
||||
if (polarity === "low") {
|
||||
duty = period - duty;
|
||||
}
|
||||
|
||||
return { period: period, duty: duty };
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Utils;
|
||||
|
|
|
@ -10,55 +10,15 @@
|
|||
|
||||
var levels = ["debug", "info", "warn", "error", "fatal"];
|
||||
|
||||
var BasicLogger = require('./logger/basic_logger'),
|
||||
NullLogger = require('./logger/null_logger'),
|
||||
Config = require('./config');
|
||||
var BasicLogger = require("./logger/basic_logger"),
|
||||
NullLogger = require("./logger/null_logger"),
|
||||
Config = require("./config");
|
||||
|
||||
// The Logger is a global object to facilitate logging stuff to the console (or
|
||||
// other output) easily and consistently. It's available anywhere in Cylon, as
|
||||
// other output) easily and consistently. It"s available anywhere in Cylon, as
|
||||
// well as in external modules that are loaded into Cylon
|
||||
var Logger = module.exports = {};
|
||||
|
||||
// Public: Creates a Logger instance and assigns it to @logger
|
||||
//
|
||||
// logger - logger object to use. Defaults to a BasicLogger, or a NullLogger if
|
||||
// false is supplied
|
||||
//
|
||||
// level - logging level to use. if supplied, will only log to specified level
|
||||
// or above
|
||||
//
|
||||
// Returns the new logger instance
|
||||
Logger.setup = function setup(opts) {
|
||||
var Cylon = require('./cylon');
|
||||
|
||||
if (typeof opts === 'object') {
|
||||
Cylon.config({ logging: opts });
|
||||
}
|
||||
|
||||
var logger = Config.logging.logger,
|
||||
level = Config.logging.level || "info";
|
||||
|
||||
if (logger == null) { logger = BasicLogger; }
|
||||
|
||||
this.logger = logger || NullLogger;
|
||||
|
||||
if (typeof level === 'string') {
|
||||
setLogLevel(level);
|
||||
}
|
||||
|
||||
return this.logger;
|
||||
};
|
||||
|
||||
Logger.toString = function() {
|
||||
return this.logger.toString();
|
||||
};
|
||||
|
||||
levels.forEach(function(level) {
|
||||
Logger[level] = function() {
|
||||
return this.logger[level].apply(this.logger, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
var setLogLevel = function(level) {
|
||||
var index = levels.indexOf(level),
|
||||
active,
|
||||
|
@ -80,7 +40,47 @@ var setLogLevel = function(level) {
|
|||
ignored.forEach(function(level) {
|
||||
Logger[level] = function() {};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Public: Creates a Logger instance and assigns it to @logger
|
||||
//
|
||||
// logger - logger object to use. Defaults to a BasicLogger, or a NullLogger if
|
||||
// false is supplied
|
||||
//
|
||||
// level - logging level to use. if supplied, will only log to specified level
|
||||
// or above
|
||||
//
|
||||
// Returns the new logger instance
|
||||
Logger.setup = function setup(opts) {
|
||||
var Cylon = require("./cylon");
|
||||
|
||||
if (typeof opts === "object") {
|
||||
Cylon.config({ logging: opts });
|
||||
}
|
||||
|
||||
var logger = Config.logging.logger,
|
||||
level = Config.logging.level || "info";
|
||||
|
||||
if (logger == null) { logger = BasicLogger; }
|
||||
|
||||
this.logger = logger || NullLogger;
|
||||
|
||||
if (typeof level === "string") {
|
||||
setLogLevel(level);
|
||||
}
|
||||
|
||||
return this.logger;
|
||||
};
|
||||
|
||||
Logger.toString = function() {
|
||||
return this.logger.toString();
|
||||
};
|
||||
|
||||
levels.forEach(function(level) {
|
||||
Logger[level] = function() {
|
||||
return this.logger[level].apply(this.logger, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
Logger.setup();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var getArgs = function(args) {
|
||||
return args.length >= 1 ? [].slice.call(args, 0) : [];
|
||||
|
@ -6,10 +6,10 @@ var getArgs = function(args) {
|
|||
|
||||
var logString = function(type) {
|
||||
var time = new Date().toISOString(),
|
||||
type = String(type).toUpperCase(),
|
||||
padded = String(" " + type).slice(-5);
|
||||
upcase = String(type).toUpperCase(),
|
||||
padded = String(" " + upcase).slice(-5);
|
||||
|
||||
return type[0] + ", [" + time + "] " + padded + " -- :";
|
||||
return upcase[0] + ", [" + time + "] " + padded + " -- :";
|
||||
};
|
||||
|
||||
// The BasicLogger logs to console.log
|
||||
|
@ -17,7 +17,7 @@ var BasicLogger = module.exports = {
|
|||
toString: function() { return "BasicLogger"; },
|
||||
};
|
||||
|
||||
['debug', 'info', 'warn', 'error', 'fatal'].forEach(function(type) {
|
||||
["debug", "info", "warn", "error", "fatal"].forEach(function(type) {
|
||||
BasicLogger[type] = function() {
|
||||
var args = getArgs(arguments);
|
||||
return console.log.apply(console, [].concat(logString(type), args));
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
// The NullLogger is designed for cases where you want absolutely nothing to
|
||||
// print to anywhere. Every proxied method from the Logger returns a noop.
|
||||
var NullLogger = module.exports = {
|
||||
toString: function() { return "NullLogger"; }
|
||||
};
|
||||
|
||||
['debug', 'info', 'warn', 'error', 'fatal'].forEach(function(type) {
|
||||
["debug", "info", "warn", "error", "fatal"].forEach(function(type) {
|
||||
NullLogger[type] = function() {};
|
||||
});
|
||||
|
|
|
@ -12,21 +12,22 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Logger = require('./logger');
|
||||
var Logger = require("./logger");
|
||||
|
||||
// Explicitly these modules here, so Browserify can grab them later
|
||||
require('./test/loopback');
|
||||
require('./test/test-adaptor');
|
||||
require('./test/test-driver');
|
||||
require('./test/ping');
|
||||
require("./test/loopback");
|
||||
require("./test/test-adaptor");
|
||||
require("./test/test-driver");
|
||||
require("./test/ping");
|
||||
|
||||
var missingModuleError = function(module) {
|
||||
var string = "Cannot find the '" + module + "' module.\n";
|
||||
string += "This problem might be fixed by installing it with 'npm install " + module + "' and trying again.";
|
||||
var str = "Cannot find the '" + module + "' module.\n";
|
||||
str += "This problem might be fixed by installing it with ";
|
||||
str +="'npm install " + module + "' and trying again.";
|
||||
|
||||
console.log(string);
|
||||
console.log(str);
|
||||
|
||||
process.emit('SIGINT');
|
||||
process.emit("SIGINT");
|
||||
};
|
||||
|
||||
var Registry = module.exports = {
|
||||
|
@ -86,7 +87,7 @@ var Registry = module.exports = {
|
|||
|
||||
Logger.debug("Registering module " + name);
|
||||
|
||||
['adaptors', 'drivers', 'dependencies'].forEach(function(field) {
|
||||
["adaptors", "drivers", "dependencies"].forEach(function(field) {
|
||||
if (module[field].length) {
|
||||
Logger.debug(" " + field + ":");
|
||||
module[field].forEach(function(item) {
|
||||
|
@ -110,6 +111,6 @@ var Registry = module.exports = {
|
|||
};
|
||||
|
||||
// Default drivers/adaptors:
|
||||
['loopback', 'ping', 'test-adaptor', 'test-driver'].forEach(function(module) {
|
||||
Registry.register('./test/' + module);
|
||||
["loopback", "ping", "test-adaptor", "test-driver"].forEach(function(module) {
|
||||
Registry.register("./test/" + module);
|
||||
});
|
||||
|
|
122
lib/robot.js
122
lib/robot.js
|
@ -6,25 +6,16 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var Connection = require("./connection"),
|
||||
Device = require("./device"),
|
||||
Logger = require('./logger'),
|
||||
Utils = require('./utils'),
|
||||
Config = require('./config');
|
||||
var initConnection = require("./connection"),
|
||||
initDevice = require("./device"),
|
||||
Logger = require("./logger"),
|
||||
Utils = require("./utils"),
|
||||
Config = require("./config");
|
||||
|
||||
var Async = require("async"),
|
||||
EventEmitter = require('events').EventEmitter;
|
||||
|
||||
var missingModuleError = function(module) {
|
||||
var string = "Cannot find the '" + module + "' module. ";
|
||||
string += "Please install it with 'npm install " + module + "' and try again.";
|
||||
|
||||
console.log(string);
|
||||
|
||||
process.emit('SIGINT');
|
||||
};
|
||||
EventEmitter = require("events").EventEmitter;
|
||||
|
||||
// Public: Creates a new Robot
|
||||
//
|
||||
|
@ -40,10 +31,10 @@ var missingModuleError = function(module) {
|
|||
// name: "Spherobot!"
|
||||
//
|
||||
// connection:
|
||||
// name: 'sphero', adaptor: 'sphero', port: '/dev/rfcomm0'
|
||||
// name: "sphero", adaptor: "sphero", port: "/dev/rfcomm0"
|
||||
//
|
||||
// device:
|
||||
// name: 'sphero', driver: 'sphero'
|
||||
// name: "sphero", driver: "sphero"
|
||||
//
|
||||
// work: (me) ->
|
||||
// Utils.every 1.second(), ->
|
||||
|
@ -90,7 +81,7 @@ var Robot = module.exports = function Robot(opts) {
|
|||
|
||||
this[n] = opt;
|
||||
|
||||
if (typeof opt === 'function' && opts.commands == null) {
|
||||
if (typeof opt === "function" && opts.commands == null) {
|
||||
this.commands[n] = opt;
|
||||
}
|
||||
}
|
||||
|
@ -98,14 +89,14 @@ var Robot = module.exports = function Robot(opts) {
|
|||
if (opts.commands) {
|
||||
var cmds = opts.commands;
|
||||
|
||||
if (typeof cmds === 'object') {
|
||||
if (typeof cmds === "object") {
|
||||
this.commands = cmds;
|
||||
}
|
||||
|
||||
if (typeof cmds === 'function') {
|
||||
if (typeof cmds === "function") {
|
||||
var result = cmds.call(this, this);
|
||||
|
||||
if (typeof result === 'object' && !Array.isArray(result)) {
|
||||
if (typeof result === "object" && !Array.isArray(result)) {
|
||||
this.commands = result;
|
||||
} else {
|
||||
throw new Error("#commands function must return an object");
|
||||
|
@ -113,10 +104,10 @@ var Robot = module.exports = function Robot(opts) {
|
|||
}
|
||||
}
|
||||
|
||||
var mode = Utils.fetch(Config, 'mode', 'manual');
|
||||
var mode = Utils.fetch(Config, "mode", "manual");
|
||||
|
||||
if (mode === 'auto') {
|
||||
// run on the next tick, to allow for 'work' event handlers to be set up
|
||||
if (mode === "auto") {
|
||||
// run on the next tick, to allow for "work" event handlers to be set up
|
||||
setTimeout(this.start, 0);
|
||||
}
|
||||
};
|
||||
|
@ -159,12 +150,16 @@ Robot.prototype.connection = function(name, conn) {
|
|||
conn.name = name;
|
||||
|
||||
if (this.connections[conn.name]) {
|
||||
var original = conn.name;
|
||||
var original = conn.name,
|
||||
str;
|
||||
conn.name = Utils.makeUnique(original, Object.keys(this.connections));
|
||||
Logger.warn("Connection names must be unique. Renaming '" + original + "' to '" + conn.name + "'");
|
||||
|
||||
str = "Connection names must be unique.";
|
||||
str += "Renaming '" + original + "' to '" + conn.name + "'";
|
||||
Logger.warn(str);
|
||||
}
|
||||
|
||||
this.connections[conn.name] = Connection(conn);
|
||||
this.connections[conn.name] = initConnection(conn);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
@ -177,6 +172,8 @@ Robot.prototype.connection = function(name, conn) {
|
|||
Robot.prototype.initConnections = function(opts) {
|
||||
Logger.info("Initializing connections.");
|
||||
|
||||
var str;
|
||||
|
||||
var isArray = Array.isArray;
|
||||
|
||||
if (opts.connection == null && opts.connections == null) {
|
||||
|
@ -184,19 +181,27 @@ Robot.prototype.initConnections = function(opts) {
|
|||
}
|
||||
|
||||
if (opts.connection) {
|
||||
Logger.warn("Specifying a single connection with the 'connection' key is deprecated, and will be removed in 1.0.0.");
|
||||
str = "Specifying a single connection with the 'connection' key ";
|
||||
str += "is deprecated. It will be removed in 1.0.0.";
|
||||
|
||||
Logger.warn(str);
|
||||
|
||||
this.connection(opts.connection.name, opts.connection);
|
||||
return this.connections;
|
||||
}
|
||||
|
||||
if (typeof opts.connections == 'object' && !isArray(opts.connections)) {
|
||||
if (typeof opts.connections === "object" && !isArray(opts.connections)) {
|
||||
for (var name in opts.connections) {
|
||||
this.connection(name, opts.connections[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray(opts.connections)) {
|
||||
Logger.warn("Specifying connections as an array is deprecated, and will be removed in 1.0.0.");
|
||||
str = "Specifying connections as an array is deprecated. ";
|
||||
str += "It will be removed in 1.0.0.";
|
||||
|
||||
Logger.warn(str);
|
||||
|
||||
opts.connections.forEach(function(conn) {
|
||||
this.connection(conn.name, conn);
|
||||
}, this);
|
||||
|
@ -206,20 +211,25 @@ Robot.prototype.initConnections = function(opts) {
|
|||
};
|
||||
|
||||
Robot.prototype.device = function(name, device) {
|
||||
var str;
|
||||
|
||||
device.robot = this;
|
||||
device.name = name;
|
||||
|
||||
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 + "'");
|
||||
|
||||
str = "Device names must be unique.";
|
||||
str += "Renaming '" + original + "' to '" + device.name + "'";
|
||||
Logger.warn(str);
|
||||
}
|
||||
|
||||
if (typeof device.connection === 'string') {
|
||||
if (typeof device.connection === "string") {
|
||||
if (this.connections[device.connection] == null) {
|
||||
var str = "No connection found with the name " + device.connection + ".\n";
|
||||
str = "No connection found with the name " + device.connection + ".\n";
|
||||
Logger.fatal(str);
|
||||
process.emit('SIGINT');
|
||||
process.emit("SIGINT");
|
||||
}
|
||||
|
||||
device.connection = this.connections[device.connection];
|
||||
|
@ -230,10 +240,10 @@ Robot.prototype.device = function(name, device) {
|
|||
}
|
||||
}
|
||||
|
||||
this.devices[device.name] = Device(device);
|
||||
this.devices[device.name] = initDevice(device);
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
// Public: Initializes all devices for the robot
|
||||
//
|
||||
|
@ -241,9 +251,10 @@ Robot.prototype.device = function(name, device) {
|
|||
//
|
||||
// Returns initialized devices
|
||||
Robot.prototype.initDevices = function(opts) {
|
||||
Logger.info("Initializing devices.");
|
||||
var isArray = Array.isArray,
|
||||
str;
|
||||
|
||||
var isArray = Array.isArray;
|
||||
Logger.info("Initializing devices.");
|
||||
|
||||
if (opts.device == null && opts.devices == null) {
|
||||
return this.devices;
|
||||
|
@ -251,23 +262,28 @@ Robot.prototype.initDevices = function(opts) {
|
|||
|
||||
// check that there are connections to use
|
||||
if (!Object.keys(this.connections).length) {
|
||||
throw new Error("No connections specified")
|
||||
throw new Error("No connections specified");
|
||||
}
|
||||
|
||||
if (opts.device) {
|
||||
Logger.warn("Specifying a single device with the 'device' key is deprecated, and will be removed in 1.0.0.");
|
||||
str = "Specifying a single device with the 'device' key is deprecated. ";
|
||||
str += "It will be removed in 1.0.0.";
|
||||
|
||||
Logger.warn(str);
|
||||
this.device(opts.device.name, opts.device);
|
||||
return this.devices;
|
||||
}
|
||||
|
||||
if (typeof opts.devices == 'object' && !isArray(opts.devices)) {
|
||||
if (typeof opts.devices === "object" && !isArray(opts.devices)) {
|
||||
for (var name in opts.devices) {
|
||||
this.device(name, opts.devices[name]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray(opts.devices)) {
|
||||
Logger.warn("Specifying devices as an array is deprecated, and will be removed in 1.0.0.");
|
||||
str = "Specifying devices as an array is deprecated.";
|
||||
str += "It will be removed in 1.0.0.";
|
||||
Logger.warn(str);
|
||||
opts.devices.forEach(function(device) {
|
||||
this.device(device.name, device);
|
||||
}, this);
|
||||
|
@ -286,13 +302,13 @@ Robot.prototype.start = function(callback) {
|
|||
return this;
|
||||
}
|
||||
|
||||
var mode = Utils.fetch(Config, 'workMode', 'async');
|
||||
var mode = Utils.fetch(Config, "workMode", "async");
|
||||
|
||||
Async.series([
|
||||
this.startConnections,
|
||||
this.startDevices,
|
||||
function(callback) {
|
||||
if (mode === 'async') {
|
||||
if (mode === "async") {
|
||||
this.startWork();
|
||||
}
|
||||
callback(null, true);
|
||||
|
@ -301,12 +317,12 @@ Robot.prototype.start = function(callback) {
|
|||
if (!!err) {
|
||||
Logger.fatal("An error occured while trying to start the robot:");
|
||||
Logger.fatal(err);
|
||||
if (typeof(this.error) === 'function') {
|
||||
if (typeof(this.error) === "function") {
|
||||
this.error.call(this, err);
|
||||
}
|
||||
this.emit('error', err);
|
||||
this.emit("error", err);
|
||||
}
|
||||
if (typeof(callback) === 'function') {
|
||||
if (typeof(callback) === "function") {
|
||||
callback(err, results);
|
||||
}
|
||||
}.bind(this));
|
||||
|
@ -314,20 +330,20 @@ Robot.prototype.start = function(callback) {
|
|||
return this;
|
||||
};
|
||||
|
||||
// Public: Starts the Robot's work and triggers a callback
|
||||
// Public: Starts the Robot"s work and triggers a callback
|
||||
//
|
||||
// callback - callback function to be triggered
|
||||
//
|
||||
// Returns nothing
|
||||
Robot.prototype.startWork = function() {
|
||||
Logger.info('Working.');
|
||||
Logger.info("Working.");
|
||||
|
||||
this.emit('ready', this);
|
||||
this.emit("ready", this);
|
||||
this.work.call(this, this);
|
||||
this.running = true;
|
||||
};
|
||||
|
||||
// Public: Starts the Robot's connections and triggers a callback
|
||||
// Public: Starts the Robot"s connections and triggers a callback
|
||||
//
|
||||
// callback - callback function to be triggered
|
||||
//
|
||||
|
@ -355,7 +371,7 @@ Robot.prototype.startConnections = function(callback) {
|
|||
return Async.parallel(starters, callback);
|
||||
};
|
||||
|
||||
// Public: Starts the Robot's devices and triggers a callback
|
||||
// Public: Starts the Robot"s devices and triggers a callback
|
||||
//
|
||||
// callback - callback function to be triggered
|
||||
//
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Adaptor = require('../adaptor'),
|
||||
Utils = require('../utils');
|
||||
var Adaptor = require("../adaptor"),
|
||||
Utils = require("../utils");
|
||||
|
||||
var Loopback;
|
||||
|
||||
|
@ -27,5 +27,5 @@ Loopback.prototype.disconnect = function(callback) {
|
|||
callback();
|
||||
};
|
||||
|
||||
Loopback.adaptors = ['loopback'];
|
||||
Loopback.adaptors = ["loopback"];
|
||||
Loopback.adaptor = function(opts) { return new Loopback(opts); };
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var Driver = require('../driver'),
|
||||
Utils = require('../utils');
|
||||
var Driver = require("../driver"),
|
||||
Utils = require("../utils");
|
||||
|
||||
var Ping = module.exports = function Ping() {
|
||||
Ping.__super__.constructor.apply(this, arguments);
|
||||
|
@ -22,7 +22,7 @@ var Ping = module.exports = function Ping() {
|
|||
Utils.subclass(Ping, Driver);
|
||||
|
||||
Ping.prototype.ping = function() {
|
||||
this.emit('ping', 'ping');
|
||||
this.emit("ping", "ping");
|
||||
return "pong";
|
||||
};
|
||||
|
||||
|
@ -34,5 +34,5 @@ Ping.prototype.halt = function(callback) {
|
|||
callback();
|
||||
};
|
||||
|
||||
Ping.drivers = ['ping'];
|
||||
Ping.drivers = ["ping"];
|
||||
Ping.driver = function(opts) { return new Ping(opts); };
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
var Adaptor = require('../adaptor'),
|
||||
Utils = require('../utils');
|
||||
var Adaptor = require("../adaptor"),
|
||||
Utils = require("../utils");
|
||||
|
||||
var TestAdaptor;
|
||||
|
||||
|
@ -19,5 +19,5 @@ module.exports = TestAdaptor = function TestAdaptor() {
|
|||
|
||||
Utils.subclass(TestAdaptor, Adaptor);
|
||||
|
||||
TestAdaptor.adaptors = ['test'];
|
||||
TestAdaptor.adaptors = ["test"];
|
||||
TestAdaptor.adaptor = function(opts) { return new TestAdaptor(opts); };
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var Driver = require('../driver'),
|
||||
Utils = require('../utils');
|
||||
var Driver = require("../driver"),
|
||||
Utils = require("../utils");
|
||||
|
||||
var TestDriver;
|
||||
|
||||
|
@ -19,5 +19,5 @@ module.exports = TestDriver = function TestDriver() {
|
|||
|
||||
Utils.subclass(TestDriver, Driver);
|
||||
|
||||
TestDriver.drivers = ['test'];
|
||||
TestDriver.drivers = ["test"];
|
||||
TestDriver.driver = function(opts) { return new TestDriver(opts); };
|
||||
|
|
491
lib/utils.js
491
lib/utils.js
|
@ -6,248 +6,12 @@
|
|||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
var Utils = module.exports = {
|
||||
// Public: Alias to setInterval, combined with Number monkeypatches below to
|
||||
// create an artoo-like syntax.
|
||||
//
|
||||
// interval - interval to run action on
|
||||
// action - action to perform at interval
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// every((5).seconds(), function() {
|
||||
// console.log('Hello world (and again in 5 seconds)!');
|
||||
// });
|
||||
//
|
||||
// Returns an interval
|
||||
every: function every(interval, action) {
|
||||
return setInterval(action, interval);
|
||||
},
|
||||
|
||||
// Public: Alias to setTimeout, combined with Number monkeypatches below to
|
||||
// create an artoo-like syntax.
|
||||
//
|
||||
// interval - interval to run action on
|
||||
// action - action to perform at interval
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// after((10).seconds(), function() {
|
||||
// console.log('Hello world from ten seconds ago!');
|
||||
// });
|
||||
//
|
||||
// Returns an interval
|
||||
after: function after(delay, action) {
|
||||
return setTimeout(action, delay);
|
||||
},
|
||||
|
||||
// Public: Alias to the `every` function, but passing 0
|
||||
// Examples
|
||||
//
|
||||
// constantly(function() {
|
||||
// console.log('hello world (and again and again)!');
|
||||
// });
|
||||
//
|
||||
// Returns an interval
|
||||
constantly: function constantly(action) {
|
||||
return every(0, action);
|
||||
},
|
||||
|
||||
// Public: Sleep - do nothing for some duration of time.
|
||||
//
|
||||
// ms - number of ms to sleep for
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// sleep((1).second());
|
||||
//
|
||||
// Returns a function
|
||||
sleep: function sleep(ms) {
|
||||
var start = Date.now();
|
||||
|
||||
while(Date.now() < start + ms) {
|
||||
var i = 0;
|
||||
}
|
||||
},
|
||||
|
||||
// Public: Function to use for class inheritance. Copy of a CoffeeScript helper
|
||||
// function.
|
||||
//
|
||||
// Example
|
||||
//
|
||||
// var Sphero = function Sphero() {};
|
||||
//
|
||||
// subclass(Sphero, ParentClass);
|
||||
//
|
||||
// // Sphero is now a subclass of Parent, and can access parent methods
|
||||
// // through Sphero.__super__
|
||||
//
|
||||
// Returns subclass
|
||||
subclass: function subclass(child, parent) {
|
||||
var ctor = function() {
|
||||
this.constructor = child;
|
||||
};
|
||||
|
||||
for (var key in parent) {
|
||||
if (Object.hasOwnProperty.call(parent, key)) {
|
||||
child[key] = parent[key];
|
||||
}
|
||||
}
|
||||
|
||||
ctor.prototype = parent.prototype;
|
||||
child.prototype = new ctor();
|
||||
child.__super__ = parent.prototype;
|
||||
return child;
|
||||
},
|
||||
|
||||
proxyFunctions: function proxyFunctions(source, target) {
|
||||
for (var opt in source) {
|
||||
if (!target[opt] && typeof source[opt] === 'function') {
|
||||
target[opt] = source[opt].bind(source);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Public: Proxies a list of methods from one object to another. It will not
|
||||
// overwrite existing methods unless told to.
|
||||
//
|
||||
// methods - array of functions to proxy
|
||||
// target - object to proxy the functions to
|
||||
// base - (optional) object that proxied functions will be declared on. Defaults
|
||||
// to this
|
||||
// force - (optional) boolean - whether or not to force method assignment
|
||||
//
|
||||
// Returns base
|
||||
proxyFunctionsToObject: function proxyFunctionsToObject(methods, target, base, force) {
|
||||
if (base == null) {
|
||||
base = this;
|
||||
}
|
||||
|
||||
if (force == null) {
|
||||
force = false;
|
||||
}
|
||||
|
||||
var proxy = function(method) {
|
||||
return base[method] = function() {
|
||||
return target[method].apply(target, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0; i < methods.length; i++) {
|
||||
var method = methods[i];
|
||||
|
||||
if (!force && typeof(base[method]) === 'function') {
|
||||
continue;
|
||||
}
|
||||
|
||||
proxy(method);
|
||||
}
|
||||
return base;
|
||||
},
|
||||
|
||||
// Public: Analogue to Ruby's Hash#fetch method for looking up object
|
||||
// properties.
|
||||
//
|
||||
// obj - object to do property lookup on
|
||||
// property - string property name to attempt to look up
|
||||
// fallback - either:
|
||||
// - a fallback value to return if `property` can't be found
|
||||
// - a function to be executed if `property` can't be found. The function
|
||||
// will be passed `property` as an argument.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// var object = { property: "hello world" };
|
||||
// fetch(object, "property");
|
||||
// //=> "hello world"
|
||||
//
|
||||
// fetch(object, "notaproperty", "default value");
|
||||
// //=> "default value"
|
||||
//
|
||||
// var notFound = function(prop) { return prop + " not found!" };
|
||||
// fetch(object, "notaproperty", notFound)
|
||||
// // "notaproperty not found!"
|
||||
//
|
||||
// var badFallback = function(prop) { prop + " not found!" };
|
||||
// fetch(object, "notaproperty", badFallback)
|
||||
// // Error: no return value from provided callback function
|
||||
//
|
||||
// fetch(object, "notaproperty");
|
||||
// // Error: key not found: "notaproperty"
|
||||
//
|
||||
// Returns the value of obj[property], a fallback value, or the results of
|
||||
// running 'fallback'. If the property isn't found, and 'fallback' hasn't been
|
||||
// provided, will throw an error.
|
||||
fetch: function(obj, property, fallback) {
|
||||
if (obj.hasOwnProperty(property)) {
|
||||
return obj[property];
|
||||
}
|
||||
|
||||
if (fallback === void 0) {
|
||||
throw new Error('key not found: "' + property + '"');
|
||||
}
|
||||
|
||||
if (typeof(fallback) === 'function') {
|
||||
var value = fallback(property);
|
||||
|
||||
if (value === void 0) {
|
||||
throw new Error('no return value from provided fallback function');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
},
|
||||
|
||||
// Public: Given a name, and an array of existing names, returns a unique
|
||||
// name.
|
||||
//
|
||||
// name - name that's colliding with existing names
|
||||
// arr - array of existing names
|
||||
//
|
||||
// Returns the new name as a string
|
||||
makeUnique: function(name, arr) {
|
||||
var newName;
|
||||
|
||||
if (!~arr.indexOf(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
for (var n = 1; ; n++) {
|
||||
newName = name + "-" + n;
|
||||
if (!~arr.indexOf(newName)) {
|
||||
return newName;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Public: Adds necessary utils to global namespace, along with base class
|
||||
// extensions.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// Number.prototype.seconds // undefined
|
||||
// after // undefined
|
||||
//
|
||||
// Utils.bootstrap();
|
||||
//
|
||||
// Number.prototype.seconds // [function]
|
||||
// (after === Utils.after) // true
|
||||
//
|
||||
// Returns Cylon.Utils
|
||||
bootstrap: function bootstrap() {
|
||||
global.every = this.every;
|
||||
global.after = this.after;
|
||||
global.constantly = this.constantly;
|
||||
|
||||
addCoreExtensions();
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
"use strict";
|
||||
|
||||
var addCoreExtensions = function addCoreExtensions() {
|
||||
var max = Math.max,
|
||||
min = Math.min;
|
||||
|
||||
// Public: Monkey-patches Number to have Rails-like //seconds() function.
|
||||
// Warning, due to the way the Javascript parser works, applying functions on
|
||||
// numbers is kind of weird. See examples for details.
|
||||
|
@ -294,7 +58,7 @@ var addCoreExtensions = function addCoreExtensions() {
|
|||
//
|
||||
// Returns an integer representing the scaled value
|
||||
Number.prototype.fromScale = function(start, end) {
|
||||
var val = (this - Math.min(start, end)) / (Math.max(start, end) - Math.min(start, end));
|
||||
var val = (this - min(start, end)) / (max(start, end) - min(start, end));
|
||||
|
||||
if (val > 1) {
|
||||
return 1;
|
||||
|
@ -319,7 +83,7 @@ var addCoreExtensions = function addCoreExtensions() {
|
|||
//
|
||||
// Returns an integer representing the scaled value
|
||||
Number.prototype.toScale = function(start, end) {
|
||||
var i = this * (Math.max(start, end) - Math.min(start, end)) + Math.min(start, end);
|
||||
var i = this * (max(start, end) - min(start, end)) + min(start, end);
|
||||
|
||||
if (i < start) {
|
||||
return start;
|
||||
|
@ -333,4 +97,247 @@ var addCoreExtensions = function addCoreExtensions() {
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
var Utils = module.exports = {
|
||||
// Public: Alias to setInterval, combined with Number monkeypatches below to
|
||||
// create an artoo-like syntax.
|
||||
//
|
||||
// interval - interval to run action on
|
||||
// action - action to perform at interval
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// every((5).seconds(), function() {
|
||||
// console.log("Hello world (and again in 5 seconds)!");
|
||||
// });
|
||||
//
|
||||
// Returns an interval
|
||||
every: function every(interval, action) {
|
||||
return setInterval(action, interval);
|
||||
},
|
||||
|
||||
// Public: Alias to setTimeout, combined with Number monkeypatches below to
|
||||
// create an artoo-like syntax.
|
||||
//
|
||||
// interval - interval to run action on
|
||||
// action - action to perform at interval
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// after((10).seconds(), function() {
|
||||
// console.log("Hello world from ten seconds ago!");
|
||||
// });
|
||||
//
|
||||
// Returns an interval
|
||||
after: function after(delay, action) {
|
||||
return setTimeout(action, delay);
|
||||
},
|
||||
|
||||
// Public: Alias to the `every` function, but passing 0
|
||||
// Examples
|
||||
//
|
||||
// constantly(function() {
|
||||
// console.log("hello world (and again and again)!");
|
||||
// });
|
||||
//
|
||||
// Returns an interval
|
||||
constantly: function constantly(action) {
|
||||
return every(0, action);
|
||||
},
|
||||
|
||||
// Public: Sleep - do nothing for some duration of time.
|
||||
//
|
||||
// ms - number of ms to sleep for
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// sleep((1).second());
|
||||
//
|
||||
// Returns a function
|
||||
sleep: function sleep(ms) {
|
||||
var start = Date.now(),
|
||||
i;
|
||||
|
||||
while(Date.now() < start + ms) {
|
||||
i = 0;
|
||||
}
|
||||
},
|
||||
|
||||
// Public: Function to use for class inheritance.
|
||||
// Based on CoffeeScript's implementation.
|
||||
//
|
||||
// Example
|
||||
//
|
||||
// var Sphero = function Sphero() {};
|
||||
//
|
||||
// subclass(Sphero, ParentClass);
|
||||
//
|
||||
// // Sphero is now a subclass of Parent, and can access parent methods
|
||||
// // through Sphero.__super__
|
||||
//
|
||||
// Returns subclass
|
||||
subclass: function subclass(child, parent) {
|
||||
var Ctor = function() {
|
||||
this.constructor = child;
|
||||
};
|
||||
|
||||
for (var key in parent) {
|
||||
if (Object.hasOwnProperty.call(parent, key)) {
|
||||
child[key] = parent[key];
|
||||
}
|
||||
}
|
||||
|
||||
Ctor.prototype = parent.prototype;
|
||||
child.prototype = new Ctor();
|
||||
child.__super__ = parent.prototype;
|
||||
return child;
|
||||
},
|
||||
|
||||
proxyFunctions: function proxyFunctions(source, target) {
|
||||
for (var opt in source) {
|
||||
if (!target[opt] && typeof source[opt] === "function") {
|
||||
target[opt] = source[opt].bind(source);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Public: Proxies a list of methods from one object to another. It will not
|
||||
// overwrite existing methods unless told to.
|
||||
//
|
||||
// methods - array of functions to proxy
|
||||
// target - object to proxy the functions to
|
||||
// base - (optional) object that proxied functions will be declared on.
|
||||
// Defaults to 'this'.
|
||||
// force - (optional) boolean - whether or not to force method assignment
|
||||
//
|
||||
// Returns base
|
||||
proxyFunctionsToObject: function(methods, target, base, force) {
|
||||
if (base == null) {
|
||||
base = this;
|
||||
}
|
||||
|
||||
if (force == null) {
|
||||
force = false;
|
||||
}
|
||||
|
||||
var proxy = function(method) {
|
||||
return base[method] = function() {
|
||||
return target[method].apply(target, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0; i < methods.length; i++) {
|
||||
var method = methods[i];
|
||||
|
||||
if (!force && typeof(base[method]) === "function") {
|
||||
continue;
|
||||
}
|
||||
|
||||
proxy(method);
|
||||
}
|
||||
return base;
|
||||
},
|
||||
|
||||
// Public: Analogue to Ruby"s Hash#fetch method for looking up object
|
||||
// properties.
|
||||
//
|
||||
// obj - object to do property lookup on
|
||||
// property - string property name to attempt to look up
|
||||
// fallback - either:
|
||||
// - a fallback value to return if `property` can"t be found
|
||||
// - a function to be executed if `property` can"t be found. The function
|
||||
// will be passed `property` as an argument.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// var object = { property: "hello world" };
|
||||
// fetch(object, "property");
|
||||
// //=> "hello world"
|
||||
//
|
||||
// fetch(object, "notaproperty", "default value");
|
||||
// //=> "default value"
|
||||
//
|
||||
// var notFound = function(prop) { return prop + " not found!" };
|
||||
// fetch(object, "notaproperty", notFound)
|
||||
// // "notaproperty not found!"
|
||||
//
|
||||
// var badFallback = function(prop) { prop + " not found!" };
|
||||
// fetch(object, "notaproperty", badFallback)
|
||||
// // Error: no return value from provided callback function
|
||||
//
|
||||
// fetch(object, "notaproperty");
|
||||
// // Error: key not found: "notaproperty"
|
||||
//
|
||||
// Returns the value of obj[property], a fallback value, or the results of
|
||||
// running "fallback". If the property isn"t found, and "fallback" hasn"t been
|
||||
// provided, will throw an error.
|
||||
fetch: function(obj, property, fallback) {
|
||||
if (obj.hasOwnProperty(property)) {
|
||||
return obj[property];
|
||||
}
|
||||
|
||||
if (fallback === void 0) {
|
||||
throw new Error("key not found: \"" + property + "\"");
|
||||
}
|
||||
|
||||
if (typeof(fallback) === "function") {
|
||||
var value = fallback(property);
|
||||
|
||||
if (value === void 0) {
|
||||
throw new Error("no return value from provided fallback function");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
},
|
||||
|
||||
// Public: Given a name, and an array of existing names, returns a unique
|
||||
// name.
|
||||
//
|
||||
// name - name that"s colliding with existing names
|
||||
// arr - array of existing names
|
||||
//
|
||||
// Returns the new name as a string
|
||||
makeUnique: function(name, arr) {
|
||||
var newName;
|
||||
|
||||
if (!~arr.indexOf(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
for (var n = 1; ; n++) {
|
||||
newName = name + "-" + n;
|
||||
if (!~arr.indexOf(newName)) {
|
||||
return newName;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Public: Adds necessary utils to global namespace, along with base class
|
||||
// extensions.
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// Number.prototype.seconds // undefined
|
||||
// after // undefined
|
||||
//
|
||||
// Utils.bootstrap();
|
||||
//
|
||||
// Number.prototype.seconds // [function]
|
||||
// (after === Utils.after) // true
|
||||
//
|
||||
// Returns Cylon.Utils
|
||||
bootstrap: function bootstrap() {
|
||||
global.every = this.every;
|
||||
global.after = this.after;
|
||||
global.constantly = this.constantly;
|
||||
|
||||
addCoreExtensions();
|
||||
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
Utils.bootstrap();
|
||||
|
|
Loading…
Reference in New Issue