Convert cache to use Tables instead and more event dispatches

This commit is contained in:
SeanOMik 2020-06-22 13:04:01 -05:00
parent 980d3c773e
commit 6dc65dfd23
No known key found for this signature in database
GPG Key ID: FA4D55AC05268A88
2 changed files with 61 additions and 24 deletions

View File

@ -1,23 +1,22 @@
import message, member, channel, guild, discordobject, nimcordutils, httpcore, user
import message, member, channel, guild, discordobject, nimcordutils, httpcore, user, tables
type Cache* = ref object
members*: seq[GuildMember]
messages*: seq[Message]
channels*: seq[Channel]
guilds*: seq[Guild]
members*: Table[snowflake, GuildMember]
messages*: Table[snowflake, Message]
channels*: Table[snowflake, Channel]
guilds*: Table[snowflake, Guild]
proc getChannel*(cache: var Cache, id: snowflake): Channel =
## Get a channel object from the id.
##
## If for some reason the channel is not in cache, it gets requested via the
## Discord REST API.
for channel in cache.channels:
if (channel.id == id):
return channel
if (cache.channels.hasKey(id)):
return cache.channels[id]
result = newChannel(sendRequest(endpoint("/channels/" & $id), HttpGet, defaultHeaders(),
id, RateLimitBucketType.channel))
cache.channels.add(result)
cache.channels.add(id, result)
proc getMessageChannel*(msg: Message, cache: var Cache): Channel =
## Get a message's channel object.
@ -31,13 +30,12 @@ proc getGuild*(cache: var Cache, id: snowflake): Guild =
##
## If for some reason the guild is not in cache, it gets requested via the
## Discord REST API.
for guild in cache.guilds:
if (guild.id == id):
return guild
if (cache.guilds.hasKey(id)):
return cache.guilds[id]
result = newGuild(sendRequest(endpoint("/guilds/" & $id), HttpGet, defaultHeaders(),
id, RateLimitBucketType.guild))
cache.guilds.add(result)
cache.guilds.add(result.id, result)
proc getChannelGuild*(channel: Channel, cache: var Cache): Guild =
## Get a channels's guild object.
@ -51,9 +49,8 @@ proc getUser*(cache: Cache, id: snowflake): User =
##
## If for some reason the user is not in cache, it gets requested via the
## Discord REST API.
for member in cache.members:
if (member.user.id == id):
return member.user
if (cache.members.hasKey(id)):
return cache.members[id].user
return newUser(sendRequest(endpoint("/users/" & $id), HttpGet, defaultHeaders()))

View File

@ -1,4 +1,6 @@
import eventhandler, json, tables, message, emoji, user, member, role, guild, channel, nimcordutils, httpClient, strformat, cache, sequtils, asyncdispatch, clientobjects
import eventhandler, json, tables, message, emoji, user, member, role
import guild, channel, nimcordutils, httpClient, strformat, cache
import sequtils, asyncdispatch, clientobjects, discordobject
proc readyEvent(discordClient: DiscordClient, json: JsonNode) =
var readyEvent = ReadyEvent(client: discordClient, readyPayload: json, name: $EventType.evtReady)
@ -26,32 +28,70 @@ proc channelCreateEvent(discordClient: DiscordClient, json: JsonNode) =
# Add the channel to its guild's `channels` field
if (chnl.guildID != 0):
discordClient.cache.cacheGuildChannel(chnl.guildID, chnl)
discordClient.cache.channels.add(chnl)
discordClient.cache.channels.add(chnl.id, chnl)
dispatchEvent(channelCreateEvent)
#proc channelUpdateEvent(discordClient: DiscordClient, json: JsonNode) =
#proc channelDeleteEvent(discordClient: DiscordClient, json: JsonNode) =
proc channelUpdateEvent(discordClient: DiscordClient, json: JsonNode) =
let chnl = newChannel(json)
let channelUpdateEvent = ChannelUpdateEvent(client: discordClient, channel: chnl, name: $EventType.evtChannelUpdate)
if (discordClient.cache.channels.hasKey(chnl.id)):
discordClient.cache.channels[chnl.id] = chnl
else:
discordClient.cache.channels.add(chnl.id, chnl)
dispatchEvent(channelUpdateEvent)
proc channelDeleteEvent(discordClient: DiscordClient, json: JsonNode) =
let chnl = newChannel(json)
let channelDeleteEvent = ChannelDeleteEvent(client: discordClient, channel: chnl, name: $EventType.evtChannelDelete)
var removedChnl: Channel
discard discordClient.cache.channels.pop(chnl.id, removedChnl)
dispatchEvent(channelDeleteEvent)
proc messageCreateEvent(discordClient: DiscordClient, json: JsonNode) =
let msg = newMessage(json)
discordClient.cache.messages.add(msg.id, msg)
let messageCreateEvnt = MessageCreateEvent(client: discordClient, message: msg, name: $EventType.evtMessageCreate)
dispatchEvent(messageCreateEvnt)
proc channelPinsUpdate(discordClient: DiscordClient, json: JsonNode) =
let channelID = getIDFromJson(json["channel_id"].getStr())
var channel: Channel
if (discordClient.cache.channels.hasKey(channelID)):
channel = discordClient.cache.channels[channelID]
channel.lastPinTimestamp = json["last_pin_timestamp"].getStr()
let channelPinsUpdateEvent = ChannelPinsUpdateEvent(client: discordClient, channel: channel, name: $EventType.evtChannelPinsUpdate)
dispatchEvent(channelPinsUpdateEvent)
proc guildCreateEvent(discordClient: DiscordClient, json: JsonNode) =
let g = newGuild(json)
let guildCreateEvnt = GuildCreateEvent(client: discordClient, guild: g, name: $EventType.evtGuildCreate)
discordClient.cache.guilds.insert(g)
discordClient.cache.channels = concat(discordClient.cache.channels, g.channels)
discordClient.cache.members = concat(discordClient.cache.members, g.members)
# Add guild and its channels and members in cache.
discordClient.cache.guilds.add(g.id, g)
for channel in g.channels:
discordClient.cache.channels.add(channel.id, channel)
for member in g.members:
discordClient.cache.members.add(member.id, member)
dispatchEvent(guildCreateEvnt)
let internalEventTable: Table[string, proc(discordClient: DiscordClient, json: JsonNode) {.nimcall.}] = {
"READY": readyEvent,
"MESSAGE_CREATE": messageCreateEvent,
"GUILD_CREATE": guildCreateEvent,
"CHANNEL_CREATE": channelCreateEvent
"CHANNEL_CREATE": channelCreateEvent,
"CHANNEL_UPDATE": channelUpdateEvent,
"CHANNEL_DELETE": channelDeleteEvent
}.toTable
proc handleDiscordEvent*(discordClient: DiscordClient, json: JsonNode, eventName: string) {.async.} =