diff --git a/src/framework/entity.js b/src/framework/entity.js index 79c36359c37..c9d88cf4e4a 100644 --- a/src/framework/entity.js +++ b/src/framework/entity.js @@ -30,6 +30,34 @@ import { getApplication } from './globals.js'; * @import { SpriteComponent } from './components/sprite/component.js' */ +/** + * @typedef {{ + * anim: AnimComponent; + * animation: AnimationComponent; + * audiolistener: AudioListenerComponent; + * button: ButtonComponent; + * camera: CameraComponent; + * collision: CollisionComponent; + * element: ElementComponent; + * gsplat: GSplatComponent; + * layoutchild: LayoutChildComponent; + * layoutgroup: LayoutGroupComponent; + * light: LightComponent; + * model: ModelComponent; + * particlesystem: ParticleSystemComponent; + * render: RenderComponent; + * rigidbody: RigidBodyComponent; + * screen: ScreenComponent; + * script: ScriptComponent; + * scrollbar: ScrollbarComponent; + * scrollview: ScrollViewComponent; + * sound: SoundComponent; + * sprite: SpriteComponent; + * }} ComponentMap A map of component names to their class types. Facilitates typings for + * {@link Entity#addComponent}, {@link Entity#removeComponent}, + * {@link Entity#findComponent}, and {@link Entity#findComponents}. + */ + /** * @param {Component} a - First object with `order` property. * @param {Component} b - Second object with `order` property. @@ -334,45 +362,48 @@ class Entity extends GraphNode { } /** - * Create a new component and add it to the entity. Use this to add functionality to the entity - * like rendering a model, playing sounds and so on. - * - * @param {string} type - The name of the component to add. Valid strings are: - * - * - "anim" - see {@link AnimComponent} - * - "animation" - see {@link AnimationComponent} - * - "audiolistener" - see {@link AudioListenerComponent} - * - "button" - see {@link ButtonComponent} - * - "camera" - see {@link CameraComponent} - * - "collision" - see {@link CollisionComponent} - * - "element" - see {@link ElementComponent} - * - "gsplat" - see {@link GSplatComponent} - * - "layoutchild" - see {@link LayoutChildComponent} - * - "layoutgroup" - see {@link LayoutGroupComponent} - * - "light" - see {@link LightComponent} - * - "model" - see {@link ModelComponent} - * - "particlesystem" - see {@link ParticleSystemComponent} - * - "render" - see {@link RenderComponent} - * - "rigidbody" - see {@link RigidBodyComponent} - * - "screen" - see {@link ScreenComponent} - * - "script" - see {@link ScriptComponent} - * - "scrollbar" - see {@link ScrollbarComponent} - * - "scrollview" - see {@link ScrollViewComponent} - * - "sound" - see {@link SoundComponent} - * - "sprite" - see {@link SpriteComponent} - * - * @param {object} [data] - The initialization data for the specific component type. Refer to - * each specific component's API reference page for details on valid values for this parameter. - * @returns {Component|null} The new Component that was attached to the entity or null if there - * was an error. + * Add a component to the entity. The associated component system must be registered with the + * application. Built-in component types are listed below; arbitrary string IDs are also + * accepted for custom component systems. + * + * - 'anim' - see {@link AnimComponent} + * - 'animation' - see {@link AnimationComponent} + * - 'audiolistener' - see {@link AudioListenerComponent} + * - 'button' - see {@link ButtonComponent} + * - 'camera' - see {@link CameraComponent} + * - 'collision' - see {@link CollisionComponent} + * - 'element' - see {@link ElementComponent} + * - 'gsplat' - see {@link GSplatComponent} + * - 'layoutchild' - see {@link LayoutChildComponent} + * - 'layoutgroup' - see {@link LayoutGroupComponent} + * - 'light' - see {@link LightComponent} + * - 'model' - see {@link ModelComponent} + * - 'particlesystem' - see {@link ParticleSystemComponent} + * - 'render' - see {@link RenderComponent} + * - 'rigidbody' - see {@link RigidBodyComponent} + * - 'screen' - see {@link ScreenComponent} + * - 'script' - see {@link ScriptComponent} + * - 'scrollbar' - see {@link ScrollbarComponent} + * - 'scrollview' - see {@link ScrollViewComponent} + * - 'sound' - see {@link SoundComponent} + * - 'sprite' - see {@link SpriteComponent} + * + * @template {keyof ComponentMap | (string & {})} T + * @param {T} type - The type of component to add. + * @param {T extends keyof ComponentMap ? Partial : unknown} [data] - Optional + * initialization data for the component. For built-in component types, this is strictly typed + * against the component's properties; refer to each specific component's API reference page + * for details on valid values. + * @returns {(T extends keyof ComponentMap ? ComponentMap[T] : Component) | null} The newly + * added component or null in the case of an error. * @example * const entity = new pc.Entity(); * * // Add a light component with default properties - * entity.addComponent("light"); + * entity.addComponent('light'); * - * // Add a camera component with some specified properties - * entity.addComponent("camera", { + * // Add a camera component with some initialization data + * entity.addComponent('camera', { * fov: 45, * clearColor: new pc.Color(1, 0, 0) * }); @@ -393,7 +424,8 @@ class Entity extends GraphNode { /** * Remove a component from the Entity. * - * @param {string} type - The name of the Component type. + * @param {keyof ComponentMap | (string & {})} type - The name of the Component type. Built-in + * component names are auto-suggested; arbitrary strings are accepted for custom components. * @example * const entity = new pc.Entity(); * entity.addComponent("light"); // add new light component @@ -416,9 +448,12 @@ class Entity extends GraphNode { /** * Search the entity and all of its descendants for the first component of specified type. * - * @param {string} type - The name of the component type to retrieve. - * @returns {Component} A component of specified type, if the entity or any of its descendants - * has one. Returns undefined otherwise. + * @template {keyof ComponentMap | (string & {})} T + * @param {T} type - The name of the component type to retrieve. Built-in component names are + * auto-suggested; arbitrary strings are accepted for custom components. + * @returns {(T extends keyof ComponentMap ? ComponentMap[T] : Component) | undefined} A + * component of specified type, if the entity or any of its descendants has one. Returns + * undefined otherwise. * @example * // Get the first found light component in the hierarchy tree that starts with this entity * const light = entity.findComponent("light"); @@ -431,9 +466,11 @@ class Entity extends GraphNode { /** * Search the entity and all of its descendants for all components of specified type. * - * @param {string} type - The name of the component type to retrieve. - * @returns {Component[]} All components of specified type in the entity or any of its - * descendants. Returns empty array if none found. + * @template {keyof ComponentMap | (string & {})} T + * @param {T} type - The name of the component type to retrieve. Built-in component names are + * auto-suggested; arbitrary strings are accepted for custom components. + * @returns {(T extends keyof ComponentMap ? ComponentMap[T] : Component)[]} All components of + * specified type in the entity or any of its descendants. Returns empty array if none found. * @example * // Get all light components in the hierarchy tree that starts with this entity * const lights = entity.findComponents("light");