UNPKG

@game-vir/entity

Version:

Entity system for game development.

69 lines (68 loc) 2.43 kB
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; }