File size: 2,914 Bytes
0aee47a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
"""
bilibili_api.utils.AsyncEvent
发布-订阅模式异步事件类支持。
"""
import asyncio
from typing import Callable, Coroutine
class AsyncEvent:
"""
发布-订阅模式异步事件类支持。
特殊事件:__ALL__ 所有事件均触发
"""
def __init__(self):
self.__handlers = {}
self.__ignore_events = []
def add_event_listener(self, name: str, handler: Coroutine) -> None:
"""
注册事件监听器。
Args:
name (str): 事件名。
handler (Coroutine): 回调异步函数。
"""
name = name.upper()
if name not in self.__handlers:
self.__handlers[name] = []
self.__handlers[name].append(handler)
def on(self, event_name: str) -> Callable:
"""
装饰器注册事件监听器。
Args:
event_name (str): 事件名。
"""
def decorator(func: Coroutine):
self.add_event_listener(event_name, func)
return func
return decorator
def remove_all_event_listener(self) -> None:
"""
移除所有事件监听函数
"""
self.__handlers = {}
def remove_event_listener(self, name: str, handler: Coroutine) -> bool:
"""
移除事件监听函数。
Args:
name (str): 事件名。
handler (Coroutine): 要移除的函数。
Returns:
bool, 是否移除成功。
"""
name = name.upper()
if name in self.__handlers:
if handler in self.__handlers[name]:
self.__handlers[name].remove(handler)
return True
return False
def ignore_event(self, name: str) -> None:
"""
忽略指定事件
Args:
name (str): 事件名。
"""
name = name.upper()
self.__ignore_events.append(name)
def remove_ignore_events(self) -> None:
"""
移除所有忽略事件
"""
self.__ignore_events = []
def dispatch(self, name: str, *args, **kwargs) -> None:
"""
异步发布事件。
Args:
name (str): 事件名。
*args, **kwargs: 要传递给函数的参数。
"""
if len(args) == 0 and len(kwargs.keys()) == 0:
args = [{}]
if name.upper() in self.__ignore_events:
return
name = name.upper()
if name in self.__handlers:
for coroutine in self.__handlers[name]:
asyncio.create_task(coroutine(*args, **kwargs))
if name != "__ALL__":
kwargs.update({"name": name, "data": args})
self.dispatch("__ALL__", kwargs)
|