一些前置方法
Matcher的其它方法
Matcher.get_receive
class Matcher(metaclass=MatcherMeta):
@overload
def get_receive(self, id: str) -> Union[Event, None]:
...
@overload
def get_receive(self, id: str, default: T) -> Union[Event, T]:
...
def get_receive(
self, id: str, default: Optional[T] = None
) -> Optional[Union[Event, T]]:
return self.state.get(RECEIVE_KEY.format(id=id), default)
# 根据id从state中获取之前放入的Event,如果没有则返回default
Matcher.set_receive
class Matcher(metaclass=MatcherMeta):
def set_receive(self, id: str, event: Event) -> None:
self.state[RECEIVE_KEY.format(id=id)] = event
self.state[LAST_RECEIVE_KEY] = event
# 将Event放入state中,同时将last event设为这个event
Matcher.get_last_receive
class Matcher(metaclass=MatcherMeta):
@overload
def get_last_receive(self) -> Union[Event, None]:
...
@overload
def get_last_receive(self, default: T) -> Union[Event, T]:
...
def get_last_receive(
self, default: Optional[T] = None
) -> Optional[Union[Event, T]]:
return self.state.get(LAST_RECEIVE_KEY, default)
# 取出last event,也就是最后一次set_receive放入的Event
Matcher.get_arg
class Matcher(metaclass=MatcherMeta):
@overload
def get_arg(self, key: str) -> Union[Message, None]:
...
@overload
def get_arg(self, key: str, default: T) -> Union[Message, T]:
...
def get_arg(
self, key: str, default: Optional[T] = None
) -> Optional[Union[Message, T]]:
return self.state.get(ARG_KEY.format(key=key), default)
# 根据key从state中获取之前放入的Message,如果没有则返回default
Matcher.set_arg
class Matcher(metaclass=MatcherMeta):
def set_arg(self, key: str, message: Message) -> None:
self.state[ARG_KEY.format(key=key)] = message
# 将Message放入state中
Matcher.set_target
class Matcher(metaclass=MatcherMeta):
def set_target(self, target: str, cache: bool = True) -> None:
if cache:
self.state[REJECT_CACHE_TARGET] = target
else:
self.state[REJECT_TARGET] = target
# 将target放入state中
Matcher.get_target
class Matcher(metaclass=MatcherMeta):
@overload
def get_target(self) -> Union[str, None]:
...
@overload
def get_target(self, default: T) -> Union[str, T]:
...
def get_target(self, default: Optional[T] = None) -> Optional[Union[str, T]]:
return self.state.get(REJECT_TARGET, default)
# 从state中取出放入的target,若没有则返回default
Matcher.stop_propagation
class Matcher(metaclass=MatcherMeta):
def stop_propagation(self):
self.block = True
# 将Matcher的block设为true
Matcher.resolve_reject
class Matcher(metaclass=MatcherMeta):
async def resolve_reject(self):
handler = current_handler.get() # 获取当前current_handler,是抛出RejectedException的handler
self.handlers.insert(0, handler) # 将抛出RejectedException的handler放到handlers第一位
if REJECT_CACHE_TARGET in self.state:
```
如果state中有REJECT_CACHE_TARGET,将其作为reject的target(见Matcher.set_target)
```
self.state[REJECT_TARGET] = self.state[REJECT_CACHE_TARGET]
补充Matcher.receive与Matcher.got
之前介绍Matcher.receive与Matcher.got是说它们的特点是parameterless第一位是Depends,那时候我们还不知道parameterless的用法,所以没深入介绍,现在介绍他们的作用
根据前面的内容,我们知道parameterless的元素会被转换为Param子类,然后调用Param._solve,_solve的返回值会被忽略。由于只有DependParam可以通过自定义函数进行一些操作,所以一般来说parameterless的元素只能是Depends,例如receive和got
这样来看,parameterless更像是hook,可以在运行handler之前执行一些操作
Matcher.receive
class Matcher(metaclass=MatcherMeta):
@classmethod
def receive(
cls, id: str = "", parameterless: Optional[Iterable[Any]] = None
) -> Callable[[T_Handler], T_Handler]:
async def _receive(event: Event, matcher: "Matcher") -> Union[None, NoReturn]:
matcher.set_target(RECEIVE_KEY.format(id=id))
```
将传入的id设为receive target
由于set_target的cache未传,默认值为True,因此REJECT_CACHE_TARGET为传入的id
```
if matcher.get_target() == RECEIVE_KEY.format(id=id):
```
如果有REJECT_TARGET,将RECEIVE_KEY和LAST_RECEIVE_KEY设为当前event并返回
```
matcher.set_receive(id, event)
return
if matcher.get_receive(id, ...) is not ...:
```
get_receive默认值为...,返回值不是...,说明RECEIVE_KEY存在
即不存在REJECT_TARGET,存在RECEIVE_KEY存在则直接返回
```
return
await matcher.reject() # 抛出RejectedException
_parameterless = (Depends(_receive), *(parameterless or tuple()))
```
parameterless会在handler之前触发,运行_receive函数
```
...
这样来看,parameterless更像是hook,可以在运行handler之前执行一些操作
Matcher.got
class Matcher(metaclass=MatcherMeta):
@classmethod
def got(
cls,
key: str,
prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None,
parameterless: Optional[Iterable[Any]] = None,
) -> Callable[[T_Handler], T_Handler]:
async def _key_getter(event: Event, matcher: "Matcher"):
matcher.set_target(ARG_KEY.format(key=key))
```
将传入的id设为arg target
由于set_target的cache未传,默认值为True,因此REJECT_CACHE_TARGET为传入的id
```
if matcher.get_target() == ARG_KEY.format(key=key):
```
如果有arg target是REJECT_TARGET,将设为当前message并返回
```
matcher.set_arg(key, event.get_message())
return
if matcher.get_arg(key, ...) is not ...:
return
await matcher.reject(prompt)
_parameterless = (Depends(_key_getter), *(parameterless or tuple()))
...
send相关方法
Matcher.send
class Matcher(metaclass=MatcherMeta):
@classmethod
async def send(
cls,
message: Union[str, Message, MessageSegment, MessageTemplate],
**kwargs: Any,
) -> Any:
bot = current_bot.get() # 获取当前bot
event = current_event.get() # 获取当前event
state = current_matcher.get().state # 获取当前state,是Matcher的state,当然包含全局state
if isinstance(message, MessageTemplate): # 如果是MessageTemplate类型,要先构造成message
_message = message.format(**state)
else:
_message = message
return await bot.send(event=event, message=_message, **kwargs) # 发送
Matcher.finish
class Matcher(metaclass=MatcherMeta):
async def finish(
cls,
message: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None,
**kwargs,
) -> NoReturn:
if message is not None: # 发消息
await cls.send(message, **kwargs)
raise FinishedException
```
抛出FinishedException,结束之后的handler和Matcher,直接开始运行event_postprocessor
```
Matcher.pause
class Matcher(metaclass=MatcherMeta):
async def pause(
cls,
prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None,
**kwargs,
) -> NoReturn:
if prompt is not None: # 发消息
await cls.send(prompt, **kwargs)
raise PausedException
```
抛出PausedException,结束之后的handler和Matcher,直接开始运行event_postprocessor
生成一个更新了的temp Matcher,由下一条消息触发
```
Matcher.reject
class Matcher(metaclass=MatcherMeta):
@classmethod
async def reject(
cls,
prompt: Optional[Union[str, Message, MessageSegment, MessageTemplate]] = None,
**kwargs,
) -> NoReturn:
if prompt is not None: # 发消息
await cls.send(prompt, **kwargs)
raise RejectedException
```
RejectedException将在后文统一分析
```