
    tj2                         d dl Z d dlZddlmZmZmZ ddlmZ ddlm	Z	  e j                  e      Zd Z G d d      Z G d	 d
      Z G d d      Z G d de      Zy)    N   )asynchronous	is_dundershare)reload)
Translatorc                 r    t        | t        j                        r |        xr   |        |i |S  | |i |S N)
isinstanceweakref
WeakMethod)fargskwargss      D/DATA/.local/lib/python3.12/site-packages/trame_server/controller.py
_safe_callr      sG     a++, 	
$T$V$     c                       e Zd ZddZd Zy)TriggerCounterc                     || _         y r
   _count)selfinits     r   __init__zTriggerCounter.__init__   s	    r   c                 D    | xj                   dz  c_         | j                   S )Nr   r   r   s    r   nextzTriggerCounter.next   s    q{{r   N)r   )__name__
__module____qualname__r   r    r   r   r   r      s    r   r   c                   p     e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	 fdZ
d	 Zdd
Zd ZddZddZ xZS )
ControlleraY  Controller acts as a container for function proxies

    It allows functions to be passed around that are not yet defined,
    and can be defined or re-defined later. For example:

    >>> ctrl.trigger_name(fn)
    trigger__12

    >>> f = ctrl.hello_func  # function is currently undefined
    >>> ctrl.hello_func = lambda: print("Hello, world!")
    >>> f()
    Hello, world!

    >>> ctrl.hello_func = lambda: print("Hello again!")
    >>> f()
    Hello again!

    >>> ctrl.on_data_change.add(lambda: print("Update pipeline!"))
    >>> ctrl.on_data_change.add(lambda: print("Update view!"))
    >>> ctrl.on_data_change.add(lambda: print("Wow that is pretty cool!"))
    >>> ctrl.on_data_change()
    "Update pipeline!"
    "Wow that is pretty cool!"
    "Update view!"
    >>> ctrl.on_data_change.clear(set_only=True)  # add, remove, discard, clear
    c           	      F   t         |   d|       t         |   d|r|n	t                      t         |   dt        |di              t         |   dt        |di              t         |   dt        |dt	                            t         |   dt        |di              y )N__trame_hot_reload___translator	_triggers_triggers_fn2name_triggers_name_id
_func_dict)super__setattr__r   r   r   )r   
translatorinternal
hot_reload	__class__s       r   r   zController.__init__8   s    2J?M:VKxb)IJx1Db!I	
 	x1DnFV!W	
 	L%,*KLr   c                 n     j                  d      s j                  j                         fd}|S )z
        Use as decorator `@server.trigger(name)` so the decorated function
        will be able to be called from the client by doing `click="trigger(name)"`.

        :param name: A name to use for that trigger
        :type name: str
        	trigger__c                 p    t         j                  d       | j                  <   j                  | <   | S )Nztrigger(%s))loggerinfor(   r)   funcnamer   s    r   register_triggerz,Controller.trigger.<locals>.register_triggerO   s4    KKt,#'DNN4 +/D""4(Kr   )
