UNPKG

@vladkrutenyuk/three-kvy-core

Version:

Everything you need to create any-complexity 3D apps with Three.js. Empower Three.js with a modular, lifecycle-managed context that seamlessly propagates through objects via reusable features providing structured logic.

151 lines (150 loc) 6.44 kB
import { EventEmitter } from "eventemitter3"; import { CoreContext, ModulesRecord } from "./CoreContext"; import { IFeaturable } from "./Object3DFeaturablity"; /** * Base class for implementing reusable components (features) that can be added to any Three.js Object3D.\ * Features get the context {@link CoreContext} when their object is added to ctx.root hierarchy, and lose it when removed, or forcibly on call.\ * Handle the context attach and detach can be through overridable lyfecycle method {@link useCtx useCtx(ctx)} where context is providen as arguement.\ * Built-in overridable lifecycle event methods like {@link onBeforeRender onBeforeRender(ctx)} etc. * Direct access to object {@link object this.object} the feature is attached to. * @see {@link https://three-kvy-core.vladkrutenyuk.ru/docs/api/object-3d-feature | Official Documentation} * @see {@link https://github.com/vladkrutenyuk/three-kvy-core/blob/main/src/core/Object3DFeature.ts | Source} */ export declare abstract class Object3DFeature<TModules extends ModulesRecord = {}, TEventTypes extends EventEmitter.ValidEventTypes = string | symbol> extends EventEmitter<TEventTypes> { /** (readonly) Flag to mark that it is an instance of `isObject3DFeature`. */ readonly isObject3DFeature: true; /** (readonly) Unique increment number for this feature instance. */ readonly id: number; /** UUID of feature instance. This gets automatically assigned, so this shouldn't be edited. * Its generation way can be changed via overriding `Object3DFeature.generateUUID` static method. */ uuid: string; /** (readonly) An instance of Three.js Object3D which this feature was added to. */ readonly object: IFeaturable<TModules>; /** * (readonly) Getter for the current attached `CoreContext`. * @warning **Throws exception** if try to access before it is attached. */ get ctx(): CoreContext<TModules>; /** (readonly) Flag to check if this feature has attached `CoreContext`. */ get hasCtx(): boolean; private _ftblty; private _ctx; /** * @private Must be initiallized through the `addFeature` static factory method. * @param {IFeaturable<TModules>} object - The object that this feature is going to be attached to. */ constructor(object: IFeaturable); /** * Initializes the feature. Called internally after instantiation. * @private */ init(): void; /** Destroys this feature instance. */ destroy(): void; private ftbltyAttachedToCtxHandler; private ftbltyDetachedFromCtxHandler; private _useCtxReturn; private attachCtx; private detachCtx; /** * Overridable Lifecycle Method. Called when some `CoreContext` is attached to this feature. * The defined returned cleanup function (optional) is called when the context is detached from the feature. * It is prohibitted to be called manually. * * @param {CoreContext<TModules>} ctx - An instance of `CoreContext` which is attached to this feature. * @returns {undefined | (() => void) | void} A cleanup function, or `undefined` if no cleanup is needed. * @override * * @example * ``` * useCtx(ctx) { * const mesh = new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial()); * this.object.add(mesh); * * const listener = () => { * // ... * } * const customTicker = ctx.modules.customTicker; * customTicker.on("tick", listener); * * return () => { * this.object.remove(mesh); * mesh.geometry.dispose(); * mesh.material.dispose(); * * customTicker.off("tick", listener); * } * } * ``` */ protected useCtx(ctx: CoreContext<TModules>): undefined | (() => void) | void; /** * When this feature `destroy()` is called. * @override */ protected onDestroy(): void; /** * Before render is called. On each frame after loop run `ctx.run()` or `ctx.three.render()` is called manually. * @param {CoreContext<TModules>} ctx - The current attached instance of `CoreContext`. * @override */ onBeforeRender(ctx: CoreContext<TModules>): void; /** * After render is called. On each frame after loop run `ctx.run()` or `ctx.three.render()` is called manually. * @param {CoreContext<TModules>} ctx - The current attached instance of `CoreContext`. * @override */ onAfterRender(ctx: CoreContext<TModules>): void; /** * When container (where mounted) is resized. * @param {CoreContext<TModules>} ctx - The current attached instance of `CoreContext`. * @override */ onResize(ctx: CoreContext<TModules>): void; /** * When `ctx.three.mount(container)` is called. * @param {CoreContext<TModules>} ctx - The current attached instance of `CoreContext`. * @override */ onMount(ctx: CoreContext<TModules>): void; /** * When `ctx.three.unmount()` is called. * @param {CoreContext<TModules>} ctx - The current attached instance of `CoreContext`. * @override */ onUnmount(ctx: CoreContext<TModules>): void; /** * When `ctx.run()` is called. * @param {CoreContext<TModules>} ctx - The current attached instance of `CoreContext`. * @override */ onLoopRun(ctx: CoreContext<TModules>): void; /** * When `ctx.stop()` is called. * @param {CoreContext<TModules>} ctx - The game context. * @override */ onLoopStop(ctx: CoreContext<TModules>): void; private _log; private initCtxEventMethods; /** * initEventHandlerMethod (iehm) */ private iehm; /** * @returns Generates a unique identifier for [`Object3DFeature`](/docs/) instances.\ * By default, it uses [`crypto.randomUUID()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID), but in case of fall back, it returns `${Math.random()}-${Date.now()}`. * You can freely override this static method to any of your own generation, e.g: * ```js * CoreContext.generateUUID = () => nanoid(10) * ``` */ static generateUUID: () => string; /** * Static method for overriding to handle logs. * @param {Object3DFeature} target - The feature instance. * @param {string} msg - The log message. */ static log: (target: Object3DFeature, msg: string) => void; }