coherent-gameface-interaction-manager
Version:
Library for the most common UI interactions
137 lines (136 loc) • 5.13 kB
JavaScript
(function(global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.actions = factory());
})(this, (function() {
"use strict";
class IM {
constructor() {
this.actions = [];
this.keyboardFunctions = [];
this.gamepadFunctions = [];
}
/**
* Initialize global object
*/
init() {
if (!window._IM) window._IM = new IM();
}
/**
* Get keyboard functions matching the given keys
*/
getKeys(keys) {
return _IM.keyboardFunctions.filter((keyFunction) => keyFunction.keys.every((key) => keys.includes(key)));
}
/**
* Get the index of a keyboard function matching the given keys
*/
getKeysIndex(keys) {
return _IM.keyboardFunctions.findIndex((keyFunction) => keyFunction.keys.every((key) => keys.includes(key)));
}
/**
* Get a gamepad function matching the given button actions and type
*/
getGamepadAction({ actions, type }) {
return _IM.gamepadFunctions.find((gpFunc) => {
return gpFunc.actions.every((action) => actions.includes(action)) && gpFunc.type === type && gpFunc.actions.length === actions.length;
});
}
/**
* Get all gamepad functions matching the given button actions
*/
getGamepadActions(actions, exactMatch = true) {
return _IM.gamepadFunctions.filter(
(gpFunc) => gpFunc.actions.every((action) => actions.includes(action)) && (exactMatch ? gpFunc.actions.length === actions.length : true)
);
}
/**
* Get the index of a gamepad function matching the given button actions
*/
getGamepadActionIndex(actions) {
return _IM.gamepadFunctions.findIndex((gpFunc) => gpFunc.actions.every((action) => actions.includes(action)));
}
/**
* Get an action by name
* @param {string} action - Action to search for
*/
getAction(action) {
return _IM.actions.find((actionObj) => actionObj.name === action);
}
/**
* Get the index of an action by name
*/
getActionIndex(action) {
return _IM.actions.findIndex((actionObj) => actionObj.name === action);
}
/**
* Checks if a callback already exists in a registered function entry
*/
hasDuplicateCallback(functionEntry, callback) {
return functionEntry.callbacks.some((cb) => cb === callback);
}
/**
* Adds a callback to an existing function entry if it's not a duplicate
* @param {KeyboardFunction | GamepadFunction} functionEntry - The function entry to add the callback to
* @param {Function | string} callback - The callback to add
* @param {Object} errorContext - Context information for error messages
* @param {string} errorContext.identifier - String identifying the keys/actions (e.g., "Keys: [A, B]")
* @param {string} errorContext.type - The type of action (press, hold, lift)
*/
addCallbackToEntry(functionEntry, callback, errorContext) {
if (this.hasDuplicateCallback(functionEntry, callback)) {
const callbackType = typeof callback === "string" ? "action" : "function";
const callbackName = typeof callback === "string" ? callback : "(anonymous function)";
return console.error(
`Duplicate callback detected!
${errorContext.identifier}
Type: '${errorContext.type}'
Callback: ${callbackName}
This ${callbackType} is already registered for this combination and type. To update it, first remove with the .off() method.`
);
}
return functionEntry.callbacks.push(callback);
}
/**
* Removes a keyboard function entry from the registry
*/
removeKeyboardFunction(functionEntry) {
const index = _IM.keyboardFunctions.indexOf(functionEntry);
if (index !== -1) _IM.keyboardFunctions.splice(index, 1);
}
/**
* Removes a gamepad function entry from the registry
*/
removeGamepadFunction(functionEntry) {
const index = _IM.gamepadFunctions.indexOf(functionEntry);
if (index !== -1) _IM.gamepadFunctions.splice(index, 1);
}
}
const IM$1 = new IM();
class Actions {
/**
* Register an action
*/
register(action, callback) {
if (IM$1.getAction(action)) return console.error(`The following action "${action}" is already registered!`);
_IM.actions.push({ name: action, callback });
}
/**
* Remove a registered action
*/
remove(action) {
const actionIndex = IM$1.getActionIndex(action);
if (actionIndex === -1) return console.error(`${action} is not a registered action!`);
_IM.actions.splice(actionIndex, 1);
}
/**
* Trigger an action
*/
execute(action, value) {
const actionObject = IM$1.getAction(action);
if (!actionObject) return console.error(`${action} is not a registered action!`);
actionObject.callback(value);
}
}
const Actions$1 = new Actions();
IM$1.init();
return Actions$1;
}));