Skip to content

Commit

Permalink
Better events
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom32i committed Jun 20, 2014
1 parent 5c8fa90 commit 1d85517
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 146 deletions.
5 changes: 4 additions & 1 deletion .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
"CustomEvent",
"Event",
"console",
"navigator"
"navigator",
"EventEmitter",
"OptionResolver",
"GamepadHandler"
]
}
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@ Percent of noise to ignore around 0.
Ex: deadZone set to 0.3 will cause stick position of from -0.3 to 0.3 to be considered 0.
Stick moves below 30% from default positon won't trigger a change.

__eventType:__ (String: default 'gamepad', available 'gamepad', 'key', 'global')
* global: Send 'gamepad:axis' and 'gamepad:button' each time an axis or a button state change.
* gamepad: Send 'gamepad:(index):axis' and 'gamepad:(index):button' where '(index)' is the index of the gamepad, allowing you to listen to a specific gamepad.
* key: Send 'gamepad:(gamepadIndex):axis:(axisIndex)' and 'gamepad:(gamepadIndex):button:(buttonIndex)' where '(gamepadIndex)' is the index of the gamepad and '(axisIndex)' / 'buttonIndex' is the index of the axis/button, allowing you to listen to a specific button or axis.

Theses options can be set for the whole gamepad:

```javascript
var listener = new GamepadListener({
analog: false,
deadZone: 0.3,
eventType: 'key'
deadZone: 0.3
});
```

