@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
118 lines (95 loc) • 2.99 kB
JavaScript
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);
}
}