aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/bridge/gateway/event.rs29
-rw-r--r--src/client/bridge/gateway/mod.rs2
-rw-r--r--src/client/bridge/gateway/shard_runner.rs15
-rw-r--r--src/client/dispatch.rs100
-rw-r--r--src/client/event_handler.rs6
-rw-r--r--src/client/mod.rs1
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;