From e8f109508bf9bf69dd06ef8fa44a42b13d4b1ccf Mon Sep 17 00:00:00 2001 From: Andrew Stewart Date: Mon, 29 Jun 2015 10:21:25 -0700 Subject: [PATCH] Replace tomdoc with jsdoc --- lib/adaptor.js | 44 +++++--- lib/basestar.js | 92 +++++++++------- lib/driver.js | 51 ++++++--- lib/io/digital-pin.js | 11 +- lib/io/utils.js | 12 ++- lib/utils.js | 208 ++++++++++++++++-------------------- lib/utils/monkey-patches.js | 19 ---- 7 files changed, 234 insertions(+), 203 deletions(-) diff --git a/lib/adaptor.js b/lib/adaptor.js index f56f1e7..82b578e 100644 --- a/lib/adaptor.js +++ b/lib/adaptor.js @@ -8,13 +8,17 @@ function formatErrorMessage(name, message) { return ["Error in connection", "'" + name + "'", "- " + message].join(" "); } -// Public: Creates a new Adaptor -// -// opts - hash of acceptable params -// name - name of the Adaptor, used when printing to console -// connection - Connection the adaptor will use to proxy commands/events -// -// Returns a new Adaptor +/** + * Adaptor class + * + * @constructor Adaptor + * + * @param {Object} [opts] adaptor options + * @param {String} [opts.name] the adaptor's name + * @param {Object} [opts.robot] the robot the adaptor belongs to + * @param {Object} [opts.host] the host the adaptor will connect to + * @param {Object} [opts.port] the port the adaptor will connect to + */ var Adaptor = module.exports = function Adaptor(opts) { Adaptor.__super__.constructor.apply(this, arguments); @@ -41,9 +45,12 @@ var Adaptor = module.exports = function Adaptor(opts) { Utils.subclass(Adaptor, Basestar); -// Public: Basic #connect function. Must be overwritten by a descendent class -// -// Returns nothing, throws an error +/** + * A base connect function. Must be overwritten by a descendent. + * + * @throws Error if not overridden by a child class + * @return {void} + */ Adaptor.prototype.connect = function() { var message = formatErrorMessage( this.name, @@ -53,9 +60,12 @@ Adaptor.prototype.connect = function() { throw new Error(message); }; -// Public: Basic #disconnect function. Must be overwritten by a descendent class -// -// Returns nothing, throws an error +/** + * A base disconnect function. Must be overwritten by a descendent. + * + * @throws Error if not overridden by a child class + * @return {void} + */ Adaptor.prototype.disconnect = function() { var message = formatErrorMessage( this.name, @@ -65,9 +75,11 @@ Adaptor.prototype.disconnect = function() { throw new Error(message); }; -// Public: Expresses the Connection in JSON format -// -// Returns an Object containing Connection data +/** + * Expresses the Adaptor in a JSON-serializable format + * + * @return {Object} a representation of the Adaptor in a serializable format + */ Adaptor.prototype.toJSON = function() { return { name: this.name, diff --git a/lib/basestar.js b/lib/basestar.js index 805423f..98624ca 100644 --- a/lib/basestar.js +++ b/lib/basestar.js @@ -5,25 +5,28 @@ var EventEmitter = require("events").EventEmitter; var Utils = require("./utils"), _ = require("./utils/helpers"); -// Basestar is a base class to be used when writing external Cylon adaptors and -// drivers. It provides some useful base methods and functionality -// -// It also extends EventEmitter, so child classes are capable of emitting events -// for other parts of the system to handle. +/** + * The Basestar class is a wrapper class around EventEmitter that underpins most + * other Cylon adaptor/driver classes, providing useful external base methods + * and functionality. + * + * @constructor Basestar + */ var Basestar = module.exports = function Basestar() { Utils.classCallCheck(this, Basestar); }; Utils.subclass(Basestar, EventEmitter); -// Public: Proxies calls from all methods in the object to a target object -// -// methods - array of methods to proxy -// target - object to proxy methods to -// source - object to proxy methods from -// force - whether or not to overwrite existing method definitions -// -// Returns the klass where the methods have been proxied +/** + * Proxies calls from all methods in the source to a target object + * + * @param {String[]} methods methods to proxy + * @param {Object} target object to proxy methods to + * @param {Object} source object to proxy methods from + * @param {Boolean} [force=false] whether or not to overwrite existing methods + * @return {Object} the source + */ Basestar.prototype.proxyMethods = Utils.proxyFunctionsToObject; // Public: Triggers a callback and emits an event with provided data @@ -33,6 +36,18 @@ Basestar.prototype.proxyMethods = Utils.proxyFunctionsToObject; // ...data - additional arguments to be passed to both event/callback // // Returns nothing + +/** + * Triggers the provided callback, and emits an event with the provided data. + * + * If an error is provided, emits the 'error' event. + * + * @param {String} event what event to emit + * @param {Function} callback function to be invoked with error/data + * @param {*} err possible error value + * @param {...*} data data values to be passed to error/callback + * @return {void} + */ Basestar.prototype.respond = function(event, callback, err) { var args = Array.prototype.slice.call(arguments, 3); @@ -47,17 +62,17 @@ Basestar.prototype.respond = function(event, callback, err) { } }; -// Public: Defines an event handler that proxies events from a source object -// to a target object -// -// opts - object containing options: -// - targetEventName or eventName - event that should be emitted from the -// target -// - target - object to proxy event to -// - source - object to proxy event from -// - sendUpdate - whether or not to send an "update" event -// -// Returns the source +/** + * Defines an event handler to proxy events from a source object to a target + * + * @param {Object} opts event options + * @param {EventEmitter} opts.source source of events to listen for + * @param {EventEmitter} opts.target target new events should be emitted from + * @param {String} opts.eventName name of event to listen for, and proxy + * @param {Bool} [opts.sendUpdate=false] whether to emit the 'update' event + * @param {String} [opts.targetEventName] new event name to emit from target + * @return {EventEmitter} the source object + */ Basestar.prototype.defineEvent = function(opts) { opts.sendUpdate = opts.sendUpdate || false; opts.targetEventName = opts.targetEventName || opts.eventName; @@ -76,23 +91,26 @@ 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) -// to the adaptor -// -// opts - hash of opts to be passed to defineEvent() -// -// Returns this.connector +/** + * A #defineEvent shorthand for adaptors. + * + * Proxies events from an adaptor's connector to the adaptor itself. + * + * @param {Object} opts proxy options + * @return {EventEmitter} the adaptor's connector + */ Basestar.prototype.defineAdaptorEvent = function(opts) { return this._proxyEvents(opts, this.connector, this); }; -// 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() -// -// Returns this.connection +/** + * A #defineEvent shorthand for drivers. + * + * Proxies events from an driver's connection to the driver itself. + * + * @param {Object} opts proxy options + * @return {EventEmitter} the driver's connection + */ Basestar.prototype.defineDriverEvent = function(opts) { return this._proxyEvents(opts, this.connection, this); }; diff --git a/lib/driver.js b/lib/driver.js index aa0ced0..1e14563 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -8,13 +8,17 @@ function formatErrorMessage(name, message) { return ["Error in driver", "'" + name + "'", "- " + message].join(" "); } -// Public: Creates a new Driver -// -// opts - hash of acceptable params -// name - name of the Driver, used when printing to console -// device - Device the driver will use to proxy commands/events -// -// Returns a new Driver +/** + * Driver class + * + * @constructor Driver + * @param {Object} [opts] driver options + * @param {String} [opts.name] the driver's name + * @param {Object} [opts.robot] the robot the driver belongs to + * @param {Object} [opts.connection] the adaptor the driver works through + * @param {Number} [opts.pin] the pin number the driver should have + * @param {Number} [opts.interval=10] read interval in milliseconds + */ var Driver = module.exports = function Driver(opts) { Driver.__super__.constructor.apply(this, arguments); @@ -45,9 +49,12 @@ var Driver = module.exports = function Driver(opts) { Utils.subclass(Driver, Basestar); -// Public: Basic #start function. Must be overwritten by a descendent class -// -// Returns nothing, throws an error +/** + * A base start function. Must be overwritten by a descendent. + * + * @throws Error if not overridden by a child class + * @return {void} + */ Driver.prototype.start = function() { var message = formatErrorMessage( this.name, @@ -57,9 +64,12 @@ Driver.prototype.start = function() { throw new Error(message); }; -// Public: Basic #halt function. Must be overwritten by a descendent class -// -// Returns nothing, throws an error +/** + * A base halt function. Must be overwritten by a descendent. + * + * @throws Error if not overridden by a child class + * @return {void} + */ Driver.prototype.halt = function() { var message = formatErrorMessage( this.name, @@ -69,6 +79,16 @@ Driver.prototype.halt = function() { throw new Error(message); }; +/** + * Sets up an array of commands for the Driver. + * + * Proxies commands from the Driver to its connection (or a manually specified + * proxy), and adds a snake_cased version to the driver's commands object. + * + * @param {String[]} commands an array of driver commands + * @param {Object} [proxy=this.connection] proxy target + * @return {void} + */ Driver.prototype.setupCommands = function(commands, proxy) { if (proxy == null) { proxy = this.connection; @@ -91,6 +111,11 @@ Driver.prototype.setupCommands = function(commands, proxy) { }, this); }; +/** + * Expresses the Driver in a JSON-serializable format + * + * @return {Object} a representation of the Driver in a serializable format + */ Driver.prototype.toJSON = function() { return { name: this.name, diff --git a/lib/io/digital-pin.js b/lib/io/digital-pin.js index a09e3f6..a277460 100644 --- a/lib/io/digital-pin.js +++ b/lib/io/digital-pin.js @@ -12,8 +12,15 @@ var GPIO_PATH = "/sys/class/gpio"; var GPIO_READ = "in"; var GPIO_WRITE = "out"; -// DigitalPin class offers an interface with the Linux GPIO system present in -// single-board computers such as a Raspberry Pi, or a BeagleBone +/** + * The DigitalPin class provides an interface with the Linux GPIO system present + * in single-board computers such as Raspberry Pi, or Beaglebone Black. + * + * @constructor DigitalPin + * @param {Object} opts digital pin options + * @param {String} pin which pin number to use + * @param {String} mode which pin mode to use + */ var DigitalPin = module.exports = function DigitalPin(opts) { this.pinNum = opts.pin.toString(); this.status = "low"; diff --git a/lib/io/utils.js b/lib/io/utils.js index 2aa94ad..9de2f91 100644 --- a/lib/io/utils.js +++ b/lib/io/utils.js @@ -1,9 +1,15 @@ "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 + /** + * Calculates PWM Period and Duty based on provided params. + * + * @param {Number} scaledDuty the scaled duty value + * @param {Number} freq frequency to use + * @param {Number} pulseWidth pulse width + * @param {String} [polarity=high] polarity value (high or low) + * @return {Object} calculated period and duty encapsulated in an object + */ periodAndDuty: function(scaledDuty, freq, pulseWidth, polarity) { var period, duty, maxDuty; diff --git a/lib/utils.js b/lib/utils.js index 129126f..d257a56 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -5,61 +5,52 @@ var _ = require("./utils/helpers"); var monkeyPatches = require("./utils/monkey-patches"); 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 + /** + * A wrapper around setInterval to provide a more english-like syntax + * (e.g. "every 5 seconds, do this thing") + * + * @param {Number} interval delay between action invocations + * @param {Function} action function to trigger every time interval elapses + * @example every((5).seconds(), function() {}); + * @return {intervalID} setInterval ID to pass to clearInterval() + */ 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 + /** + * A wrapper around setInterval to provide a more english-like syntax + * (e.g. "after 5 seconds, do this thing") + * + * @param {Number} delay how long to wait + * @param {Function} action action to perform after delay + * @example after((5).seconds(), function() {}); + * @return {timeoutId} setTimeout ID to pass to clearTimeout() + */ 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 + /** + * A wrapper around setInterval, with a delay of 0ms + * + * @param {Function} action function to invoke constantly + * @example constantly(function() {}); + * @return {intervalID} setInterval ID to pass to clearInterval() + */ 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 + /** + * Sleeps the program for a period of time. + * + * Use of this is not advised, as your program can't do anything else while + * it's running. + * + * @param {Number} ms number of milliseconds to sleep + * @return {void} + */ sleep: function sleep(ms) { var start = Date.now(), i = 0; @@ -69,19 +60,17 @@ var Utils = module.exports = { } }, - // 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 + /** + * Utility for providing class inheritance. + * + * Based on CoffeeScript's implementation of inheritance. + * + * Parent class methods/properites are available on Child.__super__. + * + * @param {Function} child the descendent class + * @param {Function} parent the parent class + * @return {Function} the child class + */ subclass: function subclass(child, parent) { var Ctor = function() { this.constructor = child; @@ -107,16 +96,15 @@ var Utils = module.exports = { }); }, - // 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 + /** + * Proxies calls from all methods in the source to a target object + * + * @param {String[]} methods methods to proxy + * @param {Object} target object to proxy methods to + * @param {Object} [base=this] object to proxy methods from + * @param {Boolean} [force=false] whether to overwrite existing methods + * @return {Object} the base + */ proxyFunctionsToObject: function(methods, target, base, force) { if (base == null) { base = this; @@ -143,39 +131,31 @@ var Utils = module.exports = { } }, - // 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. + /** + * Approximation of Ruby's Hash#fetch method for object property lookup + * + * @param {Object} obj object to do lookup on + * @param {String} property property name to attempt to access + * @param {*} fallback a fallback value if property can't be found. if + * a function, will be invoked with the string property name. + * @throws Error if fallback needed but not provided, or fallback fn doesn't + * return anything + * @example + * fetch({ property: "hello world" }, "property"); //=> "hello world" + * @example + * fetch({}, "notaproperty", "default value"); //=> "default value" + * @example + * var notFound = function(prop) { return prop + " not found!" }; + * fetch({}, "notaproperty", notFound); //=> "notaproperty not found!" + * @example + * var badFallback = function(prop) { prop + " not found!" }; + * fetch({}, "notaproperty", badFallback); + * // Error: no return value from provided callback function + * @example + * fetch(object, "notaproperty"); + * // Error: key not found: "notaproperty" + * @return {*} fetched property, fallback, or fallback function return value + */ fetch: function(obj, property, fallback) { if (obj.hasOwnProperty(property)) { return obj[property]; @@ -205,6 +185,16 @@ var Utils = module.exports = { // arr - array of existing names // // Returns the new name as a string + + /** + * Given a name, and an array of existing names, returns a unique new name + * + * @param {String} name the name that's colliding with existing names + * @param {String[]} arr array of existing names + * @example + * makeUnique("hello", ["hello", "hello-1", "hello-2"]); //=> "hello3" + * @return {String} the new name + */ makeUnique: function(name, arr) { var newName; @@ -220,20 +210,12 @@ var Utils = module.exports = { } }, - // 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 + /** + * Adds every/after/constantly to the global namespace, and installs + * monkey-patches. + * + * @return {Object} utils object + */ bootstrap: function bootstrap() { global.every = this.every; global.after = this.after; diff --git a/lib/utils/monkey-patches.js b/lib/utils/monkey-patches.js index 13d422c..90a2cd2 100644 --- a/lib/utils/monkey-patches.js +++ b/lib/utils/monkey-patches.js @@ -23,25 +23,6 @@ module.exports.uninstall = function() { }; module.exports.install = function() { - // 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. - // - // Examples - // - // 2.seconds() - // //=> SyntaxError: Unexpected token ILLEGAL - // - // 10..seconds() - // //=> 10000 - // - // (5).seconds() - // //=> 5000 - // // This is the preferred way to represent numbers when calling these - // // methods on them - // - // Returns an integer representing time in milliseconds - /** * Multiplies a number by 1000 to get time in milliseconds *