a
    Ò�éi±  ã                   @   sv   d dl mZ d dlmZ d dlmZmZmZmZm	Z	m
Z
mZmZmZmZ G dd„ deƒZeded�ZG dd	„ d	ƒZd
S )é    )ÚOrderedDict)ÚLock)
ÚAnyÚCallableÚDictÚListÚMappingÚOptionalÚSetÚTupleÚTypeVarÚUnionc                   @   s   e Zd ZdZdS )ÚPyeeExceptionzAn exception internal to pyee.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú9/home/Claro/venv/lib/python3.9/site-packages/pyee/base.pyr      s   r   ÚHandler)Úboundc                   @   sš  e Zd ZdZddœdd„Zeeef dœdd„Zeeef ddœd	d
„Z	d.ee
e eeeegef f dœdd„Zeeegef dœdd„Zeeedœdd„Zeeedœdd„Zeeedf eeef ddœdd„Zee dœdd„Zeeddœdd„Zeeedf eeef edœd d!„Zeeeedœd"d#„Zd/ee
e edœd$d%„Zeeddœd&d'„Zeeddœd(d)„Zd0e
e ddœd*d+„Zeee dœd,d-„Z dS )1ÚEventEmitteraŽ  The base event emitter class. All other event emitters inherit from
    this class.

    Most events are registered with an emitter via the `on` and `once`
    methods, and fired with the `emit` method. However, pyee event emitters
    have two *special* events:

    - `new_listener`: Fires whenever a new listener is created. Listeners for
      this event do not fire upon their own creation.

    - `error`: When emitted raises an Exception by default, behavior can be
      overridden by attaching callback to the event.

      For example:

    ```py
    @ee.on('error')
    def on_error(message):
        logging.err(message)

    ee.emit('error', Exception('something blew up'))
    ```

    All callbacks are handled in a synchronous, blocking manner. As in node.js,
    raised exceptions are not automatically handled for you---you must catch
    your own exceptions, and treat them accordingly.
    N)Úreturnc                 C   s   t ƒ | _tƒ | _d S ©N)ÚdictÚ_eventsr   Ú_lock©Úselfr   r   r   Ú__init__7   s    ýzEventEmitter.__init__c                 C   s   | j  ¡ }|d= |S )Nr   )Ú__dict__Úcopy©r   Ústater   r   r   Ú__getstate__>   s    
zEventEmitter.__getstate__)r#   r   c                 C   s   | j  |¡ tƒ | _d S r   )r    Úupdater   r   r"   r   r   r   Ú__setstate__C   s    zEventEmitter.__setstate__)ÚeventÚfr   c                 C   s"   |du r|   |¡S |  ||¡S dS )au  Registers the function `f` to the event name `event`, if provided.

        If `f` isn't provided, this method calls `EventEmitter#listens_to`, and
        otherwise calls `EventEmitter#add_listener`. In other words, you may either
        use it as a decorator:

        ```py
        @ee.on('data')
        def data_handler(data):
            print(data)
        ```

        Or directly:

        ```py
        ee.on('data', data_handler)
        ```

        In both the decorated and undecorated forms, the event handler is
        returned. The upshot of this is that you can call decorated handlers
        directly, as well as use them in remove_listener calls.

        Note that this method's return type is a union type. If you are using
        mypy or pyright, you will probably want to use either
        `EventEmitter#listens_to` or `EventEmitter#add_listener`.
        N)Ú
listens_toÚadd_listener©r   r'   r(   r   r   r   ÚonG   s    
zEventEmitter.on)r'   r   c                    s   t t dœ‡ ‡fdd„}|S )aV  Returns a decorator which will register the decorated function to
        the event name `event`:

        ```py
        @ee.listens_to("event")
        def data_handler(data):
            print(data)
        ```

        By only supporting the decorator use case, this method has improved
        type safety over `EventEmitter#on`.
        ©r(   r   c                    s   ˆ  ˆ | | ¡ | S r   ©Ú_add_event_handler©r(   ©r'   r   r   r   r,   w   s    z#EventEmitter.listens_to.<locals>.on)r   )r   r'   r,   r   r1   r   r)   i   s    zEventEmitter.listens_toc                 C   s   |   |||¡ |S )a:  Register the function `f` to the event name `event`:

        ```
        def data_handler(data):
            print(data)

        h = ee.add_listener("event", data_handler)
        ```

        By not supporting the decorator use case, this method has improved
        type safety over `EventEmitter#on`.
        r.   r+   r   r   r   r*   }   s    zEventEmitter.add_listener)r'   ÚkÚvc                 C   s\   |   d||¡ | j�4 || jvr,tƒ | j|< || j| |< W d   ƒ n1 sN0    Y  d S )NZnew_listener)Úemitr   r   r   )r   r'   r2   r3   r   r   r   r/   �   s
    
