[commands] Add support for registering more than one event listener.
This commit is contained in:
		| @@ -66,6 +66,9 @@ class Bot(GroupMixin, discord.Client): | ||||
|     def __init__(self, command_prefix, **options): | ||||
|         super().__init__(**options) | ||||
|         self.command_prefix = command_prefix | ||||
|         self.extra_events = {} | ||||
|  | ||||
|     # internal helpers | ||||
|  | ||||
|     def _get_variable(self, name): | ||||
|         stack = inspect.stack() | ||||
| @@ -81,6 +84,28 @@ class Bot(GroupMixin, discord.Client): | ||||
|         else: | ||||
|             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 | ||||
|     def say(self, content): | ||||
|         """|coro| | ||||
| @@ -179,6 +204,74 @@ class Bot(GroupMixin, discord.Client): | ||||
|         destination = self._get_variable('_internal_channel') | ||||
|         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 | ||||
|     def process_commands(self, message): | ||||
|         """|coro| | ||||
|   | ||||
		Reference in New Issue
	
	Block a user