[commands] Add support for registering more than one event listener.
This commit is contained in:
parent
52eb0e3adb
commit
c06dbbd1f0
@ -66,6 +66,9 @@ class Bot(GroupMixin, discord.Client):
|
|||||||
def __init__(self, command_prefix, **options):
|
def __init__(self, command_prefix, **options):
|
||||||
super().__init__(**options)
|
super().__init__(**options)
|
||||||
self.command_prefix = command_prefix
|
self.command_prefix = command_prefix
|
||||||
|
self.extra_events = {}
|
||||||
|
|
||||||
|
# internal helpers
|
||||||
|
|
||||||
def _get_variable(self, name):
|
def _get_variable(self, name):
|
||||||
stack = inspect.stack()
|
stack = inspect.stack()
|
||||||
@ -81,6 +84,28 @@ class Bot(GroupMixin, discord.Client):
|
|||||||
else:
|
else:
|
||||||
return prefix
|
return prefix
|
||||||
|
|
||||||
|
@asyncio.coroutine
|
||||||
|
def _run_extra(self, coro, event_name, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
yield from coro(*args, **kwargs)
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
yield from self.on_error(event_name, *args, **kwargs)
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dispatch(self, event_name, *args, **kwargs):
|
||||||
|
super().dispatch(event_name, *args, **kwargs)
|
||||||
|
ev = 'on_' + event_name
|
||||||
|
if ev in self.extra_events:
|
||||||
|
for event in self.extra_events[ev]:
|
||||||
|
coro = self._run_extra(event, event_name, *args, **kwargs)
|
||||||
|
discord.utils.create_task(coro, loop=self.loop)
|
||||||
|
|
||||||
|
# utility "send_*" functions
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def say(self, content):
|
def say(self, content):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
@ -179,6 +204,74 @@ class Bot(GroupMixin, discord.Client):
|
|||||||
destination = self._get_variable('_internal_channel')
|
destination = self._get_variable('_internal_channel')
|
||||||
yield from self.send_typing(destination)
|
yield from self.send_typing(destination)
|
||||||
|
|
||||||
|
# listener registration
|
||||||
|
|
||||||
|
def add_listener(self, func, name=None):
|
||||||
|
"""The non decorator alternative to :meth:`listen`.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
-----------
|
||||||
|
func : coroutine
|
||||||
|
The extra event to listen to.
|
||||||
|
name : Optional[str]
|
||||||
|
The name of the command to use. Defaults to ``func.__name__``.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
async def on_ready(): pass
|
||||||
|
async def my_message(message): pass
|
||||||
|
|
||||||
|
bot.add_listener(on_ready)
|
||||||
|
bot.add_listener(my_message, 'on_message')
|
||||||
|
|
||||||
|
"""
|
||||||
|
name = func.__name__ if name is None else name
|
||||||
|
|
||||||
|
if not asyncio.iscoroutinefunction(func):
|
||||||
|
func = asyncio.coroutine(func)
|
||||||
|
|
||||||
|
if name in self.extra_events:
|
||||||
|
self.extra_events[name].append(func)
|
||||||
|
else:
|
||||||
|
self.extra_events[name] = [func]
|
||||||
|
|
||||||
|
def listen(self, name=None):
|
||||||
|
"""A decorator that registers another function as an external
|
||||||
|
event listener. Basically this allows you to listen to multiple
|
||||||
|
events from different places e.g. such as :func:`discord.on_ready`
|
||||||
|
|
||||||
|
If the function being listened to is not a coroutine, it makes it into
|
||||||
|
a coroutine a la :meth:`Client.async_event`.
|
||||||
|
|
||||||
|
Examples
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
@bot.listen
|
||||||
|
async def on_message(message):
|
||||||
|
print('one')
|
||||||
|
|
||||||
|
# in some other file...
|
||||||
|
|
||||||
|
@bot.listen('on_message')
|
||||||
|
async def my_message(message):
|
||||||
|
print('two')
|
||||||
|
|
||||||
|
Would print one and two in an unspecified order.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func):
|
||||||
|
self.add_listener(func, name)
|
||||||
|
return func
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
# command processing
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def process_commands(self, message):
|
def process_commands(self, message):
|
||||||
"""|coro|
|
"""|coro|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user