o
    ÉÙ¾iÒ#  ã                   @   sr  d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
mZ edkr&eneZz7edkr0eƒ ‚ejdkrJdd	lmZmZ dd
lmZ ddlmZ ndd	lmZmZ dd
lmZ ddlmZ W n ey|   dd	lmZmZ dd
lmZ ddlmZ Y nw ejZG dd„ deƒZG dd„ deƒZd!dd„Zd"dd„Zdd„ Zdd„ Z dd„ Z!d#dd„Z"dd„ Z#dd „ Z$eeƒ dS )$zFunction namespace.é    )Úabsolute_importNé   )Ú_LIBÚ
check_callÚpy_strÚc_strÚstring_typesÚ	_FFI_MODEÚcythonÚctypes)é   r   )Ú_set_class_functionÚ_set_class_module)ÚFunctionBase)Úconvert_to_decord_funcc                   @   s   e Zd ZdZdS )ÚFunctionaR  The PackedFunc object.

    Function plays an key role to bridge front and backend in DECORD.
    Function provide a type-erased interface, you can call function with positional arguments.

    The compiled module returns Function.
    DECORD backend also registers and exposes its API as Functions.
    For example, the developer function exposed in decord.ir_pass are actually
    C++ functions that are registered as PackedFunc

    The following are list of common usage scenario of decord.Function.

    - Automatic exposure of C++ API into python
    - To call PackedFunc from python side
    - To call python callbacks to inspect results in generated code
    - Bring python hook into C++ backend

    See Also
    --------
    decord.register_func: How to register global function.
    decord.get_global_func: How to get global function.
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úH/home/ubuntu/.local/lib/python3.10/site-packages/decord/_ffi/function.pyr      s    r   c                   @   sV   e Zd ZdZg d¢Zdd„ Zdd„ Zedd„ ƒZdd
d„Z	dd„ Z
dd„ Zdd„ ZdS )Ú
ModuleBasezBase class for module©ÚhandleÚ_entryÚ
entry_namec                 C   s   || _ d | _d| _d S )NÚ__decord_main__r   )Úselfr   r   r   r   Ú__init__=   s   
zModuleBase.__init__c                 C   s   t t | j¡ƒ d S ©N)r   r   ÚDECORDModFreer   ©r   r   r   r   Ú__del__B   s   zModuleBase.__del__c                 C   s    | j r| j S |  | j¡| _ | j S )z}Get the entry function

        Returns
        -------
        f : Function
            The entry function if exist
        )r   Úget_functionr   r"   r   r   r   Ú
entry_funcE   s   	zModuleBase.entry_funcFc              	   C   sH   t ƒ }tt | jt|ƒt |¡t |¡¡ƒ |j	st
d| ƒ‚t|dƒS )a:  Get function from the module.

        Parameters
        ----------
        name : str
            The name of the function

        query_imports : bool
            Whether also query modules imported by this module.

        Returns
        -------
        f : Function
            The result function.
        zModule has no function '%s'F)ÚFunctionHandler   r   ÚDECORDModGetFunctionr   r   r   Úc_intÚbyrefÚvalueÚAttributeErrorr   )r   ÚnameÚquery_importsÚ
ret_handler   r   r   r$   S   s   
ýÿ
zModuleBase.get_functionc                 C   s   t t | j|j¡ƒ dS )z“Add module to the import list of current one.

        Parameters
        ----------
        module : Module
            The other module.
        N)r   r   ÚDECORDModImportr   )r   Úmoduler   r   r   Úimport_modulem   s   zModuleBase.import_modulec                 C   s   t |tƒs	tdƒ‚|  |¡S )Nz%Can only take string as function name)Ú
isinstancer   Ú
ValueErrorr$   )r   r,   r   r   r   Ú__getitem__w   s   

zModuleBase.__getitem__c                 G   s   | j r| j |Ž S | j}||Ž S r    )r   r%   )r   ÚargsÚfr   r   r   Ú__call__|   s   
zModuleBase.__call__N©F)r   r   r   r   Ú	__slots__r   r#   Úpropertyr%   r$   r1   r4   r7   r   r   r   r   r   9   s    


r   Fc                    sL   t ˆ ƒr	ˆ }|j‰ tˆ tƒstdƒ‚t |¡‰‡ ‡fdd„}|r$||ƒS |S )aú  Register global function

    Parameters
    ----------
    func_name : str or function
        The function name

    f : function, optional
        The function to be registered.

    override: boolean optional
        Whether override existing entry.

    Returns
    -------
    fregister : function
        Register function if f is not specified.

    Examples
    --------
    The following code registers my_packed_func as global function.
    Note that we simply get it back from global function table to invoke
    it from python side. However, we can also invoke the same function
    from C++ backend, or in the compiled DECORD code.

    .. code-block:: python

      targs = (10, 10.0, "hello")
      @decord.register_func
      def my_packed_func(*args):
          assert(tuple(args) == targs)
          return 10
      # Get it out from global function table
      f = decord.get_global_func("my_packed_func")
      assert isinstance(f, decord.nd.Function)
      y = f(*targs)
      assert y == 10
    zexpect string function namec                    s.   t | tƒs	t| ƒ} tt tˆ ƒ| jˆ¡ƒ | S )zinternal register function)r2   r   r   r   r   ÚDECORDFuncRegisterGlobalr   r   )Úmyf©Ú	func_nameÚ	ioverrider   r   Úregister²   s   
