@game-vir/entity
Version:
Entity system for game development.
69 lines (68 loc) • 2.43 kB
JavaScript
import { check } from '@augment-vir/assert';
import { getObjectTypedEntries, getOrSet, } from '@augment-vir/common';
import { BaseEntity, EntityStore, ViewEntity, } from './entity.js';
/**
* This is the starting point of the @game-vir/entity package. Call this to produce the function
* needed to define new entities and the store needed to add entity instances.
*
* @category Main
*/
export function defineEntitySuite() {
const entityKeys = new Set();
function createDefiner(entityParent) {
return (params) => {
return defineEntity(entityParent, params);
};
}
function defineEntity(entityParent, { key, paramsShape, paramsMap }) {
if (entityKeys.has(key)) {
throw new Error(`Entity key '${key}' has already been attached to an entity class.`);
}
entityKeys.add(key);
const classWrapper = {
// @ts-expect-error: abstract methods are intentionally not implemented here
[key]: class extends entityParent {
static entityKey = key;
static paramsShape = paramsShape;
static paramsMap = paramsMap;
static reverseParamsMap = reverseParamsMap(paramsMap);
},
};
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return classWrapper[key];
}
return {
EntityStore: EntityStore,
defineEntity: createDefiner(ViewEntity),
defineLogicEntity: createDefiner(BaseEntity),
entityKeys,
};
}
/**
* Converts {@link ParamsMap} to {@link ReverseParamsMap}.
*
* @category Internal
*/
export function reverseParamsMap(paramsMap) {
if (!paramsMap) {
return undefined;
}
const reverseParamsMap = {};
getObjectTypedEntries(paramsMap).forEach(([topKey, mappings,]) => {
getObjectTypedEntries(mappings).forEach(([mapToKey, mapFromKey,]) => {
if (!mapFromKey) {
return;
}
const paramMapping = getOrSet(reverseParamsMap, check.isString(mapFromKey) ? mapFromKey : mapToKey, () => {
return {};
});
const mapToArray = getOrSet(paramMapping, topKey, () => {
return [];
});
if (!mapToArray.includes(mapToKey)) {
mapToArray.push(mapToKey);
}
});
});
return reverseParamsMap;
}