/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* @license MPL 2.0
* @copyright Famous Industries, Inc. 2014
*/
/* Modified work copyright © 2015-2016 David Valdman */
define(function(require, exports, module) {
var EventHandler = require('../events/EventHandler');
var SimpleStream = require('../streams/SimpleStream');
// Global registry of input constructors. Append only.
var registry = {};
/**
* Combines multiple inputs (e.g., mouse, touch, scroll) into one unified input.
* Inputs must first be registered on the constructor by a unique identifier,
* then they can be accessed on instantiation.
*
* @example
*
* // In main.js
* GenericInput.register({
* "mouse" : MouseInput,
* "touch" : TouchInput
* });
*
* // in myFile.js
* var input = new GenericInput(['mouse', 'touch'], options);
*
* @class GenericInput
* @constructor
* @namespace Inputs
* @extends Streams.SimpleStream
* @param inputs {Object|String[]} Dictionary with {identifier : option} pairs
* or an array of identifier strings
* @param [options] {Object} Options for all inputs
*/
function GenericInput(inputs, options) {
this._eventInput = new EventHandler();
this._eventOutput = new EventHandler();
EventHandler.setInputHandler(this, this._eventInput);
EventHandler.setOutputHandler(this, this._eventOutput);
this._inputs = {};
if (inputs) this.addInput(inputs);
if (options) this.setOptions(options);
}
GenericInput.prototype = Object.create(SimpleStream.prototype);
GenericInput.prototype.constructor = GenericInput;
/**
* Constrain the input along a specific axis.
*
* @property DIRECTION {Object}
* @property DIRECTION.X {Number} x-axis
* @property DIRECTION.Y {Number} y-axis
* @static
*/
GenericInput.DIRECTION = {
X : 0,
Y : 1
};
/**
* Register a global input class with an identifying key
*
* @method register
* @static
* @param inputObject {Object} an object of {input key : input options} fields
*/
GenericInput.register = function register(inputObject) {
for (var key in inputObject){
if (registry[key]){
if (registry[key] === inputObject[key]) return; // redundant registration
else throw new Error('this key is registered to a different input class');
}
else registry[key] = inputObject[key];
}
};
/**
* Helper to set options on all input instances
*
* @method setOptions
* @param options {Object} options object
*/
GenericInput.prototype.setOptions = function(options) {
for (var key in this._inputs)
this._inputs[key].setOptions(options);
};
/**
* Subscribe events from an input class
*
* @method subscribeInput
* @param key {String} identifier for input class
*/
GenericInput.prototype.subscribeInput = function subscribeInput(key) {
var input = this._inputs[key];
input.subscribe(this._eventInput);
this._eventOutput.subscribe(input);
};
/**
* Unsubscribe events from an input class
*
* @method unsubscribeInput
* @param key {String} identifier for input class
*/
GenericInput.prototype.unsubscribeInput = function unsubscribeInput(key) {
var input = this._inputs[key];
input.unsubscribe(this._eventInput);
this._eventOutput.unsubscribe(input);
};
/**
* Get a registered input by key
*
* @method getInput
* @param key {String} Identifier for input class
* @return {Input}
*/
GenericInput.prototype.getInput = function getInput(key){
return this._inputs[key];
};
function _addSingleInput(key, options) {
if (!registry[key]) return;
this._inputs[key] = new (registry[key])(options);
this.subscribeInput(key);
}
/**
* Add an input class to from the registered classes
*
* @method addInput
* @param inputs {Object|Array.String} an array of registered input keys
* or an object with fields {input key : input options}
*/
GenericInput.prototype.addInput = function addInput(inputs) {
if (inputs instanceof Array)
for (var i = 0; i < inputs.length; i++)
_addSingleInput.call(this, inputs[i]);
else if (inputs instanceof Object)
for (var key in inputs)
_addSingleInput.call(this, key, inputs[key]);
};
module.exports = GenericInput;
});