ÿzregister_func.<locals>.register)Úcallabler   r2   Ústrr3   r   r(   )r>   r6   Úoverrider@   r   r=   r   Úregister_funcƒ   s   '

rD   c                 C   sD   t ƒ }tt t| ƒt |¡¡ƒ |jrt|dƒS |rdS t	d|  ƒ‚)aB  Get a global function by name

    Parameters
    ----------
    name : str
        The name of the global function

    allow_missing : bool
        Whether allow missing function or raise an error.

    Returns
    -------
    func : decord.Function
        The function to be returned, None if function is missing.
    FNzCannot find global function %s)
r&   r   r   ÚDECORDFuncGetGlobalr   r   r)   r*   r   r3   )r,   Úallow_missingr   r   r   r   Úget_global_func¾   s   
rG   c                  C   s\   t  t j¡ƒ } t  ¡ }tt t  |¡t  | ¡¡ƒ g }t|j	ƒD ]}| 
t| | ƒ¡ q |S )z~Get list of global functions registered.

    Returns
    -------
    names : list
       List of global functions names.
    )r   ÚPOINTERÚc_char_pÚc_uintr   r   ÚDECORDFuncListGlobalNamesr)   Úranger*   Úappendr   )ÚplistÚsizeÚfnamesÚir   r   r   Úlist_global_func_namesÚ   s   ÿrR   c                    s>   i ‰ ‡ fdd„}t |ƒ}| |jƒ}|}|dkrtd|  ƒ‚ˆ S )a  
    Extract the extension PackedFuncs from a C module.

    Parameters
    ----------
    finit : ctypes function
        a ctypes that takes signature of DECORDExtensionDeclarer

    Returns
    -------
    fdict : dict of str to Function
        The extracted functions
    c                    s   |ˆ | < d S r    r   )r,   Úfunc©Úfdictr   r   Ú_listü   s   z extract_ext_funcs.<locals>._listr   zcannot initialize with %s)r   r   ÚRuntimeError)ÚfinitrV   r<   ÚretÚ_r   rT   r   Úextract_ext_funcsí   s   
r[   c                 C   s   | }d|_ |S )NT)Ú	is_global)r6   Úflocalr   r   r   Ú_get_api  s   r^   c                 C   s:   |r|n| }|   d¡rt|| dd… ƒ dS t|| ƒ dS )zÄInitialize api for a given module name

    namespace : str
       The namespace of the source registry

    target_module_name : str
       The target module name if different from namespace
    zdecord.é   N)Ú
startswithÚ_init_api_prefix)Ú	namespaceÚtarget_module_namer   r   r   Ú	_init_api
  s
   

ÿ
rd   c                 C   s”   t j|  }tƒ D ]?}| d¡rq| |¡sq|t|ƒd d … }|}| d¡dkr0td| ƒ qt|ƒ}t|ƒ}||_	d| |_
t||j	|ƒ qd S )NrZ   r   Ú.éÿÿÿÿúWarning: invalid API name "%s".úDECORD PackedFunc %s. )ÚsysÚmodulesrR   r`   ÚlenÚfindÚprintrG   r^   r   r   Úsetattr)Úmodule_nameÚprefixr0   r,   ÚfnameÚtarget_moduler6   Úffr   r   r   ra     s"   




ñra   c                  C   st   t ƒ D ]4} |  d¡sqtjd }| }| d¡dkr td| ƒ qt| ƒ}t|ƒ}||_d| |_	t
||j|ƒ qd S )NrZ   zdecord._api_internalre   rf   rg   rh   )rR   r`   ri   rj   rl   rm   rG   r^   r   r   rn   )r,   rr   rq   r6   rs   r   r   r   Ú_init_internal_api/  s   



ôrt   )NFr8   r    )%r   Ú
__future__r   ri   r   Úbaser   r   r   r   r   r	   rW   ÚImportErrorÚIMPORT_EXCEPTÚversion_infoÚ	_cy3.corer   r   r   Ú_FunctionBaser   Ú	_cy2.coreÚ_ctypes.functionÚc_void_pr&   r   Úobjectr   rD   rG   rR   r[   r^   rd   ra   rt   r   r   r   r   Ú<module>   sD    
€ü
J
;
