import * as THREE from "three";
import { DeepPartial, Writable } from "ts-essentials";
import { MessageEvent, SettingsTreeAction } from "@foxglove/studio";
import { PanelContextMenuItem } from "@foxglove/studio-base/components/PanelContextMenu";
import { DraggedMessagePath } from "@foxglove/studio-base/components/PanelExtensionAdapter";
import type { AnyRendererSubscription, IRenderer, RendererConfig } from "./IRenderer";
import { Path } from "./LayerErrors";
import { Renderable } from "./Renderable";
import type { SettingsTreeEntry } from "./SettingsManager";
import { AnyFrameId } from "./transforms";
export type PartialMessage<T> = DeepPartial<T>;
export type PartialMessageEvent<T> = MessageEvent<DeepPartial<T>>;
/**
 * SceneExtension is a base class for extending the 3D scene. It extends THREE.Object3D and is a
 * child of the THREE.Scene with an identity position and orientation (origin is the render frame
 * origin). The `startFrame()` method will automatically call `updatePose()` for each Renderable in
 * the `renderables` map, placing it at the correct pose given the current renderer TransformTree.
 *
 * A minimum implementation can simply add THREE.Object3D instances using `this.add()`. If these
 * instances are Renderables and also added to this.renderables, their pose will be kept
 * up-to-date in `startFrame()`.
 *
 * - Override `dispose()` to dispose of any unmanaged resources such as GPU buffers. Don't forget
 *   to call `super.dispose()`.
 * - Override `startFrame()` to execute code at the start of each frame. Call `super.startFrame()`
 *   to run `updatePose()` on each entry in `this.renderables`.
 * - Override `settingsNodes()` to add entries to the settings sidebar.
 * - Message subscriptions are created with `getSubscriptions()`.
 * - Custom layer actions are added with `renderer.addCustomLayerAction()`.
 */
export declare class SceneExtension<TRenderable extends Renderable = Renderable, E extends THREE.Object3DEventMap = THREE.Object3DEventMap> extends THREE.Object3D<E> {
    /** A unique identifier for this SceneExtension, such as `foxglove.Markers`. */
    readonly extensionId: string;
    /** A reference to the parent `Renderer` instance. */
    protected readonly renderer: IRenderer;
    /** HUD API to place things on the canvas*/
    readonly hud: IRenderer["hud"];
    /**
     * A map of string identifiers to Renderable instances. SceneExtensions are free to use any IDs
     * they choose, although topic names are a common choice for extensions display up to one
     * renderable per topic.
     */
    readonly renderables: Map<string, TRenderable>;
    /**
     * @param extensionId A unique identifier for this SceneExtension, such as `foxglove.Markers`.
     * @param renderer A reference to the parent `Renderer` instance.
     */
    constructor(extensionId: string, renderer: IRenderer);
    /**
     * Called when the scene is being destroyed. Free any unmanaged resources such as GPU buffers
     * here. The base class implementation calls dispose() on all `renderables`.
     */
    dispose(): void;
    /**
     * Will add subscriptions from this scene extension to the renderer
     * This will be called by the renderer when building topic and schema subscriptions on
     * initialization and when imageOnlyMode becomes enabled
     */
    getSubscriptions(): readonly AnyRendererSubscription[];
    /**
     * Called when seeking or a new data source is loaded. The base class implementation removes all
     * `renderables` and calls `updateSettingsTree()`.
     */
    removeAllRenderables(): void;
    /** Allows SceneExtensions to add options to the context menu. */
    getContextMenuItems(): readonly PanelContextMenuItem[];
    /**
     * Returns a list of settings nodes generated by this extension and the paths they appear at in
     * the settings sidebar. This method is only called when the scene fundamentally changes such as
     * new topics appearing or seeking. To manually trigger this method being called, use
     * `updateSettingsTree()`. The base class implementation returns an empty list.
     */
    settingsNodes(): SettingsTreeEntry[];
    /**
     * Handler for settings tree updates such as visibility toggling or field edits. This is a stub
     * meant to be overridden in derived classes and used as the handler for settings tree nodes.
     */
    handleSettingsAction: (action: SettingsTreeAction) => void;
    /**
     * Manually triggers an update of the settings tree for the nodes generated by this extension. The
     * `settingsNodes()` method will be called to retrieve the latest nodes.
     */
    updateSettingsTree(): void;
    /**
     * Persists a value to the panel configuration at the given path. The base class implementation
     * calls `renderer.updateConfig()` and `updateSettingsTree()`.
     */
    saveSetting(path: Path, value: unknown): void;
    /**
     * Can be overridden to react to color scheme changes. The base class implementation does nothing.
     */
    setColorScheme(colorScheme: "dark" | "light", backgroundColor: THREE.Color | undefined): void;
    /** Returns a drop effect if the Scene Extension can handle a message path drop, undefined if it cannot */
    getDropEffectForPath: (path: DraggedMessagePath) => "add" | "replace" | undefined;
    /** Called when a Message Path is dropped on the panel. Allows the scene extension to update the config in response.
     * All updates across all SceneExtensions will occur in one `updateConfig` call on the Renderer
     */
    updateConfigForDropPath: (draft: Writable<RendererConfig>, path: DraggedMessagePath) => void;
    /**
     * Called before the Renderer renders a new frame. The base class implementation calls
     * updatePose() for each entry in `this.renderables`.
     * @param currentTime Current time of the scene being rendered in nanoseconds. This is the
     *   playback timestamp not a message timestamp, so it only makes sense to compare it to
     *   `receiveTime` values.
     * @param renderFrameId Coordinate frame where the scene camera is currently located.
     * @param fixedFrameId The root coordinate frame of the scene, called the fixed frame because it
     *   does not move relative to any parent frame. The fixed frame is the root frame of the render
     *   frame.
     */
    startFrame(currentTime: bigint, renderFrameId: AnyFrameId, fixedFrameId: AnyFrameId): void;
}
/**
 * Takes a list of MessageEvents, groups them by topic, then takes the last message for each topic and adds it to the return array.
 * Used for filtering the subscription message queue between frames (`filterQueue` on `RendererSubscriptions`), such that we don't
 * unnecessarily process messages that will be overwritten.
 */
export declare function onlyLastByTopicMessage<T>(msgs: MessageEvent<T>[]): MessageEvent<T>[];
//# sourceMappingURL=SceneExtension.d.ts.map