Expand All @@ -59,7 +53,16 @@ var listener = new GamepadListener({

## Events:

Listen for value change on gampads:
* 'gamepad:connected': When a new gamepad is connected.
* 'gamepad:disconnected': When a gamepad is disconnected.
* 'gamepad:axis': When a gamepad axis changes.
* 'gamepad:{gamepad}:axis': When a specific gamepad axis changes, '{gamepad}' being the numeric index.
* 'gamepad:{gamepad}:axis:{axis}': When a specific axis on a specific gamepad changes, '{axis}' being the numeric index of the axis.
* 'gamepad:button': When a gamepad button changes.
* 'gamepad:{gamepad}:button': When a specific gamepad button changes, '{gamepad}' being the numeric index.
* 'gamepad:{gamepad}:button:{button}': When a specific button on a specific gamepad changes, '{button}' being the numeric index of the button.

__Listen for value change on gampads:__

```javascript

Expand All @@ -73,6 +76,15 @@ listener.on('gamepad:connected', function (event) {
*/
});

listener.on('gamepad:disconnected', function (event) {
/**
* event: CustomEvent
* detail: {
* index: 0
* }
*/
});

listener.on('gamepad:axis', function (event) {
/**
* event: CustomEvent
Expand Down
149 changes: 81 additions & 68 deletions dist/gamepad.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function GamepadHandler(gamepad, options)
EventEmitter.call(this);

this.gamepad = gamepad;
this.options = options;
this.options = this.resolveOptions(typeof(options) === 'object' ? options : {});
this.sticks = new Array(this.gamepad.axes.length);
this.buttons = new Array(this.gamepad.buttons.length);

Expand All @@ -40,6 +40,49 @@ function GamepadHandler(gamepad, options)

GamepadHandler.prototype = Object.create(EventEmitter.prototype);

/**
* Option resolver
*
* @type {OptionResolver}
*/
GamepadHandler.prototype.optionResolver = new OptionResolver(false);

GamepadHandler.prototype.optionResolver.setDefaults({
analog: true,
deadZone: 0,
precision: 0
});

GamepadHandler.prototype.optionResolver.setTypes({
analog: 'boolean',
deadZone: 'number',
precision: 'number'
});

/**
* Resolve options
*
* @param {Object} options
*
* @return {Object}
*/
GamepadHandler.prototype.resolveOptions = function(source)
{
var customStick = typeof source.stick !== 'undefined',
customButton = typeof source.button !== 'undefined',
options = {
stick: this.optionResolver.resolve(customStick ? source.stick : (customButton ? {} : source)),
button: this.optionResolver.resolve(customButton ? source.button : (customStick ? {} : source))
};

options.stick.deadZone = Math.max(Math.min(options.stick.deadZone, 1), 0);
options.button.deadZone = Math.max(Math.min(options.button.deadZone, 1), 0);
options.stick.precision = options.stick.precision ? Math.pow(10, options.stick.precision) : 0;
options.button.precision = options.button.precision ? Math.pow(10, options.button.precision) : 0;

return options;
};

/**
* Update
*/
Expand Down Expand Up @@ -128,65 +171,20 @@ function GamepadListener(options)
{
EventEmitter.call(this);

this.options = this.resolveOptions(typeof(options) === 'object' ? options : {});
this.options = typeof(options) === 'object' ? options : {};
this.frame = null;
this.update = this.update.bind(this);
this.onAxis = this.onAxis.bind(this);
this.onButton = this.onButton.bind(this);
this.stop = this.stop.bind(this);
this.handlers = new Array(4);

window.addEventListener('error', this.stop);

this.start();
}

GamepadListener.prototype = Object.create(EventEmitter.prototype);

/**
* Option resolver
*
* @type {OptionResolver}
*/
GamepadListener.prototype.optionResolver = new OptionResolver(false);

GamepadListener.prototype.optionResolver.setDefaults({
analog: true,
deadZone: 0,
precision: 0,
eventType: 'gamepad'
});

GamepadListener.prototype.optionResolver.setTypes({
analog: 'boolean',
deadZone: 'number',
precision: 'number',
eventType: 'string'
});

/**
* Resolve options
*
* @param {Object} options
*
* @return {Object}
*/
GamepadListener.prototype.resolveOptions = function(source)
{
var customStick = typeof source.stick !== 'undefined',
customButton = typeof source.button !== 'undefined',
options = {
stick: this.optionResolver.resolve(customStick ? source.stick : (customButton ? {} : source)),
button: this.optionResolver.resolve(customButton ? source.button : (customStick ? {} : source))
};

options.stick.deadZone = Math.max(Math.min(options.stick.deadZone, 1), 0);
options.button.deadZone = Math.max(Math.min(options.button.deadZone, 1), 0);
options.stick.precision = options.stick.precision ? Math.pow(10, options.stick.precision) : 0;
options.button.precision = options.button.precision ? Math.pow(10, options.button.precision) : 0;

return options;
};

/**
* Start
*/
Expand Down Expand Up @@ -224,6 +222,8 @@ GamepadListener.prototype.update = function()
}

gamepads[i].handler.update();
} else if (this.handlers[i]) {
this.removeGamepad(i);
}
}
};
Expand All @@ -235,12 +235,37 @@ GamepadListener.prototype.update = function()
*/
GamepadListener.prototype.addGamepad = function(gamepad)
{
console.log('addGamepad', gamepad);

var handler = new GamepadHandler(gamepad, this.options);

handler.on('gamepad:axis', this.onAxis);
handler.on('gamepad:button', this.onButton);
handler.on('axis', this.onAxis);
handler.on('button', this.onButton);

this.emit('gamepad:connected', {gamepad: gamepad, index: gamepad.index});
this.emit('gamepad:' + gamepad.index + ':connected', {gamepad: gamepad, index: gamepad.index});

this.handlers[gamepad.index] = handler;
};

/**
* Add gamepad
*
* @param {Gamepad} gamepad
*/
GamepadListener.prototype.removeGamepad = function(index)
{
var handler = this.handlers[index];

console.log('removeGamepad', index, handler, handler.gamepad);

handler.off('axis', this.onAxis);
handler.off('button', this.onButton);

this.emit('gamepad:disconnected', {index: index});
this.emit('gamepad:' + index + ':disconnected', {index: index});

this.handlers[index] = null;
};

/**
Expand All @@ -250,15 +275,9 @@ GamepadListener.prototype.addGamepad = function(gamepad)
*/
GamepadListener.prototype.onAxis = function(event)
{
var eventName = 'gamepad:axis';

if (this.options.eventType == 'gamepad') {
eventName = 'gamepad:' + event.detail.gamepad.index + ':axis';
} else if (this.options.eventType == 'key') {
eventName = 'gamepad:' + event.detail.gamepad.index + ':axis:' + event.detail.axis;
}

this.emit(eventName, event.detail);
this.emit('gamepad:axis', event.detail);
this.emit('gamepad:' + event.detail.gamepad.index + ':axis', event.detail);
this.emit('gamepad:' + event.detail.gamepad.index + ':axis:' + event.detail.axis, event.detail);
};

/**
Expand All @@ -268,15 +287,9 @@ GamepadListener.prototype.onAxis = function(event)
*/
GamepadListener.prototype.onButton = function(event)
{
var eventName = 'gamepad:button';

if (this.options.eventType == 'gamepad') {
eventName = 'gamepad:' + event.detail.gamepad.index + ':button';
} else if (this.options.eventType == 'key') {
eventName = 'gamepad:' + event.detail.gamepad.index + ':button:' + event.detail.index;
}

this.emit(eventName, event.detail);
this.emit('gamepad:button', event.detail);
this.emit('gamepad:' + event.detail.gamepad.index + ':button', event.detail);
this.emit('gamepad:' + event.detail.gamepad.index + ':button:' + event.detail.index, event.detail);
};

/**
Expand Down
Loading

0 comments on commit 1d85517

Please sign in to comment.