class RenderResources:
    """
    The resources handler of the rendering process.
    """

    def __init__(
        self,
        opengl_context: 'moderngl.Context',
        render_target_provider: 'RenderTargetProvider'
    ):
        self.opengl_context: 'moderngl.Context' = opengl_context
        """
        The moderngl context we need to operate with GPU.
        """
        self._render_target_provider: 'RenderTargetProvider' = render_target_provider
        """
        *For internal use only*

        The render target provider, able to handle the
        pool and acquire and release `RenderTarget`
        instances on demand.
        """

        """
        TODO: Maybe having a pool for the textures, that
        is used by the RenderTarget provider is also an
        interesting thing...
        """

        """
        Exposed API below
        """
        self.render_target: '_RenderTargetAccessor' = _RenderTargetAccessor(self._render_target_provider)
        """
        The functionality related to the `RenderTarget`
        instances in one click, by using an instance of its
        provider class.
        """
        

"""
API exposer wrappers below
"""
class _RenderTargetAccessor:
    """
    *For internal use only*

    Wrapper to simplify the access to the functionality
    that the `RenderTargetProvider` is providing to us
    and limitate the part of its API we expose.
    """

    def __init__(
        self,
        render_target_provider: 'RenderTargetProvider'
    ):
        self._render_target_provider: 'RenderTargetProvider' = render_target_provider
        """
        *For internal use only*

        The `RenderTargetProvider` instance that allows us
        to have the functionality.
        """

    def acquire(
        self,
        width: int = 1920,
        height: int = 1080,
        number_of_components: int = 4,
        dtype: str = 'f1'
    ) -> 'RenderTarget':
        """
        Get a `RenderTarget` instance with the given `width`,
        `height`, `number_of_components` and `dtype` from the
        pool, that will mark it as in use.
        """
        return self._render_target_provider.acquire(
            width = width,
            height = height,
            number_of_components = number_of_components,
            dtype = dtype
        )
    
    def acquire_like(
        self,
        render_target: 'RenderTarget'
    ) -> 'RenderTarget':
        """
        Get the `RenderTarget` instance with the same
        properties than the `render_target` provided as
        parameter.
        """
        return self._render_target_provider.acquire_like(
            render_target = render_target
        )

    def release(
        self,
        render_target: 'RenderTarget'
    ):
        """
        Release the `render_target` provided, making it
        available again in the pool and marking it as free.
        """
        self._render_target_provider.release(render_target)