API Docs for: 0.3.0
Show:

File: modules/Event/InputMapper.js

/**
 * @module Event
 * @namespace Event
 */

var TW = TW || {};
define(['./EventProvider', '../Utils/inherit', '../Utils/Polyfills'], function(EventProvider, inherit) {

	TW.Event = TW.Event || {};


	/**
	 * InputMapper is a virtual event provider used to redirect event under an other event.
	 *
	 * It allow to create custom events (user-defined), following others eventProviders.
	 * Its role is to act as an interface, hiding real event which can be changed without the user noticing.
	 *
	 * A typical utilisation is the remapping is to let the choice of controls keyboard to the player.
	 *
	 *      var keyboardEvents = new KeyboardInput();
	 *      var inputMapper = new InputMapper();
	 *
	 *      inputMapper.addEvent("ATTACK");
	 *      inputMapper.bind("ATTACK", "KEY_Q", keyboardEvents);
	 *
	 *      inputMapper.addListener("ATTACK", KeyboardInput.KEY_PRESSED, function(event, value, provider) {
     *      });
	 *
	 * @class InputMapper
	 * @extends Event.EventProvider
	 * @constructor
	 */
	function InputMapper() {

		EventProvider.call(this);

		/**
		 * enable or disable this object.
		 *
		 * @property {Boolean} enable
		 */
		this.enable = true;

		this._binds = [];
	}

	inherit(InputMapper, EventProvider);

	/**
	 * return the EventProvider type.
	 *
	 * @method getType
	 * @return {String}     "MAPPER"
	 */
	InputMapper.prototype.getType = function() {
		return "MAPPER";
	};


	/**
	 * Getting the name of event bind with localEvent.
	 *
	 * @method getRealEvent
	 * @param {String}  localEvent
	 * @return {String} Name of the real event if it exist or null
	 */
	InputMapper.prototype.getRealEvent = function(localEvent) {
		var i;
		i = this._states.indexOf(localEvent);

		if (i === -1) {
			return null;
		}

		return this._binds[i] ? this._binds[i].event : null;
	};


	/**
	 * Getting a array of all no mapped local event.
	 *
	 * @method getNoMappedEvents
	 * @return {Array} Array with all local events who is not already bound
	 */
	InputMapper.prototype.getNoMappedEvents = function() {
		var i, len, arr;

		arr = [];
		for (i = 0, len = this._binds.length; i < len; ++i) {
			if (this._binds[i] === undefined) {
				arr.push(this._states[i]);
			}
		}
		return arr;
	};

	/**
	 * Adding a local event.
	 *
	 * @method addEvent
	 * @param {String}  name
	 * @return {Boolean} true if success, false if failure
	 */
	InputMapper.prototype.addEvent = function(name) {
		if (this._states.indexOf(name) !== -1) {
			return false;
		}

		this._states.push(name);
		this._binds.push(undefined);
		this._values.push(undefined);
		this._oldValues.push(undefined);

		return true;
	};

	/**
	 * Removing a local event.
	 *
	 * @method rmEvent
	 * @param {String}  name
	 * @return {Boolean} true if success, false if failure
	 */
	InputMapper.prototype.rmEvent = function(name) {
		var i;
		i = this._states.indexOf(name);

		if (i === -1) {
			return false;
		}
		this._states.splice(i, 1);
		this._binds.splice(i, 1);
		this._values.splice(i, 1);
		this._oldValues.splice(i, 1);

		return true;
	};

	/**
	 * Bind a remote event to a local event.
	 *
	 * @method bindEvent
	 * @param {String}  localEvent
	 * @param {String}  remoteEvent
	 * @param {EventProvider}  input
	 */
	InputMapper.prototype.bindEvent = function(localEvent, remoteEvent, input) {
		var i, id;
		i = this._states.indexOf(localEvent);

		if (i === -1 || input.getStateList().indexOf(remoteEvent) === -1) {
			return false;
		}

		if (this._binds[i] !== undefined) {
			this._binds[i].input.rmListener(this._binds[i].id);
		}

		id = input.addListener(remoteEvent, this._bindEvent.bind(this));
		this._binds[i] = {event: remoteEvent, input: input, id: id};
		return true;
	};


	/**
	 * Bind a remote event to a local event by listening to the next event of input.
	 *
	 * @method bindListen
	 * @param {String}  localEvent
	 * @param {EventProvider}  input
	 * @param {Function} callback
	 */
	InputMapper.prototype.bindListen = function(localEvent, input, callback) {
		var i, id;
		i = this._states.indexOf(localEvent);

		if (i === -1) {
			return false;
		}

		if (this._binds[i] !== undefined) {
			this._binds[i].input.rmListener(this._binds[i].id);
		}

		this.stopBindListen();

		id = input.addListener(this._bindListenEvent.bind(this));
		this._binds[i] = {event: undefined, input: input, id: id, callback: callback};
		return true;
	};


	/**
	 * Stop a listening of the function bindListen.
	 *
	 * @method stopBindListen
	 */
	InputMapper.prototype.stopBindListen = function() {
		var i, len;

		for (i = 0, len = this._binds.length; i < len; ++i) {
			if (this._binds[i] !== undefined && this._binds[i].event === undefined) {
				this._binds[i].input.rmListener(this._binds[i].id);
				this._binds.splice(i, 1);
				return;
			}
		}
	};

	/**
	 * Callback function who bind a local event with remote event.
	 *
	 * @method _bindEvent
	 * @param {String}   event
	 * @param {Boolean|Object}   newValue
	 * @param {EventProvider}   object
	 * @private
	 */
	InputMapper.prototype._bindEvent = function(event, newValue, object) {
		var i, len;
		if (this.enable) {
			for (i = 0, len = this._binds.length; i < len; ++i) {
				if (this._binds[i] !== undefined && this._binds[i].event === event &&
				    this._binds[i].input === object) {
					this._modifyState(this._states[i], newValue);
				}
			}
		}
	};

	/**
	 * Callback function who bind a local event with remote event when bindListen is run.
	 *
	 * @method _bindListenEvent
	 * @param {String}   event
	 * @param {Boolean|Object}   newValue
	 * @param {EventProvider}   object
	 * @private
	 */
	InputMapper.prototype._bindListenEvent = function(event, newValue, object) {
		var i, len;
		for (i = 0, len = this._binds.length; i < len; ++i) {
			if (this._binds[i] !== undefined && this._binds[i].event === undefined &&
			    this._binds[i].input === object) {

				this._binds[i].input.rmListener(this._binds[i].id);
				if (this._binds[i].callback !== undefined) {
					this._binds[i].callback(event);
				}
				this.bindEvent(this._states[i], event, object);
			}
		}
	};

	TW.Event.InputMapper = InputMapper;
	return InputMapper;
});