Skip to content

Commit

Permalink
Enhance event handling system including waitForEvents.
Browse files Browse the repository at this point in the history
* Add DispatchEvents enum

* Convert `handleEventDispatch` to use `DispatchEvent` instead of strings

This is to prevent misspellings and will also be used in #110 for the event dispatching system (So that it is typesafe)

* Very basic MVP

Needs further testing and more procs, but seems like a decent system

The use of WaitHandler is to allow for complex logic such as checking if the values match what we expect

This should handle things such as timeouts though

* Remove deleting empty keys from the wait table

This was when the keys were object IDs, but since they are just event names it should grow too large

* Remove the handler if the future has already finished

This lets it support withTimeout

* Add `waitFor` and `waitForObject` which allow users to easily write their own wait handlers

Implementations are similar, but I separated them so that I could set actual documentation. They could've been nested but then it the futures would've piled up and really made some errors confusing

I also replaced the implementation of the current two helpers to use `waitFor`/`waitForObject` since it makes implementing them easier

* Make `waitFor` just be syntax sugar for `discard await client.waitForObject`

I don't really know if it is even worthwhile having it, but imo I like it

* Use `EventDispatch` enum instead of strings for better safety (prevents misspellings)

`checkIfAwaiting` still uses pointers so it acts the same as it did before. Also means adding in the inner table will be simple as (Although it wouldn't be difficult either way

* Remove echo that was left in

Move waiters into helpers.nim

* Initial version that doesn't require inheritance

We instead cast around the proc to the required type

Zero clue as to the safety of the solution

Few places cast pointers but immediately dereference, this was to fix a cgen issue which is whats concerning me

Solution seems to properly error if the user passes the wrong proc

* Instead pass a tuple containing the properties for the handler

Instead of casting procs, we instead just allow the handlers to take a pointer to anything and let them handle the types

We can then use this to pass a tuple containing the needed information

Looking at arc expansion, the tuple is a cursor so we should be fine on memory front (Though I annotate as cursor incase cursor inference changes

* If the data tuple is only a single field then only return the first field

This makes handlers for things like message creation more concise

The handler types should probably have better variable names though

* Add helper for awaiting on a MessageComponent to be used

Fix up the cache table not allowing every handler (The replacement was too broad)

* Update example to use helpers

* Add `orTimeout` helper

This allows natural language for timing (e.g. 2.seconds) and returns `Option[T]` so the user knows if something is wrong

* Handlers now work for every event

Speed up by creating a checkAndCall macro which both called the event and checked all the handlers

Also fixed guildScheduledEventUpdate which was calling the wrong event before

* Use asyncCheck instead of await

Remove testing code

* Add helper to wait for a user to join a voice channel

Remove debug statements from voice example

* Add waitForReaction to listen for message reactions

Added an assertion that it has the needed intent. This should hopefully reduce user errors of 'Why isnt waitForReaction working for me?'

Plan to move this into the `waitForObject` so that every helper automatically checks that the client has the needed intents enabled

Sadly this will just be a runtime error, but least will make testing quicker instead of needing to track down what intent is required

* Add checks that the client has needed intents

This isn't enabled for everything (If we got a message to wait for its deletion, then we probably already recieve MESSAGE_CREATE events)

* Fix issues with stable

Add work around for enums losing enumness (Cast the int to the enum)

Use unsafeAddr when on older versions

Make sure to initalise the sequence of parameters so it is reset every loop

Don't use implicit returns in helpers

Don't have ambigious enums in the dispatch case statement

Import `json` in typedefs since it is needed there

* Tweak PR with some changes, getGuildMember in gateway with some fixes.

* fix last commit

* Support presences on getGuildMember and add waitForReady on voice.

* Add basic version of waitForRaw

Trying to figure out why to get around issue with wrong binding of procs

* update DispatchEvent to avoid conflicts with proc, update examples/advanced.nim

* Use a shim to get around issue with multiple procs having the same name

Slightly hacky, but best solution until nim-lang/Nim#22276 is fixed

* Remove `waitForObject`

now there is only `waitFor` which you can discard if you don't want the return value

* Merge changes

* Make Unknown be dispatched

Fix up some docs

Change scrambled name

* Remove TODO

It uses pointer now and doesn't have an inner table anymore

* Fix name of future

It was using old waitFor

* Remove de prefix

I'm assuming this was accidently left in from a bad merge

* Update some event names for clarity. Added some info in waitFor.

* Added some constants to avoid conflict with event name and object.

---------

Co-authored-by: krisppurg <[email protected]>
  • Loading branch information
ire4ever1190 and krisppurg authored Aug 17, 2023
1 parent e0fb292 commit 2bc1545
Show file tree
Hide file tree
Showing 33 changed files with 14,094 additions and 12,768 deletions.
67 changes: 66 additions & 1 deletion dimscord/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,71 @@ type
GuildOnboardingPromptType* = enum
ptMultipleChoice = 0,
ptDropdown = 1
DispatchEvent* = enum
Unknown
VoiceStateUpdate = "VOICE_STATE_UPDATE"
ChannelPinsUpdate = "CHANNEL_PINS_UPDATE"
GuildEmojisUpdate = "GUILD_EMOJIS_UPDATE"
GuildStickersUpdate = "GUILD_STICKERS_UPDATE"
PresenceUpdate = "PRESENCE_UPDATE"
MessageCreate = "MESSAGE_CREATE"
MessageReactionAdd = "MESSAGE_REACTION_ADD"
MessageReactionRemove = "MESSAGE_REACTION_REMOVE"
MessageReactionRemoveEmoji = "MESSAGE_REACTION_REMOVE_EMOJI"
MessageReactionRemoveAll = "MESSAGE_REACTION_REMOVE_ALL"
MessageDelete = "MESSAGE_DELETE"
MessageUpdate = "MESSAGE_UPDATE"
MessageDeleteBulk = "MESSAGE_DELETE_BULK"
ChannelCreate = "CHANNEL_CREATE"
ChannelUpdate = "CHANNEL_UPDATE"
ChannelDelete = "CHANNEL_DELETE"
GuildMembersChunk = "GUILD_MEMBERS_CHUNK"
GuildMemberAdd = "GUILD_MEMBER_ADD"
GuildMemberUpdate = "GUILD_MEMBER_UPDATE"
GuildMemberRemove = "GUILD_MEMBER_REMOVE"
GuildAuditLogEntryCreate = "GUILD_AUDIT_LOG_ENTRY_CREATE"
GuildBanAdd = "GUILD_BAN_ADD"
GuildBanRemove = "GUILD_BAN_REMOVE"
GuildUpdate = "GUILD_UPDATE"
GuildDelete = "GUILD_DELETE"
GuildCreate = "GUILD_CREATE"
GuildRoleCreate = "GUILD_ROLE_CREATE"
GuildRoleUpdate = "GUILD_ROLE_UPDATE"
GuildRoleDelete = "GUILD_ROLE_DELETE"
WebhooksUpdate = "WEBHOOKS_UPDATE"
TypingStart = "TYPING_START"
InviteCreate = "INVITE_CREATE"
InviteDelete = "INVITE_DELETE"
GuildIntegrationsUpdate = "GUILD_INTEGRATIONS_UPDATE"
VoiceServerUpdate = "VOICE_SERVER_UPDATE"
UserUpdate = "USER_UPDATE"
InteractionCreate = "INTERACTION_CREATE"
ThreadCreate = "THREAD_CREATE"
ThreadUpdate = "THREAD_UPDATE"
ThreadDelete = "THREAD_DELETE"
ThreadListSync = "THREAD_LIST_SYNC"
ThreadMembersUpdate = "THREAD_MEMBERS_UPDATE"
ThreadMemberUpdate = "THREAD_MEMBER_UPDATE"
StageInstanceCreate = "STAGE_INSTANCE_CREATE"
StageInstanceUpdate = "STAGE_INSTANCE_UPDATE"
StageInstanceDelete = "STAGE_INSTANCE_DELETE"
GuildScheduledEventUserAdd = "GUILD_SCHEDULED_EVENT_USER_ADD"
GuildScheduledEventUserRemove = "GUILD_SCHEDULED_EVENT_USER_REMOVE"
GuildScheduledEventCreate = "GUILD_SCHEDULED_EVENT_CREATE"
GuildScheduledEventUpdate = "GUILD_SCHEDULED_EVENT_UPDATE"
GuildScheduledEventDelete = "GUILD_SCHEDULED_EVENT_DELETE"
AutoModerationRuleCreate = "AUTO_MODERATION_RULE_CREATE"
AutoModerationRuleUpdate = "AUTO_MODERATION_RULE_UPDATE"
AutoModerationRuleDelete = "AUTO_MODERATION_RULE_DELETE"
AutoModerationActionExecution = "AUTO_MODERATION_ACTION_EXECUTION"

const
deGuildMembersChunk* = DispatchEvent.GuildMembersChunk
deTypingStart* = DispatchEvent.TypingStart
deInviteCreate* = DispatchEvent.InviteCreate
deThreadListSync* = DispatchEvent.ThreadListSync
deThreadMembersUpdate* = DispatchEvent.ThreadMembersUpdate


const
permAllText* = {permCreateInstantInvite,
Expand Down Expand Up @@ -605,7 +670,7 @@ proc cdnBanner*(bid, banner: string; fmt = "png"): string =
result = cdnBanners&bid&"/"&banner&"."&fmt

proc cdnGuildSplash*(gid, splash: string; fmt = "png"): string =
assert fmt in @["png", "jpg", "webp"]
assert fmt in @["png", "jpg", "webp"]
result = cdnSplashes&gid&"/"&splash&"."&fmt

proc cdnGuildDiscoverySplash*(gid, splash: string; fmt = "png"): string =
Expand Down
Loading

0 comments on commit 2bc1545

Please sign in to comment.