import { CanvasVariant } from './context';

/**
 * An async function that executes the render in the loop. This function can return an
 * optional cleanup that is executed before the next render. This cleanup function will
 * be passed the signature of the previous render request.
 */
export type Func = () => Promise<Cleanup | undefined>;
/**
 * A request to render a component in the aether visualization tree. Submit a complete
 * version of this request to the {@link Loop} to render a component.
 */
export interface Request {
    /**
     * A key identifying the component requesting the render. This helps to prevent
     * duplicate renders for the same component from being executed.
     */
    key: string;
    /**
     * A priority ("high" or "low") for the render. High priority renders that have
     * an equal or greater number of canvases will replace low priority renders already
     * requested.
     */
    priority: Priority;
    /**
     * A list of canvases that the component is requesting to render to. This provides
     * information to cleanup functions about which canvases to clear. The component should
     * ONLY render to these canvases, otherwise the cleanup function may unnecessarily
     * clear canvases that should persist.
     */
    canvases: CanvasVariant[];
    /**
     * An async function that performs the render. This function can return an optional
     * cleanup that is executed before the next render. This cleanup function will be
     * passed the signature of the previous render request.
     */
    render: Func;
}
/**
 * A cleanup function that receives the request from the previous render. Cleanup
 * functions should clear canvases and other resources that need to be freed from
 * the previous render.
 */
export type Cleanup = (req: Request) => Promise<void>;
export type Priority = "high" | "low";
/**
 * Implements the core rendering loop for Synnax's aether components, accepting requests
 * into a queue and rendering them in sync with the browser animation frame.
 *
 * --------------------------------- VERY IMPORTANT ------------------------------
 *
 * This loop intentionally permits race conditions on the requests map access. We tried
 * locking this with an async mutex, but this resulted in a significant performance
 * hit for high-speed rendering for live telemetry. We've decided
 *
 */
export declare class Loop {
    private readonly mutex;
    /** Stores the current requests for rendering. */
    private readonly requests;
    /** Stores render cleanup functions for clearing canvases and other resources. */
    private readonly cleanup;
    private readonly afterRender?;
    constructor(afterRender?: () => void);
    /**
     * Sets a new request in the queue according to a set of rules:
     *
     * 1. If no request with the same key exists, add the request to the queue.
     * 2. If a request with the same key exists, replace it if the new request has a
     * greater or equal priority and a greater or equal number of canvases that are
     * being rendered to.
     *
     * @param req - The request to set.
     */
    set(req: Request): Promise<void>;
    /** Execute the render. */
    private render;
    /** Starts the rendering loop. */
    private start;
    private sleep;
}
//# sourceMappingURL=loop.d.ts.map