{"version":3,"file":"ViewContainer.mjs","sources":["../../../src/scene/view/ViewContainer.ts"],"sourcesContent":["import { type GCable, type GCData } from '../../rendering/renderers/shared/GCSystem';\nimport { type InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';\nimport { type RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';\nimport { type GPUDataOwner, type Renderer } from '../../rendering/renderers/types';\nimport { Bounds } from '../container/bounds/Bounds';\nimport { Container, type ContainerOptions } from '../container/Container';\nimport { type RenderLayer } from '../layers/RenderLayer';\n\nimport type { PointData } from '../../maths/point/PointData';\nimport type { View } from '../../rendering/renderers/shared/view/View';\nimport type { DestroyOptions } from '../container/destroyTypes';\n\n/**\n * A GPU Data object\n * @internal\n */\nexport interface GPUData\n{\n    destroy: () => void;\n}\n\n/** @internal */\nexport interface GPUDataContainer<GPU_DATA extends GPUData = any>\n{\n    _gpuData: Record<number, GPU_DATA>;\n    unload: () => void;\n}\n\n/**\n * Options for the construction of a ViewContainer.\n * @category scene\n * @advanced\n */\nexport interface ViewContainerOptions extends ContainerOptions, PixiMixins.ViewContainerOptions\n{\n    /** If set to true, the resource will be garbage collected automatically when it is not used. */\n    autoGarbageCollect?: boolean;\n}\n// eslint-disable-next-line requireExport/require-export-jsdoc, requireMemberAPI/require-member-api-doc\nexport interface ViewContainer<GPU_DATA extends GPUData = any> extends\n    PixiMixins.ViewContainer, Container, GPUDataOwner<GPU_DATA>, GCable {}\n\n/**\n * A ViewContainer is a type of container that represents a view.\n * This view can be a Sprite, a Graphics object, or any other object that can be rendered.\n * This class is abstract and should not be used directly.\n * @category scene\n * @advanced\n */\nexport abstract class ViewContainer<GPU_DATA extends GPUData = any> extends Container implements View, GCable\n{\n    /** @internal */\n    public override readonly renderPipeId: string;\n    /** @internal */\n    public readonly canBundle = true;\n    /** @internal */\n    public override allowChildren = false;\n\n    /** @internal */\n    public _roundPixels: 0 | 1 = 0;\n    /** @internal */\n    public _lastUsed = -1;\n\n    /** @internal */\n    public _gpuData: Record<number, GPU_DATA> = Object.create(null);\n    /** @internal */\n    public _gcData?: GCData;\n    /** If set to true, the resource will be garbage collected automatically when it is not used. */\n    public autoGarbageCollect = true;\n    /** @internal */\n    public _gcLastUsed = -1;\n\n    protected _bounds: Bounds = new Bounds(0, 1, 0, 0);\n    protected _boundsDirty = true;\n\n    /**\n     * The local bounds of the view in its own coordinate space.\n     * Bounds are automatically updated when the view's content changes.\n     * @example\n     * ```ts\n     * // Get bounds dimensions\n     * const bounds = view.bounds;\n     * console.log(`Width: ${bounds.maxX - bounds.minX}`);\n     * console.log(`Height: ${bounds.maxY - bounds.minY}`);\n     * ```\n     * @returns The rectangular bounds of the view\n     * @see {@link Bounds} For bounds operations\n     */\n    public get bounds()\n    {\n        if (!this._boundsDirty) return this._bounds;\n\n        this.updateBounds();\n\n        this._boundsDirty = false;\n\n        return this._bounds;\n    }\n\n    /** @private */\n    protected abstract updateBounds(): void;\n\n    /**\n     * Whether or not to round the x/y position of the sprite.\n     * @example\n     * ```ts\n     * // Enable pixel rounding for crisp rendering\n     * view.roundPixels = true;\n     * ```\n     * @default false\n     */\n    get roundPixels()\n    {\n        return !!this._roundPixels;\n    }\n\n    set roundPixels(value: boolean)\n    {\n        this._roundPixels = value ? 1 : 0;\n    }\n\n    constructor(options: ViewContainerOptions)\n    {\n        super(options);\n        this.autoGarbageCollect = options.autoGarbageCollect ?? true;\n    }\n\n    /**\n     * Checks if the object contains the given point in local coordinates.\n     * Uses the view's bounds for hit testing.\n     * @example\n     * ```ts\n     * // Basic point check\n     * const localPoint = { x: 50, y: 25 };\n     * const contains = view.containsPoint(localPoint);\n     * console.log('Point is inside:', contains);\n     * ```\n     * @param point - The point to check in local coordinates\n     * @returns True if the point is within the view's bounds\n     * @see {@link ViewContainer#bounds} For the bounds used in hit testing\n     * @see {@link Container#toLocal} For converting global coordinates to local\n     */\n    public containsPoint(point: PointData)\n    {\n        const bounds = this.bounds;\n        const { x, y } = point;\n\n        return (x >= bounds.minX\n            && x <= bounds.maxX\n            && y >= bounds.minY\n            && y <= bounds.maxY);\n    }\n\n    /** @private */\n    public abstract batched: boolean;\n\n    /** @private */\n    protected onViewUpdate()\n    {\n        this._didViewChangeTick++;\n\n        this._boundsDirty = true;\n\n        if (this.didViewUpdate) return;\n        this.didViewUpdate = true;\n\n        const renderGroup = this.renderGroup || this.parentRenderGroup;\n\n        if (renderGroup)\n        {\n            renderGroup.onChildViewUpdate(this);\n        }\n    }\n\n    /** Unloads the GPU data from the view. */\n    public unload(): void\n    {\n        this.emit('unload', this);\n        for (const key in this._gpuData)\n        {\n            this._gpuData[key]?.destroy();\n        }\n        this._gpuData = Object.create(null);\n        this.onViewUpdate();\n    }\n\n    public override destroy(options?: DestroyOptions): void\n    {\n        this.unload();\n        super.destroy(options);\n\n        this._bounds = null;\n    }\n\n    /**\n     * Collects renderables for the view container.\n     * @param instructionSet - The instruction set to collect renderables for.\n     * @param renderer - The renderer to collect renderables for.\n     * @param currentLayer - The current render layer.\n     * @internal\n     */\n    public override collectRenderablesSimple(\n        instructionSet: InstructionSet,\n        renderer: Renderer,\n        currentLayer: RenderLayer,\n    ): void\n    {\n        const { renderPipes } = renderer;\n\n        renderPipes.blendMode.pushBlendMode(this, this.groupBlendMode, instructionSet);\n\n        const rp = renderPipes as unknown as Record<string, RenderPipe>;\n        const pipe = rp[this.renderPipeId];\n\n        if (pipe?.addRenderable)\n        {\n            pipe.addRenderable(this, instructionSet);\n        }\n\n        this.didViewUpdate = false;\n\n        const children = this.children;\n        const length = children.length;\n\n        for (let i = 0; i < length; i++)\n        {\n            children[i].collectRenderables(instructionSet, renderer, currentLayer);\n        }\n        renderPipes.blendMode.popBlendMode(instructionSet);\n    }\n}\n\n"],"names":[],"mappings":"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"}