zEventEmitter._add_event_handler.)r(   ÚargsÚkwargsr   c                 C   s   ||i |¤Ž d S r   r   )r   r(   r5   r6   r   r   r   Ú	_emit_runš   s    zEventEmitter._emit_runc                 C   s   t | j ¡ ƒS )z6Get a set of events that this emitter is listening to.)Úsetr   Úkeysr   r   r   r   Úevent_names¢   s    zEventEmitter.event_names)r'   Úerrorr   c                 C   s*   |dkr&t |tƒr|‚ntd|› �ƒ‚d S )Nr;   z%Uncaught, unspecified 'error' event: )Ú
isinstanceÚ	Exceptionr   )r   r'   r;   r   r   r   Ú_emit_handle_potential_error¦   s    
z)EventEmitter._emit_handle_potential_error)r'   r5   r6   r   c                 C   sb   d}| j �( t| j |tƒ ¡ ¡ ƒ}W d   ƒ n1 s80    Y  |D ]}|  |||¡ d}qF|S )NFT)r   Úlistr   Úgetr   Úvaluesr7   )r   r'   r5   r6   ÚhandledÚfuncsr(   r   r   r   Ú_call_handlers­   s    6zEventEmitter._call_handlersc                 O   s.   |   |||¡}|s*|  ||r$|d nd¡ |S )ac  Emit `event`, passing `*args` and `**kwargs` to each attached
        function. Returns `True` if any functions are attached to `event`;
        otherwise returns `False`.

        Example:

        ```py
        ee.emit('data', '00101001')
        ```

        Assuming `data` is an attached function, this will call
        `data('00101001')'`.
        r   N)rD   r>   )r   r'   r5   r6   rB   r   r   r   r4   ½   s    zEventEmitter.emitc                    s.   t t dœ‡ ‡fdd„}|du r"|S ||ƒS dS )zkThe same as `ee.on`, except that the listener is automatically
        removed after being called.
        r-   c                    s,   t t t dœ‡‡ ‡fdd„}ˆ ˆˆ |¡ ˆ S )N)r5   r6   r   c                     sj   ˆj �F ˆ ˆjv r.ˆˆjˆ  v r.ˆ ˆ ˆ¡ nW d   ƒ d S W d   ƒ n1 sR0    Y  ˆ| i |¤ŽS r   )r   r   Ú_remove_listener)r5   r6   )r'   r(   r   r   r   Úgá   s
    .z.EventEmitter.once.<locals>._wrapper.<locals>.g)r   r/   )r(   rF   r1   r0   r   Ú_wrapperà   s    ýz#EventEmitter.once.<locals>._wrapperN)r   )r   r'   r(   rG   r   r1   r   Úonce×   s    	zEventEmitter.oncec                 C   s*   | j |  |¡ t| j | ƒs&| j |= dS )zNaked unprotected removal.N)r   ÚpopÚlenr+   r   r   r   rE   ø   s    zEventEmitter._remove_listenerc                 C   s6   | j � |  ||¡ W d  ƒ n1 s(0    Y  dS )z&Removes the function `f` from `event`.N)r   rE   r+   r   r   r   Úremove_listenerþ   s    zEventEmitter.remove_listenerc                 C   sH   | j �. |durtƒ | j|< ntƒ | _W d  ƒ n1 s:0    Y  dS )ztRemove all listeners attached to `event`.
        If `event` is `None`, remove all listeners on all events.
        N)r   r   r   r   ©r   r'   r   r   r   Úremove_all_listeners  s    z!EventEmitter.remove_all_listenersc                 C   s   t | j |tƒ ¡ ¡ ƒS )z:Returns a list of all listeners registered to the `event`.)r?   r   r@   r   r9   rL   r   r   r   Ú	listeners  s    zEventEmitter.listeners)N)N)N)!r   r   r   r   r   r   Ústrr   r$   r&   r	   r   r   r   r,   r)   r*   r/   r   r   r7   r
   r:   r>   ÚboolrD   r4   rH   rE   rK   rM   r   rN   r   r   r   r   r      sN    ÿþ"

û	

ûû ýü!
r   N)Úcollectionsr   Ú	threadingr   Útypingr   r   r   r   r   r	   r
   r   r   r   r=   r   r   r   r   r   r   r   Ú<module>   s
   0