diff options
| -rw-r--r-- | src/client/bridge/gateway/event.rs | 29 | ||||
| -rw-r--r-- | src/client/bridge/gateway/mod.rs | 2 | ||||
| -rw-r--r-- | src/client/bridge/gateway/shard_runner.rs | 15 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 100 | ||||
| -rw-r--r-- | src/client/event_handler.rs | 6 | ||||
| -rw-r--r-- | src/client/mod.rs | 1 |
6 files changed, 106 insertions, 47 deletions
diff --git a/src/client/bridge/gateway/event.rs b/src/client/bridge/gateway/event.rs new file mode 100644 index 0000000..a967ab5 --- /dev/null +++ b/src/client/bridge/gateway/event.rs @@ -0,0 +1,29 @@ +//! A collection of events created by the client, not a part of the Discord API +//! itself. + +use super::ShardId; +use ::gateway::ConnectionStage; + +#[derive(Clone, Debug)] +pub(crate) enum ClientEvent { + ShardStageUpdate(ShardStageUpdateEvent), +} + +/// An event denoting that a shard's connection stage was changed. +/// +/// # Examples +/// +/// This might happen when a shard changes from [`ConnectionStage::Identifying`] +/// to [`ConnectionStage::Connected`]. +/// +/// [`ConnectionStage::Connected`]: ../../../../gateway/enum.ConnectionStage.html#variant.Connected +/// [`ConnectionStage::Identifying`]: ../../../../gateway/enum.ConnectionStage.html#variant.Identifying +#[derive(Clone, Debug)] +pub struct ShardStageUpdateEvent { + /// The new connection stage. + pub new: ConnectionStage, + /// The old connection stage. + pub old: ConnectionStage, + /// The ID of the shard that had its connection stage change. + pub shard_id: ShardId, +} diff --git a/src/client/bridge/gateway/mod.rs b/src/client/bridge/gateway/mod.rs index 5c9ec69..23d2864 100644 --- a/src/client/bridge/gateway/mod.rs +++ b/src/client/bridge/gateway/mod.rs @@ -47,6 +47,8 @@ //! [`ShardQueuer`]: struct.ShardQueuer.html //! [`ShardRunner`]: struct.ShardRunner.html +pub mod event; + mod shard_manager; mod shard_manager_monitor; mod shard_messenger; diff --git a/src/client/bridge/gateway/shard_runner.rs b/src/client/bridge/gateway/shard_runner.rs index 7c6cf83..8781149 100644 --- a/src/client/bridge/gateway/shard_runner.rs +++ b/src/client/bridge/gateway/shard_runner.rs @@ -6,7 +6,9 @@ use parking_lot::Mutex; use serde::Deserialize; use std::sync::mpsc::{self, Receiver, Sender, TryRecvError}; use std::sync::Arc; -use super::super::super::{EventHandler, dispatch}; +use super::super::super::dispatch::{DispatchEvent, dispatch}; +use super::super::super::EventHandler; +use super::event::{ClientEvent, ShardStageUpdateEvent}; use super::{ShardClientMessage, ShardId, ShardManagerMessage, ShardRunnerMessage}; use threadpool::ThreadPool; use typemap::ShareMap; @@ -149,6 +151,13 @@ impl<H: EventHandler + Send + Sync + 'static> ShardRunner<H> { if post != pre { self.update_manager(); + + let e = ClientEvent::ShardStageUpdate(ShardStageUpdateEvent { + new: post, + old: pre, + shard_id: ShardId(self.shard.shard_info()[0]), + }); + self.dispatch(DispatchEvent::Client(e)); } match action { @@ -162,7 +171,7 @@ impl<H: EventHandler + Send + Sync + 'static> ShardRunner<H> { } if let Some(event) = event { - self.dispatch(event); + self.dispatch(DispatchEvent::Model(event)); } if !successful && !self.shard.stage().is_connecting() { @@ -222,7 +231,7 @@ impl<H: EventHandler + Send + Sync + 'static> ShardRunner<H> { } #[inline] - fn dispatch(&self, event: Event) { + fn dispatch(&self, event: DispatchEvent) { dispatch( event, #[cfg(feature = "framework")] diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 01e7c4b..908751b 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -2,6 +2,7 @@ use model::event::Event; use model::channel::{Channel, Message}; use std::sync::Arc; use parking_lot::Mutex; +use super::bridge::gateway::event::ClientEvent; use super::bridge::gateway::ShardClientMessage; use super::event_handler::EventHandler; use super::Context; @@ -45,10 +46,15 @@ fn context( Context::new(Arc::clone(data), runner_tx.clone(), shard_id) } +pub(crate) enum DispatchEvent { + Client(ClientEvent), + Model(Event), +} + #[cfg(feature = "framework")] #[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] -pub fn dispatch<H: EventHandler + Send + Sync + 'static>( - event: Event, +pub(crate) fn dispatch<H: EventHandler + Send + Sync + 'static>( + event: DispatchEvent, framework: &Arc<Mutex<Option<Box<Framework + Send>>>>, data: &Arc<Mutex<ShareMap>>, event_handler: &Arc<H>, @@ -57,7 +63,7 @@ pub fn dispatch<H: EventHandler + Send + Sync + 'static>( shard_id: u64, ) { match event { - Event::MessageCreate(event) => { + DispatchEvent::Model(Event::MessageCreate(event)) => { let context = context(data, runner_tx, shard_id); dispatch_message( context.clone(), @@ -83,7 +89,7 @@ pub fn dispatch<H: EventHandler + Send + Sync + 'static>( #[cfg(not(feature = "framework"))] pub fn dispatch<H: EventHandler + Send + Sync + 'static>( - event: Event, + event: DispatchEvent, data: &Arc<Mutex<ShareMap>>, event_handler: &Arc<H>, runner_tx: &Sender<ShardClientMessage>, @@ -127,7 +133,7 @@ fn dispatch_message<H>( #[allow(cyclomatic_complexity, unused_assignments, unused_mut)] fn handle_event<H: EventHandler + Send + Sync + 'static>( - event: Event, + event: DispatchEvent, data: &Arc<Mutex<ShareMap>>, event_handler: &Arc<H>, runner_tx: &Sender<ShardClientMessage>, @@ -149,7 +155,15 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }; match event { - Event::ChannelCreate(mut event) => { + DispatchEvent::Client(ClientEvent::ShardStageUpdate(event)) => { + let context = context(data, runner_tx, shard_id); + let event_handler = Arc::clone(event_handler); + + threadpool.execute(move || { + event_handler.shard_stage_update(context, event); + }); + } + DispatchEvent::Model(Event::ChannelCreate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -182,7 +196,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }, } }, - Event::ChannelDelete(mut event) => { + DispatchEvent::Model(Event::ChannelDelete(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -205,7 +219,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }, } }, - Event::ChannelPinsUpdate(mut event) => { + DispatchEvent::Model(Event::ChannelPinsUpdate(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -213,7 +227,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.channel_pins_update(context, event); }); }, - Event::ChannelRecipientAdd(mut event) => { + DispatchEvent::Model(Event::ChannelRecipientAdd(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -228,7 +242,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( ); }); }, - Event::ChannelRecipientRemove(mut event) => { + DispatchEvent::Model(Event::ChannelRecipientRemove(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -242,7 +256,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( ); }); }, - Event::ChannelUpdate(mut event) => { + DispatchEvent::Model(Event::ChannelUpdate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -258,7 +272,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildBanAdd(mut event) => { + DispatchEvent::Model(Event::GuildBanAdd(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -266,7 +280,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_ban_addition(context, event.guild_id, event.user); }); }, - Event::GuildBanRemove(mut event) => { + DispatchEvent::Model(Event::GuildBanRemove(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -274,7 +288,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_ban_removal(context, event.guild_id, event.user); }); }, - Event::GuildCreate(mut event) => { + DispatchEvent::Model(Event::GuildCreate(mut event)) => { #[cfg(feature = "cache")] let _is_new = { let cache = CACHE.read(); @@ -317,7 +331,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildDelete(mut event) => { + DispatchEvent::Model(Event::GuildDelete(mut event)) => { let _full = update!(event); let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -330,7 +344,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildEmojisUpdate(mut event) => { + DispatchEvent::Model(Event::GuildEmojisUpdate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -340,7 +354,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_emojis_update(context, event.guild_id, event.emojis); }); }, - Event::GuildIntegrationsUpdate(mut event) => { + DispatchEvent::Model(Event::GuildIntegrationsUpdate(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -348,7 +362,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_integrations_update(context, event.guild_id); }); }, - Event::GuildMemberAdd(mut event) => { + DispatchEvent::Model(Event::GuildMemberAdd(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -358,7 +372,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_member_addition(context, event.guild_id, event.member); }); }, - Event::GuildMemberRemove(mut event) => { + DispatchEvent::Model(Event::GuildMemberRemove(mut event)) => { let _member = update!(event); let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -371,7 +385,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildMemberUpdate(mut event) => { + DispatchEvent::Model(Event::GuildMemberUpdate(mut event)) => { let _before = update!(event); let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -392,7 +406,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildMembersChunk(mut event) => { + DispatchEvent::Model(Event::GuildMembersChunk(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -402,7 +416,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_members_chunk(context, event.guild_id, event.members); }); }, - Event::GuildRoleCreate(mut event) => { + DispatchEvent::Model(Event::GuildRoleCreate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -412,7 +426,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_role_create(context, event.guild_id, event.role); }); }, - Event::GuildRoleDelete(mut event) => { + DispatchEvent::Model(Event::GuildRoleDelete(mut event)) => { let _role = update!(event); let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -425,7 +439,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildRoleUpdate(mut event) => { + DispatchEvent::Model(Event::GuildRoleUpdate(mut event)) => { let _before = update!(event); let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -438,7 +452,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::GuildUnavailable(mut event) => { + DispatchEvent::Model(Event::GuildUnavailable(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -448,7 +462,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.guild_unavailable(context, event.guild_id); }); }, - Event::GuildUpdate(mut event) => { + DispatchEvent::Model(Event::GuildUpdate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -468,8 +482,8 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }); }, // Already handled by the framework check macro - Event::MessageCreate(_) => {}, - Event::MessageDeleteBulk(mut event) => { + DispatchEvent::Model(Event::MessageCreate(_)) => {}, + DispatchEvent::Model(Event::MessageDeleteBulk(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -477,7 +491,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.message_delete_bulk(context, event.channel_id, event.ids); }); }, - Event::MessageDelete(mut event) => { + DispatchEvent::Model(Event::MessageDelete(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -485,7 +499,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.message_delete(context, event.channel_id, event.message_id); }); }, - Event::MessageUpdate(mut event) => { + DispatchEvent::Model(Event::MessageUpdate(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -493,7 +507,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.message_update(context, event); }); }, - Event::PresencesReplace(mut event) => { + DispatchEvent::Model(Event::PresencesReplace(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -503,7 +517,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.presence_replace(context, event.presences); }); }, - Event::PresenceUpdate(mut event) => { + DispatchEvent::Model(Event::PresenceUpdate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -513,7 +527,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.presence_update(context, event); }); }, - Event::ReactionAdd(mut event) => { + DispatchEvent::Model(Event::ReactionAdd(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -521,7 +535,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.reaction_add(context, event.reaction); }); }, - Event::ReactionRemove(mut event) => { + DispatchEvent::Model(Event::ReactionRemove(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -529,7 +543,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.reaction_remove(context, event.reaction); }); }, - Event::ReactionRemoveAll(mut event) => { + DispatchEvent::Model(Event::ReactionRemoveAll(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -537,7 +551,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.reaction_remove_all(context, event.channel_id, event.message_id); }); }, - Event::Ready(mut event) => { + DispatchEvent::Model(Event::Ready(mut event)) => { update!(event); let event_handler = Arc::clone(event_handler); @@ -563,12 +577,12 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }); }} }, - Event::Resumed(mut event) => { + DispatchEvent::Model(Event::Resumed(mut event)) => { let context = context(data, runner_tx, shard_id); event_handler.resume(context, event); }, - Event::TypingStart(mut event) => { + DispatchEvent::Model(Event::TypingStart(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -576,7 +590,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.typing_start(context, event); }); }, - Event::Unknown(mut event) => { + DispatchEvent::Model(Event::Unknown(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -584,7 +598,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.unknown(context, event.kind, event.value); }); }, - Event::UserUpdate(mut event) => { + DispatchEvent::Model(Event::UserUpdate(mut event)) => { let _before = update!(event); let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -597,7 +611,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( }} }); }, - Event::VoiceServerUpdate(mut event) => { + DispatchEvent::Model(Event::VoiceServerUpdate(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); @@ -605,7 +619,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.voice_server_update(context, event); }); }, - Event::VoiceStateUpdate(mut event) => { + DispatchEvent::Model(Event::VoiceStateUpdate(mut event)) => { update!(event); let context = context(data, runner_tx, shard_id); @@ -615,7 +629,7 @@ fn handle_event<H: EventHandler + Send + Sync + 'static>( event_handler.voice_state_update(context, event.guild_id, event.voice_state); }); }, - Event::WebhookUpdate(mut event) => { + DispatchEvent::Model(Event::WebhookUpdate(mut event)) => { let context = context(data, runner_tx, shard_id); let event_handler = Arc::clone(event_handler); diff --git a/src/client/event_handler.rs b/src/client/event_handler.rs index d5bd035..552c3a9 100644 --- a/src/client/event_handler.rs +++ b/src/client/event_handler.rs @@ -4,6 +4,7 @@ use serde_json::Value; use std::collections::HashMap; use std::sync::Arc; use super::context::Context; +use ::client::bridge::gateway::event::*; pub trait EventHandler { #[cfg(feature = "cache")] @@ -67,6 +68,11 @@ pub trait EventHandler { fn presence_update(&self, _: Context, _: PresenceUpdateEvent) {} fn ready(&self, _: Context, _: Ready) {} fn resume(&self, _: Context, _: ResumedEvent) {} + + /// Called when a shard's connection stage is updated, providing the context + /// of the shard and the event information about the update. + fn shard_stage_update(&self, _: Context, _: ShardStageUpdateEvent) {} + fn typing_start(&self, _: Context, _: TypingStartEvent) {} fn unknown(&self, _: Context, _: String, _: Value) {} #[cfg(feature = "cache")] diff --git a/src/client/mod.rs b/src/client/mod.rs index 58d411e..bf0a307 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -41,7 +41,6 @@ use http; use internal::prelude::*; use parking_lot::Mutex; use self::bridge::gateway::{ShardManager, ShardManagerMonitor}; -use self::dispatch::dispatch; use std::sync::Arc; use threadpool::ThreadPool; use typemap::ShareMap; |