第四节 Matcher的运行(send)

realhuhu 191 0

一些前置方法

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将在后文统一分析
        ```

发表评论 取消回复
表情 图片 链接 代码

分享