diff options
-rw-r--r-- | discord/__init__.py | 5 | ||||
-rw-r--r-- | discord/client.py | 24 | ||||
-rw-r--r-- | discord/user.py | 4 | ||||
-rw-r--r-- | discord/utils/__init__.py | 1 | ||||
-rw-r--r-- | discord/utils/event_emitter.py | 29 |
5 files changed, 51 insertions, 12 deletions
diff --git a/discord/__init__.py b/discord/__init__.py index 066d9f5..000b15d 100644 --- a/discord/__init__.py +++ b/discord/__init__.py @@ -1,3 +1,6 @@ """ .. include:: ../README.md -""" \ No newline at end of file +""" + +from .client import * +from .intents import * diff --git a/discord/client.py b/discord/client.py index c61c4b9..4c6be14 100644 --- a/discord/client.py +++ b/discord/client.py @@ -2,10 +2,12 @@ import asyncio import json import sys import threading -import websockets from typing import Coroutine -from discord.intents import Intents, gen_number -from discord.user import User +import websockets + +from .utils import EventEmitter +from .intents import Intents, gen_number +from .user import User class Client: @@ -13,6 +15,7 @@ class Client: self.gateway = None self.loop = asyncio.get_event_loop() self.code = gen_number(intents) + self.event_emitter = EventEmitter() async def connect(self, token: str, intent_code: int): async with websockets.connect("wss://gateway.discord.gg/?v=10&encoding=json") as gateway: @@ -35,8 +38,7 @@ class Client: } await gateway.send(json.dumps(identify)) ready = await gateway.recv() - if (hasattr(self, 'on_ready')): - await getattr(self, 'on_ready')() + self.event_emitter.emit('on_ready', False) self.user = User(json.loads(ready)['d']['user']) async def heartbeat(self, gateway: websockets.WebSocketClientProtocol, interval: int): @@ -50,12 +52,16 @@ class Client: ack = await gateway.recv() def event(self, coro: Coroutine, /) -> Coroutine: + """ + Registers a coroutine to be called when an event is emitted. + """ if not asyncio.iscoroutinefunction(coro): raise TypeError('event registered must be a coroutine function') - - setattr(self, coro.__name__, coro) + self.event_emitter.add_listener(coro.__name__, coro) return coro def run(self, token: str): - self.token = token - asyncio.run(self.connect(self.token, self.code)) \ No newline at end of file + """ + Run the client. + """ + asyncio.run(self.connect(token, self.code)) diff --git a/discord/user.py b/discord/user.py index 838b6e2..16ddf1b 100644 --- a/discord/user.py +++ b/discord/user.py @@ -18,5 +18,5 @@ class User: ) def __init__(self, data: dict): - for k, v in data: - setattr(self, k, v) + for k in data: + setattr(self, k, data[k]) diff --git a/discord/utils/__init__.py b/discord/utils/__init__.py new file mode 100644 index 0000000..7fdb52b --- /dev/null +++ b/discord/utils/__init__.py @@ -0,0 +1 @@ +from .event_emitter import * \ No newline at end of file diff --git a/discord/utils/event_emitter.py b/discord/utils/event_emitter.py new file mode 100644 index 0000000..77fff72 --- /dev/null +++ b/discord/utils/event_emitter.py @@ -0,0 +1,29 @@ +import asyncio +from types import NoneType +from typing import Coroutine + +class EventEmitter(): + def __init__(self): + self.listeners = {} + + def add_listener(self, event_name: str, func: Coroutine): + if not self.listeners.get(event_name, None): + self.listeners[event_name] = {func} + else: + self.listeners[event_name].add(func) + + def remove_listener(self, event_name: str, func: Coroutine): + self.listeners[event_name].remove(func) + if len(self.listeners[event_name]) == 0: + del self.listeners[event_name] + + def emit(self, event_name: str, args_required=False, *args, **kwargs): + listeners = self.listeners.get(event_name, []) + for func in listeners: + if args_required: + if len(args) == 0: + raise TypeError('event registered must have arguments') + else: + asyncio.create_task(func(*args, **kwargs)) + else: + asyncio.create_task(func(*args, **kwargs)) |