UNPKG

@dcl/ecs

Version:
240 lines (239 loc) • 9.36 kB
import type { ISchema } from '../schemas/ISchema'; import { MapResult, Spec } from '../schemas/Map'; import { OnChangeFunction } from '../systems/crdt'; import { Transport } from '../systems/crdt/types'; import { ComponentDefinition, GrowOnlyValueSetComponentDefinition, LastWriteWinElementSetComponentDefinition } from './component'; import { Entity, IEntityContainer, EntityState } from './entity'; import { ValueSetOptions } from './grow-only-value-set-component-definition'; import { ReadonlyComponentSchema } from './readonly'; import { SystemFn } from './systems'; export * from './component'; export { ValueSetOptions }; /** * @public */ export type Unpacked<T> = T extends (infer U)[] ? U : T; /** * @public * Overrides component definition to support partial default values */ export interface MapComponentDefinition<T> extends LastWriteWinElementSetComponentDefinition<T> { /** * Add the current component to an entity, throw an error if the component already exists (use `createOrReplace` instead). * - Internal comment: This method adds the &lt;entity,component&gt; to the list to be reviewed next frame * @param entity - Entity that will be used to create the component * @param val - The initial value */ create(entity: Entity, val?: Partial<T>): T; /** * Add the current component to an entity or replace the content if the entity already has the component * - Internal comment: This method adds the &lt;entity,component&gt; to the list to be reviewed next frame * @param entity - Entity that will be used to create or replace the component * @param val - The initial or new value */ createOrReplace(entity: Entity, val?: Partial<T>): T; } /** * @public */ export interface IEngineOptions { onChangeFunction: OnChangeFunction; entityContainer?: IEntityContainer; } /** * @public */ export interface IEngine { _id: number; /** * @public * Increment the used entity counter and return the next one. * @returns the next entity unused */ addEntity(): Entity; /** * @public * Remove all components of an entity * @param entity - entity */ removeEntity(entity: Entity): void; /** * Remove all components of each entity in the tree made with Transform parenting * @param entity - the root entity of the tree */ removeEntityWithChildren(entity: Entity): void; /** * * @public * Check the state of an entityin the engine * @param entity - the entity to validate * @returns EntityState enum */ getEntityState(entity: Entity): EntityState; /** * @public * Add the system to the engine. It will be called every tick updated. * @param system - function that receives the delta time between last tick and current one. * @param priority - a number with the priority, big number are called before smaller ones * @param name - optional: a unique name to identify it * * @example * ```ts * function mySystem(dt: number) { * const entitiesWithMeshRenderer = engine.getEntitiesWith(MeshRenderer, Transform) * for (const [entity, _meshRenderer, _transform] of engine.getEntitiesWith(MeshRenderer, Transform)) { * // do stuffs * } * } * engine.addSystem(mySystem, 10) * ``` */ addSystem(system: SystemFn, priority?: number, name?: string): void; /** * @public * Remove a system from the engine. * @param selector - the function or the unique name to identify * @returns if it was found and removed */ removeSystem(selector: string | SystemFn): boolean; /** * @public * Registers a custom component definition. * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions. * @param componentDefinition - The component definition */ registerComponentDefinition<T>(componentName: string, componentDefinition: ComponentDefinition<T>): ComponentDefinition<T>; /** * @public * Define a component and add it to the engine. * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions. * @param spec - An object with schema fields * @param constructorDefault - the initial value prefilled when a component is created without a value * @returns The component definition * * @example * ```ts * const CustomComponent = engine.defineComponent("my-scene::custom-name", { * id: Schemas.Int, * name: Schemas.String * }) * ``` */ defineComponent<T extends Spec>(componentName: string, spec: T, constructorDefault?: Partial<MapResult<T>>): MapComponentDefinition<MapResult<T>>; /** * @public * Define a component and add it to the engine. * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions. * @param spec - An object with schema fields * @returns The component definition * * @example * ```ts * const StateComponentId = 10023 * const StateComponent = engine.defineComponentFromSchema("my-lib::VisibleComponent", Schemas.Bool) * ``` */ defineComponentFromSchema<T>(componentName: string, spec: ISchema<T>): LastWriteWinElementSetComponentDefinition<T>; /** * @public * Defines a value set component. * @param componentName - unique name to identify the component, a hash is calculated for it, it will fail if the hash has collisions. * @param spec - An object with schema fields * @returns The component definition * * @example * ```ts * const StateComponentId = 10023 * const StateComponent = engine.defineValueSetComponentFromSchema("my-lib::VisibleComponent", Schemas.Int) * ``` */ defineValueSetComponentFromSchema<T>(componentName: string, spec: ISchema<T>, options: ValueSetOptions<T>): GrowOnlyValueSetComponentDefinition<T>; /** * @public * Get the component definition from the component id. * @param componentId - component number or name used to identify the component descriptor * @returns the component definition, throw an error if it doesn't exist * ```ts * const StateComponentId = 10023 * const StateComponent = engine.getComponent(StateComponentId) * ``` */ getComponent<T>(componentId: number | string): ComponentDefinition<T>; /** * Get the component definition from the component id. * @param componentId - component number or name used to identify the component descriptor * @returns the component definition or null if its not founded * ```ts * const StateComponentId = 10023 * const StateComponent = engine.getComponent(StateComponentId) * ``` */ getComponentOrNull<T>(componentId: number | string): ComponentDefinition<T> | null; /** * @public * Get a iterator of entities that has all the component requested. * @param components - a list of component definitions * @returns An iterator of an array with the [entity, component1, component2, ...] * * Example: * ```ts * for (const [entity, meshRenderer, transform] of engine.getEntitiesWith(MeshRenderer, Transform)) { * // the properties of meshRenderer and transform are read only * } * ``` */ getEntitiesWith<T extends [ComponentDefinition<any>, ...ComponentDefinition<any>[]]>(...components: T): Iterable<[Entity, ...ReadonlyComponentSchema<T>]>; /** * @alpha * Search for the entity that matches de label string defined in the editor. * @param value - Name value string */ getEntityOrNullByName<T = string>(label: T): Entity | null; /** * @public * Search for the entity that matches de label string defined in the editor. * @param value - Name value string * @typeParam T - The type of the entity name value */ getEntityByName<T = never, K = T>(value: K & (T extends never ? never : string)): Entity; /** * @public * @param deltaTime - deltaTime in seconds */ update(deltaTime: number): Promise<void>; /** * @public * @param componentId - component number or name */ removeComponentDefinition(componentId: number | string): void; /** * @public * Refer to the root of the scene, all Transforms without a parent are parenting with RootEntity. */ readonly RootEntity: Entity; /** * @public * The current player entity */ readonly PlayerEntity: Entity; /** * @public * Camera entity of current player. */ readonly CameraEntity: Entity; /** * @alpha * @param transport - transport which changes its onmessage to process CRDT messages */ addTransport(transport: Transport): void; /** * @public * Iterator of registered components */ componentsIter(): Iterable<ComponentDefinition<unknown>>; /** * Seals the engine components. It is used to clearly define the scope of the * components that will be available to this engine and to run optimizations. */ seal(): void; }