@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
157 lines (121 loc) • 3.69 kB
JavaScript
import { resolvePath } from "../../../../core/json/resolvePath.js";
import { System } from "../../../ecs/System.js";
import { Input } from "../components/Input.js";
import { assert } from "../../../../core/assert.js";
/**
*
* @param {string} path
* @param {function} action
* @param devices
* @param {*} thisArg
*/
function linkBinding(path, action, devices, thisArg) {
/**
*
* @type {Signal}
*/
const signal = resolvePath(devices, path);
assert.notEqual(signal, undefined, `signal at path '${path}' is undefined`);
assert.notEqual(signal, null, `signal at path '${path}' is null`);
assert.ok(signal.isSignal, `expected signal.isSignal to be true, instead got '${signal.isSignal}'`);
signal.add(action, thisArg);
}
function unlinkBinding(path, action, devices, thisArg) {
/**
*
* @type {Signal}
*/
const signal = resolvePath(devices, path);
assert.notEqual(signal, undefined, `signal at path '${path}' is undefined`);
assert.notEqual(signal, null, `signal at path '${path}' is null`);
assert.ok(signal.isSignal, `expected signal.isSignal to be true, instead got '${signal.isSignal}'`);
signal.remove(action, thisArg);
}
class BindingLink {
/**
*
* @param {InputBinding} binding
* @param {EntityComponentDataset} dataset
* @param {number} entity
* @param {object} devices
*/
constructor(binding, dataset, entity, devices) {
/**
*
* @type {InputBinding}
*/
this.binding = binding;
/**
*
* @type {EntityComponentDataset}
*/
this.dataset = dataset;
/**
*
* @type {number}
*/
this.entity = entity;
this.devices = devices;
}
/**
*
* @param {*} eventData
*/
emit(eventData) {
this.dataset.sendEvent(this.entity, this.binding.event, eventData);
}
link() {
linkBinding(this.binding.path, this.emit, this.devices, this);
}
unlink() {
unlinkBinding(this.binding.path, this.emit, this.devices, this);
}
}
export class InputSystem extends System {
constructor(devices) {
super();
this.dependencies = [Input];
this.devices = devices;
/**
*
* @type {Map<number,BindingLink[]>}
*/
this.links = new Map();
}
/**
*
* @param {Input} component
* @param entity
*/
link(component, entity) {
const mapping = component.bindings;
const dataset = this.entityManager.dataset;
const devices = this.devices;
const links = [];
//create links array
this.links.set(entity, links);
for (let i = 0; i < mapping.length; i++) {
const binding = mapping.get(i);
const bindingLink = new BindingLink(binding, dataset, entity, devices);
bindingLink.link();
links.push(bindingLink);
}
//TODO support binding alteration while component is linked
}
/**
*
* @param {Input} component
* @param entity
*/
unlink(component, entity) {
const bindingLinks = this.links.get(entity);
if (bindingLinks === undefined) {
console.error(`Bindings for entity '${entity}' not found`);
}
for (const bindingLink of bindingLinks) {
bindingLink.unlink();
}
//cleanup
this.links.delete(entity);
}
}