From ce11b1613c71653e48ddcad9cf1c6299497ea5ab Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Fri, 29 May 2020 23:59:23 -0500 Subject: [PATCH] Finish event system. --- .gitignore | 12 ++++++++++++ .vscode/launch.json | 25 +++++++++++++++++++++++++ .vscode/tasks.json | 20 ++++++++++++++++++++ nimcord.nimble | 4 ++-- src/client.nim | 14 ++++++++++---- src/event_handler.nim | 27 --------------------------- src/eventdispatcher.nim | 16 ++++++++++++++++ src/eventhandler.nim | 36 ++++++++++++++++++++++++++++++++++++ 8 files changed, 121 insertions(+), 33 deletions(-) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json delete mode 100644 src/event_handler.nim create mode 100644 src/eventdispatcher.nim create mode 100644 src/eventhandler.nim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e439757 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Don't track content of these folders + +# Compiled source # +################### +*.exe + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +#*.7z +#*.dmg diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..616c364 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Attach", + "type": "cppdbg", + "request": "attach", + "program": "${workspaceFolder}/src/client.exe", + "processId": "${command:pickProcess}", + "MIMode": "gdb", + "miDebuggerPath": "/path/to/gdb", + "preLaunchTask": "Run client.nim", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + }, + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..c9ce985 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,20 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "taskName": "Run client.nim", + "command": "nim", + "args": ["c", "-d:ssl", "-r", "src/client.nim"], + "options": { + "cwd": "${workspaceRoot}" + }, + "type": "shell", + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/nimcord.nimble b/nimcord.nimble index 6331425..5d65529 100644 --- a/nimcord.nimble +++ b/nimcord.nimble @@ -2,9 +2,9 @@ version = "0.0.0" author = "SeanOMik, Intexisty" -description = "Discord API wrapper written in nim. Inspired by discord.py" +description = "Discord API wrapper written in Nim. Inspired by discord.py" license = "MIT" # Dependencies -requires "nim >= 1.0.4", "websocket >= 0.4.1" \ No newline at end of file +requires "nim >= 1.0.4", "websocket == 0.4.1" \ No newline at end of file diff --git a/src/client.nim b/src/client.nim index 3f9f88a..0515ea4 100644 --- a/src/client.nim +++ b/src/client.nim @@ -1,4 +1,4 @@ -import websocket, asyncnet, asyncdispatch, json, httpClient, strformat +import websocket, asyncnet, asyncdispatch, json, httpClient, strformat, eventdispatcher, eventhandler type DiscordOpCode = enum @@ -14,8 +14,6 @@ type opHello = 10, opHeartbeatAck = 11 - - DiscordClient* = ref object ## Discord Client token*: string #user*: User @@ -72,6 +70,8 @@ proc handleWebsocketPacket(client: DiscordClient) {.async.} = client.heartbeatAcked = true of ord(DiscordOpCode.opHeartbeatAck): client.heartbeatAcked = true + of ord(DiscordOpCode.opDispatch): + handleDiscordEvent(json["d"], json["t"].getStr()) else: discard @@ -101,5 +101,11 @@ proc startConnection*(client: DiscordClient) {.async.} = raise e var bot = DiscordClient(token: - "NjQ4NjcwNDA4NDg4MjU1NTAw.XtCGDw.ZNaRT6kNIMyO1wlcZbbaUGSsm7g") + "TOKEN") + +registerEventListener(EventType.evtReady, proc(bEvt: BaseEvent) = + let event: ReadyEvent = ReadyEvent(bEvt) + echo "Ready and connected!" +) + waitFor bot.startConnection() \ No newline at end of file diff --git a/src/event_handler.nim b/src/event_handler.nim deleted file mode 100644 index 18a7227..0000000 --- a/src/event_handler.nim +++ /dev/null @@ -1,27 +0,0 @@ -import tables, hashes, sequtils - -type - BaseEvent* = object - name*: string - -proc hash[T: object](o: T): Hash = - for k, v in o.fieldPairs: - result = result !& v.hash - result = !$result - -# Table storing all the event listeners -let eventListeners = newTable[BaseEvent, seq[proc()]]() - -proc registerEventListener*(event: BaseEvent, listener: proc()) = - if (eventListeners.hasKey(event)): - var listeners = eventListeners[event] - listeners.add(listener) - else: - let tmp = @[listener] - eventListeners.add(event, tmp) - -proc dispatchEvent(event: BaseEvent) = - if (eventListeners.hasKey(event)): - let listeners = eventListeners[event] - for index, eventListener in listeners.pairs: - eventListener() \ No newline at end of file diff --git a/src/eventdispatcher.nim b/src/eventdispatcher.nim new file mode 100644 index 0000000..eda742b --- /dev/null +++ b/src/eventdispatcher.nim @@ -0,0 +1,16 @@ +import eventhandler, json, tables, hashes + +proc readyEvent(json: JsonNode) = + let readyEvent = ReadyEvent(readyPayload: json, name: $EventType.evtReady) + dispatchEvent(readyEvent) + +let internalEventTable: Table[string, proc(json: JsonNode) {.nimcall.}] = { + "READY": readyEvent + }.toTable + +proc handleDiscordEvent*(json: JsonNode, eventName: string) = + if (internalEventTable.hasKey(eventName)): + let eventProc:proc(json: JsonNode) = internalEventTable[eventName] + eventProc(json) + else: + echo "Failed to find event: ", eventName \ No newline at end of file diff --git a/src/eventhandler.nim b/src/eventhandler.nim new file mode 100644 index 0000000..5f83178 --- /dev/null +++ b/src/eventhandler.nim @@ -0,0 +1,36 @@ +import tables, hashes, json + +type + EventType* = enum + evtReady = "READY" + + BaseEvent* = object of RootObj + name*: string + ReadyEvent* = object of BaseEvent + readyPayload*: JsonNode + +# Table storing all the event listeners +let eventListeners = newTable[string, seq[proc(event: BaseEvent)]]() + +proc registerEventListener*(event: EventType, listener: proc(event: BaseEvent)) = + if (eventListeners.hasKey($event)): + var listeners = eventListeners[$event] + listeners.add(cast[proc(event: BaseEvent)](listener)) + + echo "Added other event listener: ", $event + else: + let tmp = @[listener] + eventListeners.add($event, tmp) + + echo "Added new event listener: ", $event + +proc dispatchEvent*[T: BaseEvent](event: T) = + #let base: BaseEvent = BaseEvent(event) + + if (eventListeners.hasKey(event.name)): + let listeners = eventListeners[event.name] + for index, eventListener in listeners.pairs: + echo "Dispatching event: ", event.name + eventListener(event) + else: + echo "No event listeners for event: ", event.name \ No newline at end of file