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;
}
