UNPKG

@javelin/ecs

Version:

161 lines 5.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSchemaId = exports.toComponent = exports.toComponentFromType = exports.component = exports.registerSchema = exports.createComponentPool = exports.isComponentOf = exports.$pool = exports.$type = void 0; const core_1 = require("@javelin/core"); const internal_1 = require("./internal"); exports.$type = Symbol("javelin_component_type"); exports.$pool = Symbol("javelin_component_pool"); const { schemaIndex, schemaPools, instanceTypeLookup } = internal_1.UNSAFE_internals; let schemaIds = 0; function createComponentBase(schema, pool = true) { return Object.defineProperties({}, { [exports.$type]: { value: schemaIndex.get(schema), writable: false, enumerable: false, }, [exports.$pool]: { value: pool, writable: false, enumerable: false, }, }); } /** * Check if a component is an instance of a component type. * @param component * @param schema * @returns * @example * const A = {} * const B = {} * const a = component(A) * isComponentOf(a, A) // true * isComponentOf(a, B) // false */ function isComponentOf(component, schema) { return getSchemaId(component) === schemaIndex.get(schema); } exports.isComponentOf = isComponentOf; function createComponentPool(schema, poolSize) { const componentPool = core_1.createStackPool(() => core_1.createSchemaInstance(schema, createComponentBase(schema)), component => core_1.resetSchemaInstance(component, schema), poolSize); return componentPool; } exports.createComponentPool = createComponentPool; const modelConfig = new Map(); /** * Manually register a component type. Optionally specify a unique, integer id * and/or size for the component type's object pool. * @param schema * @param schemaId * @param [poolSize=1000] * @returns * @example <caption>register a schema as a component type (optional)</caption> * ```ts * const Vehicle = { torque: number } * registerSchema(Vehicle) * ``` * @example <caption>register a schema with a fixed id</caption> * ```ts * const Vehicle = { torque: number } * registerSchema(Vehicle, 22) * ``` * @example <caption>register a schema with a fixed id and pool size</caption> * ```ts * const Particle = { color: number } * registerSchema(Particle, 3, 10_000) * ``` */ function registerSchema(schema, schemaId, poolSize = 1000) { let type = schemaIndex.get(schema); if (type !== undefined) { return type; } type = schemaId; if (type === undefined) { while (modelConfig.has(schemaIds)) { schemaIds++; } type = schemaIds; } else if (modelConfig.has(type)) { throw new Error("Failed to register component type: a component with same id is already registered"); } if (poolSize > 0) { schemaPools.set(type, createComponentPool(schema, poolSize)); } modelConfig.set(type, schema); schemaIndex.set(schema, type); internal_1.UNSAFE_setModel(core_1.createModel(modelConfig)); return type; } exports.registerSchema = registerSchema; function createComponentInner(schema) { const type = registerSchema(schema); const pool = internal_1.UNSAFE_internals.schemaPools.get(type); return (pool ? pool.retain() : core_1.createSchemaInstance(schema, createComponentBase(schema, false))); } /** * Use a Schema to create a component. The second parameter is an optional * object that will be used to assign initial values to the new component * instance. * @param schema * @param props * @returns * @example * ```ts * const Quaternion = { x: number, y: number, z: number, w: number } * const quaternion = component(Quaternion, { w: 1 }) * ``` */ function component(schema, props) { const instance = createComponentInner(schema); if (props !== undefined) { Object.assign(instance, props); } return instance; } exports.component = component; function toComponentFromType(object, type) { try { ; object[exports.$type] = type; object[exports.$pool] = false; } catch { } if (object[exports.$type] !== type) { instanceTypeLookup.set(object, type); } return object; } exports.toComponentFromType = toComponentFromType; /** * Instruct the ECS to treat an object as a component instance of a given * schema. * @param object * @param schema * @returns */ function toComponent(object, schema) { const type = registerSchema(schema, undefined, 0); return toComponentFromType(object, type); } exports.toComponent = toComponent; /** * Get the type id (number) of a component. Throws an error if the object is * not a valid component. * @param component * @returns */ function getSchemaId(component) { var _a; const type = (_a = component[exports.$type]) !== null && _a !== void 0 ? _a : instanceTypeLookup.get(component); if (type === undefined) { throw new Error("Failed to get component type id: object is not a component"); } return type; } exports.getSchemaId = getSchemaId; //# sourceMappingURL=component.js.map