|
"""
|
|
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)
|
|
|