|
2 | 2 | import inspect
|
3 | 3 | import json
|
4 | 4 | from collections import defaultdict
|
5 |
| -from typing import Any, Callable, Dict, List, Optional, Set |
| 5 | +from typing import Any, Callable, Coroutine, Dict, List, Optional, Set, Union |
6 | 6 |
|
7 | 7 | import websockets.client
|
8 | 8 | from pyee.asyncio import AsyncIOEventEmitter
|
|
12 | 12 | from .consts import ActorEventTypes
|
13 | 13 | from .log import logger
|
14 | 14 |
|
| 15 | +ListenerType = Union[Callable[[], None], Callable[[Any], None], Callable[[], Coroutine[Any, Any, None]], Callable[[Any], Coroutine[Any, Any, None]]] |
| 16 | + |
15 | 17 |
|
16 | 18 | @ignore_docs
|
17 | 19 | class EventManager:
|
@@ -87,26 +89,37 @@ async def close(self, event_listeners_timeout_secs: Optional[float] = None) -> N
|
87 | 89 |
|
88 | 90 | self._initialized = False
|
89 | 91 |
|
90 |
| - def on(self, event_name: ActorEventTypes, listener: Callable) -> Callable: |
| 92 | + def on(self, event_name: ActorEventTypes, listener: ListenerType) -> Callable: |
91 | 93 | """Add an event listener to the event manager.
|
92 | 94 |
|
93 | 95 | Args:
|
94 | 96 | event_name (ActorEventTypes): The actor event for which to listen to.
|
95 | 97 | listener (Callable): The function which is to be called when the event is emitted (can be async).
|
| 98 | + Must accept either zero or one arguments (the first argument will be the event data). |
96 | 99 | """
|
97 | 100 | if not self._initialized:
|
98 | 101 | raise RuntimeError('EventManager was not initialized!')
|
99 | 102 |
|
| 103 | + listener_argument_count = len(inspect.signature(listener).parameters) |
| 104 | + if listener_argument_count > 1: |
| 105 | + raise ValueError('The "listener" argument must be a callable which accepts 0 or 1 arguments!') |
| 106 | + |
100 | 107 | event_name = _maybe_extract_enum_member_value(event_name)
|
101 | 108 |
|
102 |
| - async def inner_wrapper(*args: Any, **kwargs: Any) -> None: |
| 109 | + async def inner_wrapper(event_data: Any) -> None: |
103 | 110 | if inspect.iscoroutinefunction(listener):
|
104 |
| - await listener(*args, **kwargs) |
| 111 | + if listener_argument_count == 0: |
| 112 | + await listener() |
| 113 | + else: |
| 114 | + await listener(event_data) |
105 | 115 | else:
|
106 |
| - listener(*args, **kwargs) |
| 116 | + if listener_argument_count == 0: |
| 117 | + listener() # type: ignore[call-arg] |
| 118 | + else: |
| 119 | + listener(event_data) # type: ignore[call-arg] |
107 | 120 |
|
108 |
| - async def outer_wrapper(*args: Any, **kwargs: Any) -> None: |
109 |
| - listener_task = asyncio.create_task(inner_wrapper(*args, **kwargs)) |
| 121 | + async def outer_wrapper(event_data: Any) -> None: |
| 122 | + listener_task = asyncio.create_task(inner_wrapper(event_data)) |
110 | 123 | self._listener_tasks.add(listener_task)
|
111 | 124 | try:
|
112 | 125 | await listener_task
|
|
0 commit comments