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 type Cache* = ref object
members*: seq[GuildMember] members*: Table[snowflake, GuildMember]
messages*: seq[Message] messages*: Table[snowflake, Message]
channels*: seq[Channel] channels*: Table[snowflake, Channel]
guilds*: seq[Guild] guilds*: Table[snowflake, Guild]
proc getChannel*(cache: var Cache, id: snowflake): Channel = proc getChannel*(cache: var Cache, id: snowflake): Channel =
## Get a channel object from the id. ## Get a channel object from the id.
## ##
## If for some reason the channel is not in cache, it gets requested via the ## If for some reason the channel is not in cache, it gets requested via the
## Discord REST API. ## Discord REST API.
for channel in cache.channels: if (cache.channels.hasKey(id)):
if (channel.id == id): return cache.channels[id]
return channel
result = newChannel(sendRequest(endpoint("/channels/" & $id), HttpGet, defaultHeaders(), result = newChannel(sendRequest(endpoint("/channels/" & $id), HttpGet, defaultHeaders(),
id, RateLimitBucketType.channel)) id, RateLimitBucketType.channel))
cache.channels.add(result) cache.channels.add(id, result)
proc getMessageChannel*(msg: Message, cache: var Cache): Channel = proc getMessageChannel*(msg: Message, cache: var Cache): Channel =
## Get a message's channel object. ## 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 ## If for some reason the guild is not in cache, it gets requested via the
## Discord REST API. ## Discord REST API.
for guild in cache.guilds: if (cache.guilds.hasKey(id)):
if (guild.id == id): return cache.guilds[id]
return guild
result = newGuild(sendRequest(endpoint("/guilds/" & $id), HttpGet, defaultHeaders(), result = newGuild(sendRequest(endpoint("/guilds/" & $id), HttpGet, defaultHeaders(),
id, RateLimitBucketType.guild)) id, RateLimitBucketType.guild))
cache.guilds.add(result) cache.guilds.add(result.id, result)
proc getChannelGuild*(channel: Channel, cache: var Cache): Guild = proc getChannelGuild*(channel: Channel, cache: var Cache): Guild =
## Get a channels's guild object. ## 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 ## If for some reason the user is not in cache, it gets requested via the
## Discord REST API. ## Discord REST API.
for member in cache.members: if (cache.members.hasKey(id)):
if (member.user.id == id): return cache.members[id].user
return member.user
return newUser(sendRequest(endpoint("/users/" & $id), HttpGet, defaultHeaders())) 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) = proc readyEvent(discordClient: DiscordClient, json: JsonNode) =
var readyEvent = ReadyEvent(client: discordClient, readyPayload: json, name: $EventType.evtReady) 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 # Add the channel to its guild's `channels` field
if (chnl.guildID != 0): if (chnl.guildID != 0):
discordClient.cache.cacheGuildChannel(chnl.guildID, chnl) discordClient.cache.cacheGuildChannel(chnl.guildID, chnl)
discordClient.cache.channels.add(chnl) discordClient.cache.channels.add(chnl.id, chnl)
dispatchEvent(channelCreateEvent) dispatchEvent(channelCreateEvent)
#proc channelUpdateEvent(discordClient: DiscordClient, json: JsonNode) = proc channelUpdateEvent(discordClient: DiscordClient, json: JsonNode) =
#proc channelDeleteEvent(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) = proc messageCreateEvent(discordClient: DiscordClient, json: JsonNode) =
let msg = newMessage(json) let msg = newMessage(json)
discordClient.cache.messages.add(msg.id, msg)
let messageCreateEvnt = MessageCreateEvent(client: discordClient, message: msg, name: $EventType.evtMessageCreate) let messageCreateEvnt = MessageCreateEvent(client: discordClient, message: msg, name: $EventType.evtMessageCreate)
dispatchEvent(messageCreateEvnt) 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) = proc guildCreateEvent(discordClient: DiscordClient, json: JsonNode) =
let g = newGuild(json) let g = newGuild(json)
let guildCreateEvnt = GuildCreateEvent(client: discordClient, guild: g, name: $EventType.evtGuildCreate) let guildCreateEvnt = GuildCreateEvent(client: discordClient, guild: g, name: $EventType.evtGuildCreate)
discordClient.cache.guilds.insert(g) # Add guild and its channels and members in cache.
discordClient.cache.channels = concat(discordClient.cache.channels, g.channels) discordClient.cache.guilds.add(g.id, g)
discordClient.cache.members = concat(discordClient.cache.members, g.members) 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) dispatchEvent(guildCreateEvnt)
let internalEventTable: Table[string, proc(discordClient: DiscordClient, json: JsonNode) {.nimcall.}] = { let internalEventTable: Table[string, proc(discordClient: DiscordClient, json: JsonNode) {.nimcall.}] = {
"READY": readyEvent, "READY": readyEvent,
"MESSAGE_CREATE": messageCreateEvent, "MESSAGE_CREATE": messageCreateEvent,
"GUILD_CREATE": guildCreateEvent, "GUILD_CREATE": guildCreateEvent,
"CHANNEL_CREATE": channelCreateEvent "CHANNEL_CREATE": channelCreateEvent,
"CHANNEL_UPDATE": channelUpdateEvent,
"CHANNEL_DELETE": channelDeleteEvent
}.toTable }.toTable
proc handleDiscordEvent*(discordClient: DiscordClient, json: JsonNode, eventName: string) {.async.} = proc handleDiscordEvent*(discordClient: DiscordClient, json: JsonNode, eventName: string) {.async.} =