Skip to content
This repository was archived by the owner on Mar 13, 2023. It is now read-only.

feat 💥: delay non-raw listeners until client ready #635

Merged
merged 2 commits into from
Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion naff/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@

import naff.api.events as events
import naff.client.const as constants
from naff.models.naff.context import SendableContext
from naff.api.events import MessageCreate, RawGatewayEvent, processors, Component, BaseEvent
from naff.api.gateway.gateway import GatewayClient
from naff.api.gateway.state import ConnectionState
Expand Down Expand Up @@ -99,6 +98,7 @@
from naff.models.naff.active_voice_state import ActiveVoiceState
from naff.models.naff.application_commands import ModalCommand
from naff.models.naff.auto_defer import AutoDefer
from naff.models.naff.context import SendableContext
from naff.models.naff.hybrid_commands import _prefixed_from_slash, _base_subcommand_generator
from naff.models.naff.listener import Listener
from naff.models.naff.tasks import Task
Expand Down Expand Up @@ -555,6 +555,10 @@ async def generate_prefixes(bot, message):
def _queue_task(self, coro: Listener, event: BaseEvent, *args, **kwargs) -> asyncio.Task:
async def _async_wrap(_coro: Listener, _event: BaseEvent, *_args, **_kwargs) -> None:
try:
if not isinstance(_event, (events.Error, events.RawGatewayEvent)):
if coro.delay_until_ready and not self.is_ready:
await self.wait_until_ready()

if len(_event.__attrs_attrs__) == 2:
# override_name & bot
await _coro()
Expand Down
19 changes: 14 additions & 5 deletions naff/models/naff/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,26 @@ class Listener(CallbackObject):
"""Name of the event to listen to."""
callback: Coroutine
"""Coroutine to call when the event is triggered."""
delay_until_ready: bool
"""whether to delay the event until the client is ready"""

def __init__(self, func: Callable[..., Coroutine], event: str) -> None:
def __init__(self, func: Callable[..., Coroutine], event: str, *, delay_until_ready: bool = True) -> None:
super().__init__()

self.event = event
self.callback = func
self.delay_until_ready = delay_until_ready

@classmethod
def create(cls, event_name: Absent[str | BaseEvent] = MISSING) -> Callable[[Coroutine], "Listener"]:
def create(
cls, event_name: Absent[str | BaseEvent] = MISSING, *, delay_until_ready: bool = True
) -> Callable[[Coroutine], "Listener"]:
"""
Decorator for creating an event listener.

Args:
event_name: The name of the event to listen to. If left blank, event name will be inferred from the function name or parameter.
delay_until_ready: Whether to delay the listener until the client is ready.

Returns:
A listener object.
Expand All @@ -55,20 +61,23 @@ def wrapper(coro: Coroutine) -> "Listener":
if not name:
name = coro.__name__

return cls(coro, get_event_name(name))
return cls(coro, get_event_name(name), delay_until_ready=delay_until_ready)

return wrapper


def listen(event_name: Absent[str | BaseEvent] = MISSING) -> Callable[[Callable[..., Coroutine]], Listener]:
def listen(
event_name: Absent[str | BaseEvent] = MISSING, *, delay_until_ready: bool = True
) -> Callable[[Callable[..., Coroutine]], Listener]:
"""
Decorator to make a function an event listener.

Args:
event_name: The name of the event to listen to. If left blank, event name will be inferred from the function name or parameter.
delay_until_ready: Whether to delay the listener until the client is ready.

Returns:
A listener object.

"""
return Listener.create(event_name)
return Listener.create(event_name, delay_until_ready=delay_until_ready)