Skip to content

Tighten up types for Entity API #7560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 91 additions & 40 deletions src/framework/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ 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}.
*/

/**
* @param {Component} a - First object with `order` property.
* @param {Component} b - Second object with `order` property.
Expand Down Expand Up @@ -336,49 +363,71 @@ 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 built-in component to the entity. The associated component system must be registered
* with the application.
*
* @template {keyof ComponentMap} T
* @overload
* @param {T} type - The type of built-in component to add. Can be:
* - '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 {Partial<ComponentMap[T]>} [data] - Optional initialization data for the component.
* Refer to each specific component's API reference page for details on valid values for this
* parameter.
* @returns {ComponentMap[T] | 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)
* });
*/
/**
* Add a custom component to the entity. The associated component system must be registered
* with the application.
*
* @overload
* @param {string} type - The type of custom component to add.
* @param {any} [data] - Optional initialization data for the component.
* @returns {Component | null} The newly added component or null in the case of an error.
* @example
* const entity = new pc.Entity();
*
* // Add a custom component with some initialization data
* entity.addComponent('custom', {
* foo: 'bar'
* });
*/
/**
* @template {keyof ComponentMap} T
* @param {T | string} type - The type of component to add.
* @param {Partial<ComponentMap[T]> | any} [data] - Optional initialization data for the component.
* @returns {ComponentMap[T] | Component | null} The newly added component or null in the case of an error.
*/
addComponent(type, data) {
const system = this._app.systems[type];
if (!system) {
Expand All @@ -395,7 +444,7 @@ class Entity extends GraphNode {
/**
* Remove a component from the Entity.
*
* @param {string} type - The name of the Component type.
* @param {keyof ComponentMap} type - The name of the Component type.
* @example
* const entity = new pc.Entity();
* entity.addComponent("light"); // add new light component
Expand All @@ -418,9 +467,10 @@ 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} T
* @param {T} type - The name of the component type to retrieve.
* @returns {ComponentMap[T] | 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");
Expand All @@ -433,8 +483,9 @@ 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
* @template {keyof ComponentMap} T
* @param {T} type - The name of the component type to retrieve.
* @returns {ComponentMap[T][]} 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
Expand Down