UNPKG

@javelin/ecs

Version:

76 lines 2.38 kB
import { unpackSparseArray } from "@javelin/core"; import { getSchemaId, toComponentFromType, } from "./component"; import { normalizeType } from "./type"; function hydrateTableFromSnapshot(table, type) { return table.map((column, i) => { const schemaId = type[i]; return column .slice() .map(component => toComponentFromType(component, schemaId)); }); } function createArchetypeStateFromSnapshot(snapshot) { const entities = Object.keys(snapshot.indices).map(Number); const indices = unpackSparseArray(snapshot.indices); const type = normalizeType(snapshot.type); const table = hydrateTableFromSnapshot(snapshot.table, type); return { entities, indices, type, table }; } function createStore(options) { if ("snapshot" in options) { return createArchetypeStateFromSnapshot(options.snapshot); } const type = normalizeType(options.type); const table = type.map(() => []); return { entities: [], indices: [], type, table }; } function invertSignature(signature) { return signature.reduce((a, x, i) => { a[x] = i; return a; }, []); } /** * Create an Archetype. * @param signature * @param table */ export function createArchetype(options) { const { table, indices, entities, type } = createStore(options); const typeInverse = invertSignature(type); function insert(entity, components) { for (let i = 0; i < components.length; i++) { const component = components[i]; const schemaIndex = typeInverse[getSchemaId(component)]; table[schemaIndex].push(component); } indices[entity] = entities.push(entity) - 1; } function remove(entity) { const length = entities.length; const index = indices[entity]; const head = entities.pop(); delete indices[entity]; if (index === length - 1) { for (const column of table) column.pop(); } else { for (const column of table) { column[index] = column.pop(); } entities[index] = head; indices[head] = index; } } return { entities, indices, insert, remove, type, typeInverse, table, }; } //# sourceMappingURL=archetype.js.map