UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

118 lines (95 loc) 2.99 kB
import { assert } from "../../core/assert.js"; import { BitSet } from "../../core/binary/BitSet.js"; export class EntityObserver { /** * * @type {BitSet} */ componentMask = new BitSet(); /** * Mapping from component index to position in array of observed component types, * this is used to build arguments for callbacks * @type {number[]} */ componentIndexMapping = []; /** * * @type {EntityComponentDataset|null} */ dataset = null; /** * * @param {Array} componentTypes * @param {function(components:Array)} completedCallback * @param {function(components:Array)} brokenCallback * @param {*} [thisArg=undefined] will assume {@link this} value inside callbacks * @constructor */ constructor( componentTypes, completedCallback, brokenCallback, thisArg ) { assert.isArray(componentTypes, 'componentTypes must be an array, instead was something else'); assert.isFunction(completedCallback, 'completedCallback'); assert.isFunction(brokenCallback, 'brokenCallback'); const numComponentTypes = componentTypes.length; if (numComponentTypes < 1) { throw new Error(`Observer has to have at least 1 component types to watch, instead was given ${numComponentTypes}`); } /** * @type {number} */ this.componentTypeCount = numComponentTypes; /** * * @type {function(Array)} */ this.callbackComplete = completedCallback; /** * * @type {function(Array)} */ this.callbackBroken = brokenCallback; /** * * @type {Array} */ this.componentTypes = componentTypes; /** * * @type {*} */ this.thisArg = thisArg; } /** * * @param {Array} componentTypeMap */ build(componentTypeMap) { let i; this.componentIndexMapping = []; this.componentMask.reset(); for (i = 0; i < this.componentTypeCount; i++) { const componentType = this.componentTypes[i]; const componentTypeIndex = componentTypeMap.indexOf(componentType); if (componentTypeIndex === -1) { throw new Error(`Component type[${i}] was not found in the supplied map. Observer is not compatible.`); } this.componentMask.set(componentTypeIndex, true); this.componentIndexMapping[componentTypeIndex] = i; } } /** * * @param {EntityComponentDataset} dataset */ connect(dataset) { dataset.addObserver(this, true); } disconnect() { //de-register updates this.dataset.removeObserver(this); } }