diff --git a/src/cache.nim b/src/cache.nim index babee9f..0437a14 100644 --- a/src/cache.nim +++ b/src/cache.nim @@ -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())) diff --git a/src/eventdispatcher.nim b/src/eventdispatcher.nim index fb57b20..96bfb8a 100644 --- a/src/eventdispatcher.nim +++ b/src/eventdispatcher.nim @@ -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.} =