startswithr'   translate_key)r   r9   r:   s   `` r   triggerzController.triggerD   s4     {+##11$7D	  r   c                     || j                   v r| j                   |   S d| j                  j                          } | j                  |      |       |S )z
        Given a function this method will register a trigger and returned its name.
        If manually registered, the given name at the time will be returned.

        :return: The trigger name for that function
        :rtype: str
        r3   )r)   r*   r   r=   )r   fnr9   s      r   trigger_namezController.trigger_nameW   sW     '''))"--4116689:T2r   c                 8    | j                   j                  |      S )z
        Given a trigger name get its attached function/method.

        :return: The trigger function for that name
        :rtype: function
        )r(   getr   r9   s     r   
trigger_fnzController.trigger_fnf   s     ~~!!$''r   c                 $    | j                  |      S r
   )__getattr__rC   s     r   __getitem__zController.__getitem__o   s    %%r   c                 (    | j                  ||       y r
   )r-   )r   r9   values      r   __setitem__zController.__setitem__r   s    u%r   c                     t        |      rt        | 	  |      S | j                  j	                  |      }|| j
                  vrt        | |      | j
                  |<   | j
                  |   S r
   )r   r,   rF   r'   r<   r+   ControllerFunction)r   r9   r1   s     r   rF   zController.__getattr__u   s`    T?7&t,,--d3t&$6tT$BDOOD!t$$r   c                    || j                   v s|t        j                   v rd| d}t        |      | j                  j	                  |      }|| j
                  v r|| j
                  |   _        y t        | ||      | j
                  |<   y )N'zA' is a special attribute on Controller that cannot be re-assigned)__dict__r$   	NameErrorr'   r<   r+   r8   rL   )r   r9   r8   msgs       r   r-   zController.__setattr__   s     4== DJ,?,?$?D6 ! !  C. --d34??")-DOOD!&$6tT4$HDOOD!r   c                       fd}|S )a1  
        Use as decorator `@ctrl.add(name)` so the decorated function
        will be added to a given controller name

        :param name: Controller method name to be added to
        :type name: str

        .. code-block::

            ctrl = server.controller

            @ctr.add("on_server_ready")
            def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready.add(on_ready)

        You can also make sure when the method get registered we clear
        any previous content.

        .. code-block::

            ctrl = server.controller

            @ctr.add("on_server_ready", clear=True)
            def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready.clear()
            ctrl.on_server_ready.add(on_ready)

        c                 Z    r   j                             j                  |        | S r
   )clearaddr8   rT   r9   r   s    r   register_ctrl_methodz,Controller.add.<locals>.register_ctrl_method   s+    T
  "JNN4 Kr   r"   r   r9   rT   rW   s   ``` r   rU   zController.add       H	 $#r   c                       fd}|S )a  
        Use as decorator `@ctrl.once(name)` so the decorated function
        will be added to a given controller name and will only execute once.

        :param name: Controller method name to be added to
        :type name: str

        .. code-block::

            ctrl = server.controller

            @ctr.once("on_server_ready")
            def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready.once(on_ready)

        c                 0       j                  |        | S r
   )oncer7   s    r   rW   z-Controller.once.<locals>.register_ctrl_method   s    JOOD!Kr   r"   )r   r9   rW   s   `` r   r\   zController.once   s    *	 $#r   c                       fd}|S )aV  
        Use as decorator `@ctrl.add_task(name)` so the decorated function
        will be added to a given controller name

        :param name: Controller method name to be added to
        :type name: str

        .. code-block::

            ctrl = server.controller

            @ctr.add_task("on_server_ready")
            async def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready.add_task(on_ready)

        You can also make sure when the method get registered we clear
        any previous content.

        .. code-block::

            ctrl = server.controller

            @ctr.add_task("on_server_ready", clear=True)
            async def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready.clear()
            ctrl.on_server_ready.add_task(on_ready)

        c                 Z    r   j                             j                  |        | S r
   )rT   add_taskrV   s    r   rW   z1Controller.add_task.<locals>.register_ctrl_method   s-    T
  "J%Kr   r"   rX   s   ``` r   r_   zController.add_task   rY   r   c                       fd}|S )a)  
        Use as decorator `@ctrl.set(name)` so the decorated function
        will be added to a given controller name

        :param name: Controller method name to be set to
        :type name: str

        .. code-block::

            ctrl = server.controller

            @ctr.set("on_server_ready")
            def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready = on_ready

        You can also make sure when the method get registered we clear
        any previous content.

        .. code-block::

            ctrl = server.controller

            @ctr.set("on_server_ready", clear=True)
            def on_ready(**state):
                pass

            # or
            ctrl.on_server_ready.clear()
            ctrl.on_server_ready = on_ready

        c                 <    r   j                          | <   | S r
   )rT   rV   s    r   rW   z,Controller.set.<locals>.register_ctrl_method(  s$    T
  "DJKr   r"   rX   s   ``` r   setzController.set  rY   r   )NNFF)r   r    r!   __doc__r   r=   r@   rD   rG   rJ   rF   r-   rU   r\   r_   rb   __classcell__)r1   s   @r   r$   r$      sH    6
M &(&&%I +$Z$6+$Z+$r   r$   c                   h    e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 ZddZd ZddZed        Zy)rL   a  Controller functions are callable function proxy objects

    Any calls are forwarded to the internal function, which may be
    undefined or dynamically changed. If a call is made when the
    internal function is undefined, a FunctionNotImplementedError is
    raised.
    Nc                     || _         || _        || _        t               | _        t               | _        t               | _        d| _        y )NF)
controllerr9   r8   rb   funcs
task_funcs
funcs_oncecan_be_empty)r   rh   r9   r8   s       r   r   zControllerFunction.__init__;  s<    $ 		U
%%!r   c           
      j   | j                   Pt        | j                        t        | j                        z   dk(  r"| j                  ry t        | j                        t        | j                        t        | j                        z   }| j                  j                          d }| j                   =| j                  rt        | j                         }n| j                   }t        |g|i |}| j                  rt        t        t        |            }|D cg c]  }t        |g|i | }}t        | j                        D ]3  }|j                  t        j                   t        |g|i |             5 | j                   |S t        |      r|g|S t        | j                        r|S |S c c}w )Nr   )r8   lenri   rj   rl   FunctionNotImplementedErrorr9   listrk   rT   r0   r   r   mapappendr   create_task)r   r   r   	copy_listresultr   resultstask_fns           r   __call__zControllerFunction.__call__G  sq   99TZZ3t3G!G1!L  -dii88$tDOO'<<	 99 499%II3D3F3F??S34I <EE9a:a1$1&19E DOO,GNN((G)Md)Mf)MN - 99Ny>%W%%tN Fs   F0c                 :    | j                   j                  |       y)z
        Add function to the set of functions to be called when
        the current ControllerFunction is called.
        After first execution, the function will automatically be removed.

        :param func: Function to add
        N)rk   rU   r   r8   s     r   r\   zControllerFunction.onceo  s     	D!r   c                 :    | j                   j                  |       y)z
        Add function to the set of functions to be called when
        the current ControllerFunction is called.

        :param func: Function to add
        N)ri   rU   rz   s     r   rU   zControllerFunction.addy  s     	

tr   c                 :    | j                   j                  |       y)z
        Add task to the set of coroutine to be called when
        the current ControllerFunction is called.

        :param func: Function to add
        N)rj   rU   rz   s     r   r_   zControllerFunction.add_task  s     	D!r   c                     | j                   j                  |       | j                  j                  |       | j                  j                  |       y)z
        Discard function to the set of functions to be called when
        the current ControllerFunction is called.

        :param func: Function to discard
        N)ri   discardrk   rj   rz   s     r   r~   zControllerFunction.discard  s:     	

4 %%r   c                 :    | j                   j                  |       y)z
        Remove function to the set of functions to be called when
        the current ControllerFunction is called.

        :param func: Function to remove
        N)ri   removerz   s     r   r   zControllerFunction.remove  s     	

$r   c                 :    | j                   j                  |       y)z
        Remove task function to the set of functions to be called when
        the current ControllerFunction is called.

        :param func: Function to remove
        N)rj   r   rz   s     r   remove_taskzControllerFunction.remove_task  s     	t$r   c                     |sd| _         | j                  j                          | j                  j                          | j                  j                          y)z
        Clear all the functions registered to the current ControllerFunction.

        :param set_only: (default: False) If true only the "added" one will be removed.
        N)r8   ri   rT   rk   rj   )r   set_onlys     r   rT   zControllerFunction.clear  s>     DI

r   c                 x    | j                   yt        | j                        t        | j                        z   dkD  S )z
        Check if at least a function was registered to the current ControllerFunction.

        :return: True if either a function was set or added
        Tr   )r8   rn   ri   rj   r   s    r   existszControllerFunction.exists  s2     99 4::T__!5599r   c                     || _         | S )z
        Enable entry to be empty.
        Useful for events when you don't know if someone will be listening.

        :return: self so it can be used inline like a builder.
        )rl   )r   rI   s     r   enable_emptyzControllerFunction.enable_empty  s     "r   c                 .    | j                   j                  S r
   )rh   r&   r   s    r   r0   zControllerFunction.hot_reload  s    333r   r
   rc   )T)r   r    r!   rd   r   rx   r\   rU   r_   r~   r   r   rT   r   r   propertyr0   r"   r   r   rL   rL   2  sS    
"&P""	& % : 4 4r   rL   c                       e Zd Zy)ro   N)r   r    r!   r"   r   r   ro   ro     s    r   ro   )loggingr   utilsr   r   r   utils.hot_reloadr   utils.namespacer   	getLoggerr   r5   r   r   r$   rL   	Exceptionro   r"   r   r   <module>r      s^      1 1 $ '			8	$ S$ S$lY4 Y4x	) 	r   