aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authoracdenisSK <[email protected]>2017-06-28 19:38:51 +0200
committeracdenisSK <[email protected]>2017-06-28 19:38:51 +0200
commitea432af97a87b8a3d673a1f40fe06cde4d84e146 (patch)
tree1afbc7d396f83e1eea0550b848764a14832c277a /src/client
parentAdd reaction actions (#115) (diff)
downloadserenity-ea432af97a87b8a3d673a1f40fe06cde4d84e146.tar.xz
serenity-ea432af97a87b8a3d673a1f40fe06cde4d84e146.zip
Merge branch "trait-based-event-handling"
Diffstat (limited to 'src/client')
-rw-r--r--src/client/dispatch.rs520
-rw-r--r--src/client/event_handler.rs77
-rw-r--r--src/client/mod.rs662
3 files changed, 322 insertions, 937 deletions
diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs
index 4021838..fc3daaf 100644
--- a/src/client/dispatch.rs
+++ b/src/client/dispatch.rs
@@ -1,7 +1,7 @@
-use std::sync::{Arc, Mutex, RwLock};
+use std::sync::{Arc, Mutex};
use std::thread;
use std::time;
-use super::event_store::EventStore;
+use super::event_handler::EventHandler;
use super::Context;
use typemap::ShareMap;
use ::gateway::Shard;
@@ -15,16 +15,6 @@ use ::ext::framework::{Framework, ReactionAction};
#[cfg(feature="cache")]
use super::CACHE;
-macro_rules! handler {
- ($field:ident, $event_store:ident) => {
- $event_store.read()
- .unwrap()
- .$field
- .as_ref()
- .cloned()
- }
-}
-
macro_rules! update {
($method:ident, @$event:expr) => {
{
@@ -70,11 +60,11 @@ fn context(conn: &Arc<Mutex<Shard>>,
}
#[cfg(feature="framework")]
-pub fn dispatch(event: Event,
+pub fn dispatch<H: EventHandler + Send + Sync + 'static>(event: Event,
conn: &Arc<Mutex<Shard>>,
framework: &Arc<Mutex<Framework>>,
data: &Arc<Mutex<ShareMap>>,
- event_store: &Arc<RwLock<EventStore>>) {
+ event_handler: &Arc<H>) {
match event {
Event::MessageCreate(event) => {
let context = context(conn, data);
@@ -83,11 +73,11 @@ pub fn dispatch(event: Event,
if framework.initialized {
dispatch_message(context.clone(),
event.message.clone(),
- event_store);
+ event_handler);
framework.dispatch(context, event.message);
} else {
- dispatch_message(context, event.message, event_store);
+ dispatch_message(context, event.message, event_handler);
}
},
Event::ReactionAdd(event) => {
@@ -97,11 +87,11 @@ pub fn dispatch(event: Event,
if framework.initialized {
dispatch_reaction_add(context.clone(),
event.reaction.clone(),
- event_store);
+ event_handler);
let res = framework.reaction_actions
.iter()
- .find(|&(ra, ..)| {
+ .find(|&(ra, _)| {
if let ReactionAction::Add(ref kind) = *ra {
*kind == event.reaction.emoji
} else {
@@ -113,7 +103,7 @@ pub fn dispatch(event: Event,
f(context, event.reaction.message_id, event.reaction.channel_id);
}
} else {
- dispatch_reaction_add(context, event.reaction, event_store);
+ dispatch_reaction_add(context, event.reaction, event_handler);
}
},
Event::ReactionRemove(event) => {
@@ -123,7 +113,7 @@ pub fn dispatch(event: Event,
if framework.initialized {
dispatch_reaction_remove(context.clone(),
event.reaction.clone(),
- event_store);
+ event_handler);
let res = framework.reaction_actions
.iter()
@@ -139,24 +129,24 @@ pub fn dispatch(event: Event,
f(context, event.reaction.message_id, event.reaction.channel_id);
}
} else {
- dispatch_reaction_remove(context, event.reaction, event_store);
+ dispatch_reaction_remove(context, event.reaction, event_handler);
}
},
- other => handle_event(other, conn, data, event_store),
+ other => handle_event(other, conn, data, event_handler),
}
}
#[cfg(not(feature="framework"))]
-pub fn dispatch(event: Event,
+pub fn dispatch<H: EventHandler + Send + Sync + 'static>(event: Event,
conn: &Arc<Mutex<Shard>>,
data: &Arc<Mutex<ShareMap>>,
- event_store: &Arc<RwLock<EventStore>>) {
+ event_handler: &Arc<H>) {
match event {
Event::MessageCreate(event) => {
let context = context(conn, data);
dispatch_message(context,
event.message,
- event_store);
+ event_handler);
},
Event::ReactionAdd(event) => {
let context = context(conn, data);
@@ -166,53 +156,52 @@ pub fn dispatch(event: Event,
let context = context(conn, data);
dispatch_reaction_remove(context, event.reaction);
},
- other => handle_event(other, conn, data, event_store),
+ other => handle_event(other, conn, data, event_handler),
}
}
#[allow(unused_mut)]
-fn dispatch_message(context: Context,
+fn dispatch_message<H: EventHandler + Send + Sync + 'static>(context: Context,
mut message: Message,
- event_store: &Arc<RwLock<EventStore>>) {
- if let Some(handler) = handler!(on_message, event_store) {
- thread::spawn(move || {
- #[cfg(feature="model")]
- {
- message.transform_content();
- }
+ event_handler: &Arc<H>) {
+ let h = event_handler.clone();
+ thread::spawn(move || {
+ #[cfg(feature="model")]
+ {
+ message.transform_content();
+ }
- (handler)(context, message);
- });
- }
+ h.on_message(context, message);
+ });
}
-fn dispatch_reaction_add(context: Context,
+fn dispatch_reaction_add<H: EventHandler + Send + Sync + 'static>(context: Context,
reaction: Reaction,
- event_store: &Arc<RwLock<EventStore>>) {
- if let Some(handler) = handler!(on_reaction_add, event_store) {
- thread::spawn(move || {
- (handler)(context, reaction);
- });
- }
+ event_handler: &Arc<H>) {
+ let h = event_handler.clone();
+ thread::spawn(move || {
+ h.on_reaction_add(context, reaction);
+ });
}
-fn dispatch_reaction_remove(context: Context,
+fn dispatch_reaction_remove<H: EventHandler + Send + Sync + 'static>(context: Context,
reaction: Reaction,
- event_store: &Arc<RwLock<EventStore>>) {
- if let Some(handler) = handler!(on_reaction_remove, event_store) {
- thread::spawn(move || {
- (handler)(context, reaction);
- });
- }
+ event_handler: &Arc<H>) {
+ let h = event_handler.clone();
+ thread::spawn(move || {
+ h.on_reaction_remove(context, reaction);
+ });
}
#[allow(cyclomatic_complexity, unused_assignments, unused_mut)]
-fn handle_event(event: Event,
+fn handle_event<H: EventHandler + Send + Sync + 'static>(event: Event,
conn: &Arc<Mutex<Shard>>,
data: &Arc<Mutex<ShareMap>>,
- event_store: &Arc<RwLock<EventStore>>) {
- let mut last_guild_create_time = now!();
+ event_handler: &Arc<H>) {
+ #[cfg(feature="cache")]
+ let mut last_guild_create_time = now!();
+ #[cfg(feature="cache")]
let wait_for_guilds = move || -> ::Result<()> {
let unavailable_guilds = CACHE.read().unwrap().unavailable_guilds.len();
@@ -225,406 +214,337 @@ fn handle_event(event: Event,
match event {
Event::ChannelCreate(event) => {
- if let Some(handler) = handler!(on_channel_create, event_store) {
- update!(update_with_channel_create, event);
+ update!(update_with_channel_create, event);
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.channel));
- } else {
- update!(update_with_channel_create, event);
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_channel_create(context, event.channel));
},
Event::ChannelDelete(event) => {
- if let Some(handler) = handler!(on_channel_delete, event_store) {
- update!(update_with_channel_delete, event);
- let context = context(conn, data);
+ update!(update_with_channel_delete, event);
- thread::spawn(move || (handler)(context, event.channel));
- } else {
- update!(update_with_channel_delete, event);
- }
+ let context = context(conn, data);
+
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_channel_delete(context, event.channel));
},
Event::ChannelPinsUpdate(event) => {
- if let Some(handler) = handler!(on_channel_pins_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_channel_pins_update(context, event));
},
Event::ChannelRecipientAdd(mut event) => {
update!(update_with_channel_recipient_add, @event);
- if let Some(handler) = handler!(on_channel_recipient_addition, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.channel_id, event.user));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_channel_recipient_addition(context, event.channel_id, event.user));
},
Event::ChannelRecipientRemove(event) => {
update!(update_with_channel_recipient_remove, event);
- if let Some(handler) = handler!(on_channel_recipient_removal, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.channel_id, event.user));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_channel_recipient_removal(context, event.channel_id, event.user));
},
Event::ChannelUpdate(event) => {
- if let Some(handler) = handler!(on_channel_update, event_store) {
- let context = context(conn, data);
+ update!(update_with_channel_update, event);
- feature_cache! {{
- let before = CACHE.read().unwrap().channel(event.channel.id());
- update!(update_with_channel_update, event);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, before, event.channel));
- } else {
- thread::spawn(move || (handler)(context, event.channel));
- }}
+ let h = event_handler.clone();
+ feature_cache! {{
+ let before = CACHE.read().unwrap().channel(event.channel.id());
+ thread::spawn(move || h.on_channel_update(context, before, event.channel));
} else {
- update!(update_with_channel_update, event);
- }
+ thread::spawn(move || h.on_channel_update(context, event.channel));
+ }}
},
Event::GuildBanAdd(event) => {
- if let Some(handler) = handler!(on_guild_ban_addition, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.user));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_ban_addition(context, event.guild_id, event.user));
},
Event::GuildBanRemove(event) => {
- if let Some(handler) = handler!(on_guild_ban_removal, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.user));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_ban_removal(context, event.guild_id, event.user));
},
Event::GuildCreate(event) => {
update!(update_with_guild_create, event);
- last_guild_create_time = now!();
-
#[cfg(feature="cache")]
{
+ last_guild_create_time = now!();
+
let cache = CACHE.read().unwrap();
if cache.unavailable_guilds.len() == 0 {
- if let Some(handler) = handler!(on_cached, event_store) {
- let context = context(conn, data);
+ let h = event_handler.clone();
+
+ let context = context(conn, data);
- let guild_amount = cache.guilds.iter()
+ let guild_amount = cache.guilds.iter()
.map(|(&id, _)| id)
.collect::<Vec<GuildId>>();
-
- thread::spawn(move || (handler)(context, guild_amount));
- }
+
+ thread::spawn(move || h.on_cached(context, guild_amount));
}
}
- if let Some(handler) = handler!(on_guild_create, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_create(context, event.guild));
},
Event::GuildDelete(event) => {
- if let Some(handler) = handler!(on_guild_delete, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let full = update!(update_with_guild_delete, event);
+ let _full = update!(update_with_guild_delete, event);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild, full));
- } else {
- thread::spawn(move || (handler)(context, event.guild));
- }}
+ let h = event_handler.clone();
+ feature_cache! {{
+ thread::spawn(move || h.on_guild_delete(context, event.guild, _full));
} else {
- #[cfg(feature="cache")]
- {
- let _ = update!(update_with_guild_delete, event);
- }
- }
+ thread::spawn(move || h.on_guild_delete(context, event.guild));
+ }}
},
Event::GuildEmojisUpdate(event) => {
update!(update_with_guild_emojis_update, event);
- if let Some(handler) = handler!(on_guild_emojis_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.emojis));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_emojis_update(context, event.guild_id, event.emojis));
},
Event::GuildIntegrationsUpdate(event) => {
- if let Some(handler) = handler!(on_guild_integrations_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_integrations_update(context, event.guild_id));
},
Event::GuildMemberAdd(mut event) => {
update!(update_with_guild_member_add, @event);
- if let Some(handler) = handler!(on_guild_member_addition, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.member));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_member_addition(context, event.guild_id, event.member));
},
Event::GuildMemberRemove(event) => {
- if let Some(handler) = handler!(on_guild_member_removal, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let member = update!(update_with_guild_member_remove, event);
+ let _member = update!(update_with_guild_member_remove, event);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.user, member));
- } else {
- thread::spawn(move || (handler)(context, event.guild_id, event.user));
- }}
+ let h = event_handler.clone();
+ feature_cache! {{
+ thread::spawn(move || h.on_guild_member_removal(context, event.guild_id, event.user, _member));
} else {
- #[cfg(feature="cache")]
- {
- let _ = update!(update_with_guild_member_remove, event);
- }
- }
+ thread::spawn(move || h.on_guild_member_removal(context, event.guild_id, event.user));
+ }}
},
Event::GuildMemberUpdate(event) => {
- if let Some(handler) = handler!(on_guild_member_update, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let before = update!(update_with_guild_member_update, event);
-
- // This is safe to unwrap, as the update would have created
- // the member if it did not exist. So, there is be _no_ way
- // that this could fail under any circumstance.
- let after = CACHE.read()
- .unwrap()
- .member(event.guild_id, event.user.id)
- .unwrap()
- .clone();
-
- thread::spawn(move || (handler)(context, before, after));
- } else {
- thread::spawn(move || (handler)(context, event));
- }}
+ let _before = update!(update_with_guild_member_update, event);
+ let context = context(conn, data);
+
+ let h = event_handler.clone();
+ feature_cache! {{
+ // This is safe to unwrap, as the update would have created
+ // the member if it did not exist. So, there is be _no_ way
+ // that this could fail under any circumstance.
+ let after = CACHE.read()
+ .unwrap()
+ .member(event.guild_id, event.user.id)
+ .unwrap()
+ .clone();
+
+ thread::spawn(move || h.on_guild_member_update(context, _before, after));
} else {
- update!(update_with_guild_member_update, event);
- }
+ thread::spawn(move || h.on_guild_member_update(context, event));
+ }}
},
Event::GuildMembersChunk(event) => {
update!(update_with_guild_members_chunk, event);
- if let Some(handler) = handler!(on_guild_members_chunk, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.members));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_members_chunk(context, event.guild_id, event.members));
},
Event::GuildRoleCreate(event) => {
update!(update_with_guild_role_create, event);
- if let Some(handler) = handler!(on_guild_role_create, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.role));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_role_create(context, event.guild_id, event.role));
},
Event::GuildRoleDelete(event) => {
- if let Some(handler) = handler!(on_guild_role_delete, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let role = update!(update_with_guild_role_delete, event);
+ let _role = update!(update_with_guild_role_delete, event);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.role_id, role));
- } else {
- thread::spawn(move || (handler)(context, event.guild_id, event.role_id));
- }}
+ let h = event_handler.clone();
+ feature_cache! {{
+ thread::spawn(move || h.on_guild_role_delete(context, event.guild_id, event.role_id, _role));
} else {
- #[cfg(feature="cache")]
- {
- let _ = update!(update_with_guild_role_delete, event);
- }
- }
+ thread::spawn(move || h.on_guild_role_delete(context, event.guild_id, event.role_id));
+ }}
},
Event::GuildRoleUpdate(event) => {
- if let Some(handler) = handler!(on_guild_role_update, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let before = update!(update_with_guild_role_update, event);
+ let _before = update!(update_with_guild_role_update, event);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, before, event.role));
- } else {
- thread::spawn(move || (handler)(context, event.guild_id, event.role));
- }}
+ let h = event_handler.clone();
+ feature_cache! {{
+ thread::spawn(move || h.on_guild_role_update(context, event.guild_id, _before, event.role));
} else {
- #[cfg(feature="cache")]
- {
- let _ = update!(update_with_guild_role_update, event);
- }
- }
+ thread::spawn(move || h.on_guild_role_update(context, event.guild_id, event.role));
+ }}
},
Event::GuildUnavailable(event) => {
update!(update_with_guild_unavailable, event);
- if let Some(handler) = handler!(on_guild_unavailable, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_guild_unavailable(context, event.guild_id));
},
Event::GuildUpdate(event) => {
- if let Some(handler) = handler!(on_guild_update, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let before = CACHE.read()
- .unwrap()
- .guilds
- .get(&event.guild.id)
- .cloned();
- update!(update_with_guild_update, event);
-
- thread::spawn(move || (handler)(context, before, event.guild));
- } else {
- thread::spawn(move || (handler)(context, event.guild));
- }}
+ update!(update_with_guild_update, event);
+
+ let context = context(conn, data);
+
+ let h = event_handler.clone();
+ feature_cache! {{
+ let before = CACHE.read()
+ .unwrap()
+ .guilds
+ .get(&event.guild.id)
+ .cloned();
+
+ thread::spawn(move || h.on_guild_update(context, before, event.guild));
} else {
- update!(update_with_guild_update, event);
- }
+ thread::spawn(move || h.on_guild_update(context, event.guild));
+ }}
},
// Already handled by the framework check macro
Event::MessageCreate(_) => {},
Event::MessageDeleteBulk(event) => {
- if let Some(handler) = handler!(on_message_delete_bulk, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.channel_id, event.ids));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_message_delete_bulk(context, event.channel_id, event.ids));
},
Event::MessageDelete(event) => {
- if let Some(handler) = handler!(on_message_delete, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.channel_id, event.message_id));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_message_delete(context, event.channel_id, event.message_id));
},
Event::MessageUpdate(event) => {
- if let Some(handler) = handler!(on_message_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_message_update(context, event));
},
Event::PresencesReplace(event) => {
update!(update_with_presences_replace, event);
- if let Some(handler) = handler!(on_presence_replace, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.presences));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_presence_replace(context, event.presences));
},
Event::PresenceUpdate(mut event) => {
update!(update_with_presence_update, @event);
- if let Some(handler) = handler!(on_presence_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_presence_update(context, event));
},
// Already handled by the framework check macro
Event::ReactionAdd(_) => {},
Event::ReactionRemove(_) => {},
-
Event::ReactionRemoveAll(event) => {
- if let Some(handler) = handler!(on_reaction_remove_all, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.channel_id, event.message_id));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_reaction_remove_all(context, event.channel_id, event.message_id));
},
Event::Ready(event) => {
update!(update_with_ready, event);
- last_guild_create_time = now!();
-
- let _ = wait_for_guilds()
- .map(|_| {
- if let Some(handler) = handler!(on_ready, event_store) {
+ feature_cache!{{
+ last_guild_create_time = now!();
+ let _ = wait_for_guilds()
+ .map(|_| {
let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.ready));
- }
- });
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_ready(context, event.ready));
+ });
+ } else {
+ let context = context(conn, data);
+
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_ready(context, event.ready));
+ }}
},
Event::Resumed(event) => {
- if let Some(handler) = handler!(on_resume, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_resume(context, event));
},
Event::TypingStart(event) => {
- if let Some(handler) = handler!(on_typing_start, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_typing_start(context, event));
},
Event::Unknown(event) => {
- if let Some(handler) = handler!(on_unknown, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.kind, event.value));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_unknown(context, event.kind, event.value));
},
Event::UserUpdate(event) => {
- if let Some(handler) = handler!(on_user_update, event_store) {
- let context = context(conn, data);
-
- feature_cache! {{
- let before = update!(update_with_user_update, event);
+ let _before = update!(update_with_user_update, event);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, before, event.current_user));
- } else {
- thread::spawn(move || (handler)(context, event.current_user));
- }}
+ let h = event_handler.clone();
+ feature_cache! {{
+ thread::spawn(move || h.on_user_update(context, _before, event.current_user));
} else {
- #[cfg(feature="cache")]
- {
- let _ = update!(update_with_user_update, event);
- }
- }
+ thread::spawn(move || h.on_user_update(context, event.current_user));
+ }}
},
Event::VoiceServerUpdate(event) => {
- if let Some(handler) = handler!(on_voice_server_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_voice_server_update(context, event));
},
Event::VoiceStateUpdate(event) => {
update!(update_with_voice_state_update, event);
- if let Some(handler) = handler!(on_voice_state_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.voice_state));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_voice_state_update(context, event.guild_id, event.voice_state));
},
Event::WebhookUpdate(event) => {
- if let Some(handler) = handler!(on_webhook_update, event_store) {
- let context = context(conn, data);
+ let context = context(conn, data);
- thread::spawn(move || (handler)(context, event.guild_id, event.channel_id));
- }
+ let h = event_handler.clone();
+ thread::spawn(move || h.on_webhook_update(context, event.guild_id, event.channel_id));
},
}
}
diff --git a/src/client/event_handler.rs b/src/client/event_handler.rs
new file mode 100644
index 0000000..b233b8a
--- /dev/null
+++ b/src/client/event_handler.rs
@@ -0,0 +1,77 @@
+use serde_json::Value;
+use std::collections::HashMap;
+use std::sync::Arc;
+use super::context::Context;
+use ::model::event::*;
+use ::model::*;
+
+#[cfg(feature="cache")]
+use std::sync::RwLock;
+
+#[allow(type_complexity)]
+pub trait EventHandler {
+ #[cfg(feature="cache")]
+ fn on_cached(&self, Context, Vec<GuildId>) {}
+ fn on_channel_create(&self, Context, Channel) {}
+ fn on_channel_delete(&self, Context, Channel) {}
+ fn on_channel_pins_update(&self, Context, ChannelPinsUpdateEvent) {}
+ fn on_channel_recipient_addition(&self, Context, ChannelId, User) {}
+ fn on_channel_recipient_removal(&self, Context, ChannelId, User) {}
+ #[cfg(feature="cache")]
+ fn on_channel_update(&self, Context, Option<Channel>, Channel) {}
+ #[cfg(not(feature="cache"))]
+ fn on_channel_update(&self, Context, Channel) {}
+ fn on_guild_ban_addition(&self, Context, GuildId, User) {}
+ fn on_guild_ban_removal(&self, Context, GuildId, User) {}
+ fn on_guild_create(&self, Context, Guild) {}
+ #[cfg(feature="cache")]
+ fn on_guild_delete(&self, Context, PartialGuild, Option<Arc<RwLock<Guild>>>) {}
+ #[cfg(not(feature="cache"))]
+ fn on_guild_delete(&self, Context, PartialGuild) {}
+ fn on_guild_emojis_update(&self, Context, GuildId, HashMap<EmojiId, Emoji>) {}
+ fn on_guild_integrations_update(&self, Context, GuildId) {}
+ fn on_guild_member_addition(&self, Context, GuildId, Member) {}
+ #[cfg(feature="cache")]
+ fn on_guild_member_removal(&self, Context, GuildId, User, Option<Member>) {}
+ #[cfg(not(feature="cache"))]
+ fn on_guild_member_removal(&self, Context, GuildId, User) {}
+ #[cfg(feature="cache")]
+ fn on_guild_member_update(&self, Context, Option<Member>, Member) {}
+ #[cfg(not(feature="cache"))]
+ fn on_guild_member_update(&self, Context, GuildMemberUpdateEvent) {}
+ fn on_guild_members_chunk(&self, Context, GuildId, HashMap<UserId, Member>) {}
+ fn on_guild_role_create(&self, Context, GuildId, Role) {}
+ #[cfg(feature="cache")]
+ fn on_guild_role_delete(&self, Context, GuildId, RoleId, Option<Role>) {}
+ #[cfg(not(feature="cache"))]
+ fn on_guild_role_delete(&self, Context, GuildId, RoleId) {}
+ #[cfg(feature="cache")]
+ fn on_guild_role_update(&self, Context, GuildId, Option<Role>, Role) {}
+ #[cfg(not(feature="cache"))]
+ fn on_guild_role_update(&self, Context, GuildId, Role) {}
+ fn on_guild_unavailable(&self, Context, GuildId) {}
+ #[cfg(feature="cache")]
+ fn on_guild_update(&self, Context, Option<Arc<RwLock<Guild>>>, PartialGuild) {}
+ #[cfg(not(feature="cache"))]
+ fn on_guild_update(&self, Context, PartialGuild) {}
+ fn on_message(&self, Context, Message) {}
+ fn on_message_delete(&self, Context, ChannelId, MessageId) {}
+ fn on_message_delete_bulk(&self, Context, ChannelId, Vec<MessageId>) {}
+ fn on_reaction_add(&self, Context, Reaction) {}
+ fn on_reaction_remove(&self, Context, Reaction) {}
+ fn on_reaction_remove_all(&self, Context, ChannelId, MessageId) {}
+ fn on_message_update(&self, Context, MessageUpdateEvent) {}
+ fn on_presence_replace(&self, Context, Vec<Presence>) {}
+ fn on_presence_update(&self, Context, PresenceUpdateEvent) {}
+ fn on_ready(&self, Context, Ready) {}
+ fn on_resume(&self, Context, ResumedEvent) {}
+ fn on_typing_start(&self, Context, TypingStartEvent) {}
+ fn on_unknown(&self, Context, String, Value) {}
+ #[cfg(feature="cache")]
+ fn on_user_update(&self, Context, CurrentUser, CurrentUser) {}
+ #[cfg(not(feature="cache"))]
+ fn on_user_update(&self, Context, CurrentUser) {}
+ fn on_voice_server_update(&self, Context, VoiceServerUpdateEvent) {}
+ fn on_voice_state_update(&self, Context, Option<GuildId>, VoiceState) {}
+ fn on_webhook_update(&self, Context, GuildId, ChannelId) {}
+}
diff --git a/src/client/mod.rs b/src/client/mod.rs
index 87ebfff..9895fe9 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -22,10 +22,11 @@
mod context;
mod dispatch;
mod error;
-mod event_store;
+mod event_handler;
pub use self::context::Context;
pub use self::error::Error as ClientError;
+pub use self::event_handler::EventHandler;
// Note: the following re-exports are here for backwards compatibility
pub use ::gateway;
@@ -35,9 +36,7 @@ pub use ::http as rest;
pub use ::CACHE;
use self::dispatch::dispatch;
-use self::event_store::EventStore;
-use std::collections::HashMap;
-use std::sync::{Arc, Mutex, RwLock};
+use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{mem, thread};
use super::gateway::Shard;
@@ -47,7 +46,6 @@ use ::http;
use ::internal::prelude::*;
use ::internal::ws_impl::ReceiverExt;
use ::model::event::*;
-use ::model::*;
#[cfg(feature="framework")]
use ::framework::Framework;
@@ -89,7 +87,7 @@ use ::framework::Framework;
/// [`on_message`]: #method.on_message
/// [`Event::MessageCreate`]: ../model/event/enum.Event.html#variant.MessageCreate
/// [sharding docs]: gateway/index.html#sharding
-pub struct Client {
+pub struct Client<H: EventHandler + Send + Sync + 'static> {
/// A ShareMap which requires types to be Send + Sync. This is a map that
/// can be safely shared across contexts.
///
@@ -165,14 +163,13 @@ pub struct Client {
///
/// [`Event::Ready`]: ../model/event/enum.Event.html#variant.Ready
/// [`on_ready`]: #method.on_ready
- event_store: Arc<RwLock<EventStore>>,
+ event_handler: Arc<H>,
#[cfg(feature="framework")]
framework: Arc<Mutex<Framework>>,
token: Arc<Mutex<String>>,
}
-#[allow(type_complexity)]
-impl Client {
+impl<H: EventHandler + Send + Sync + 'static> Client<H> {
/// Creates a Client for a bot user.
///
/// Discord has a requirement of prefixing bot tokens with `"Bot "`, which
@@ -198,14 +195,14 @@ impl Client {
/// # try_main().unwrap();
/// # }
/// ```
- pub fn new(token: &str) -> Self {
+ pub fn new(token: &str, handler: H) -> Self {
let token = if token.starts_with("Bot ") {
token.to_owned()
} else {
format!("Bot {}", token)
};
- init_client(token)
+ init_client(token, handler)
}
/// Alias of [`new`].
@@ -213,8 +210,8 @@ impl Client {
/// [`new`]: #method.new
#[deprecated(since="0.1.5", note="Use `new` instead")]
#[inline(always)]
- pub fn login_bot(token: &str) -> Self {
- Self::new(token)
+ pub fn login_bot(token: &str, handler: H) -> Self {
+ Self::new(token, handler)
}
/// Alias for [`new`].
@@ -222,8 +219,8 @@ impl Client {
/// [`new`]: #method.new
#[deprecated(since="0.2.1", note="Use `new` instead")]
#[inline(always)]
- pub fn login(token: &str) -> Self {
- Self::new(token)
+ pub fn login(token: &str, handler: H) -> Self {
+ Self::new(token, handler)
}
/// Sets a framework to be used with the client. All message events will be
@@ -545,422 +542,6 @@ impl Client {
self.start_connection([range[0], range[1], total_shards], http::get_gateway()?.url)
}
- /// Attaches a handler for when a [`ChannelCreate`] is received.
- ///
- /// # Examples
- ///
- /// If the channel is a guild channel, send `"first"` to the channel when
- /// one is created:
- ///
- /// ```rust,no_run
- /// # use serenity::Client;
- /// #
- /// # let mut client = Client::new("");
- /// use serenity::model::Channel;
- ///
- /// client.on_channel_create(|ctx, channel| {
- /// if let Channel::Guild(ch) = channel {
- /// if let Err(why) = ch.read().unwrap().say("first") {
- /// println!("Err sending first message: {:?}", why);
- /// }
- /// }
- /// });
- /// ```
- ///
- /// [`ChannelCreate`]: ../model/event/enum.Event.html#variant.ChannelCreate
- pub fn on_channel_create<F>(&mut self, handler: F)
- where F: Fn(Context, Channel) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_create = Some(Arc::new(handler));
- }
-
- /// Attaches a handle for when all the [`GuildCreate`]s are received;
- /// providing all the guilds' id.
- ///
- /// notes: This requires the cache feature. And that this'll fire when
- /// all the guilds from all the shards have been cached.
- ///
- /// # Examples
- ///
- /// ```rust,no_run
- /// # use serenity::client::Client;
- /// #
- /// # let mut client = Client::new("");
- ///
- /// client.on_cached(|_, guilds| {
- /// println!("All the guilds have been cached; and those are: {:?}", guilds);
- /// });
- /// ```
- ///
- /// [`GuildCreate`]: ../model/event/enum.Event.html#variant.GuildCreate
- #[cfg(feature="cache")]
- pub fn on_cached<F>(&mut self, handle: F)
- where F: Fn(Context, Vec<GuildId>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_cached = Some(Arc::new(handle));
- }
- /// Attaches a handler for when a [`ChannelDelete`] is received.
- ///
- /// # Examples
- ///
- /// If the channel is a guild channel, send the name of the channel to the
- /// guild's default channel.
- ///
- /// ```rust,no_run
- /// # use serenity::Client;
- /// #
- /// # let mut client = Client::new("");
- /// use serenity::model::{Channel, ChannelId};
- ///
- /// client.on_channel_delete(|ctx, channel| {
- /// if let Channel::Guild(channel) = channel {
- /// let (content, default_channel_id) = {
- /// let reader = channel.read().unwrap();
- /// let content = format!("A channel named '{}' was deleted.", reader.name);
- /// let id = ChannelId(reader.guild_id.0);
- ///
- /// (content, id)
- /// };
- ///
- /// if let Err(why) = default_channel_id.say(&content) {
- /// println!("Err sending message to default channel: {:?}", why);
- /// }
- /// }
- /// });
- /// ```
- ///
- /// [`ChannelDelete`]: ../model/event/enum.Event.html#variant.ChannelDelete
- pub fn on_channel_delete<F>(&mut self, handler: F)
- where F: Fn(Context, Channel) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_delete = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`ChannelPinsUpdate`] is received.
- ///
- /// [`ChannelPinsUpdate`]: ../model/event/enum.Event.html#variant.ChannelPinsUpdate
- pub fn on_channel_pins_update<F>(&mut self, handler: F)
- where F: Fn(Context, ChannelPinsUpdateEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_pins_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildCreate`] is received.
- ///
- /// [`GuildCreate`]: ../model/event/enum.Event.html#variant.GuildCreate
- pub fn on_guild_create<F>(&mut self, handler: F)
- where F: Fn(Context, Guild) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_create = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildEmojisUpdate`] is received.
- ///
- /// The `HashMap` of emojis is the new full list of emojis.
- ///
- /// [`GuildEmojisUpdate`]: ../model/event/enum.Event.html#variant.GuildEmojisUpdate
- pub fn on_guild_emojis_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, HashMap<EmojiId, Emoji>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_emojis_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildIntegrationsUpdate`] is received.
- ///
- /// [`GuildIntegrationsUpdate`]: ../model/event/enum.Event.html#variant.GuildIntegrationsUpdate
- pub fn on_guild_integrations_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_integrations_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMemberAdd`] is received.
- ///
- /// [`GuildMemberAdd`]: ../model/event/enum.Event.html#variant.GuildMemberAdd
- pub fn on_guild_member_add<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, Member) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_member_addition = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMembersChunk`] is received.
- ///
- /// [`GuildMembersChunk`]: ../model/event/enum.Event.html#variant.GuildMembersChunk
- pub fn on_guild_members_chunk<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, HashMap<UserId, Member>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_members_chunk = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildRoleCreate`] is received.
- ///
- /// [`GuildRoleCreate`]: ../model/event/enum.Event.html#variant.GuildRoleCreate
- pub fn on_guild_role_create<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, Role) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_role_create = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildUnavailable`] is received.
- ///
- /// [`GuildUnavailable`]: ../model/event/enum.Event.html#variant.GuildUnavailable
- pub fn on_guild_unavailable<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_unavailable = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildBan`] is received.
- ///
- /// [`GuildBan`]: ../model/event/enum.Event.html#variant.GuildBan
- pub fn on_member_ban<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, User) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_ban_addition = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildUnban`] is received.
- ///
- /// [`GuildUnban`]: ../model/event/enum.Event.html#variant.GuildUnban
- pub fn on_member_unban<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, User) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_ban_removal = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`MessageCreate`] is received.
- ///
- /// # Examples
- ///
- /// Print the contents of every received message:
- ///
- /// ```rust,ignore
- /// use serenity::Client;
- ///
- /// let mut client = Client::new("bot token here");
- ///
- /// client.on_message(|_context, message| {
- /// println!("{}", message.content);
- /// });
- ///
- /// let _ = client.start();
- /// ```
- ///
- /// [`MessageCreate`]: ../model/event/enum.Event.html#variant.MessageCreate
- pub fn on_message<F>(&mut self, handler: F)
- where F: Fn(Context, Message) + Send + Sync + 'static {
-
- self.event_store.write()
- .unwrap()
- .on_message = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`MessageDelete`] is received.
- ///
- /// [`MessageDelete`]: ../model/event/enum.Event.html#variant.MessageDelete
- pub fn on_message_delete<F>(&mut self, handler: F)
- where F: Fn(Context, ChannelId, MessageId) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_message_delete = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`MessageDeleteBulk`] is received.
- ///
- /// [`MessageDeleteBulk`]: ../model/event/enum.Event.html#variant.MessageDeleteBulk
- pub fn on_message_delete_bulk<F>(&mut self, handler: F)
- where F: Fn(Context, ChannelId, Vec<MessageId>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_message_delete_bulk = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`MessageUpdate`] is received.
- ///
- /// [`MessageUpdate`]: ../model/event/enum.Event.html#variant.MessageUpdate
- pub fn on_message_update<F>(&mut self, handler: F)
- where F: Fn(Context, MessageUpdateEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_message_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`PresencesReplace`] is received.
- ///
- /// [`PresencesReplace`]: ../model/event/enum.Event.html#variant.PresencesReplace
- pub fn on_presence_replace<F>(&mut self, handler: F)
- where F: Fn(Context, Vec<Presence>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_presence_replace = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`PresenceUpdate`] is received.
- ///
- /// [`PresenceUpdate`]: ../model/event/enum.Event.html#variant.PresenceUpdate
- pub fn on_presence_update<F>(&mut self, handler: F)
- where F: Fn(Context, PresenceUpdateEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_presence_update = Some(Arc::new(handler));
- }
-
- /// Attached a handler for when a [`ReactionAdd`] is received.
- ///
- /// [`ReactionAdd`]: ../model/event/enum.Event.html#variant.ReactionAdd
- pub fn on_reaction_add<F>(&mut self, handler: F)
- where F: Fn(Context, Reaction) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_reaction_add = Some(Arc::new(handler));
- }
-
- /// Attached a handler for when a [`ReactionRemove`] is received.
- ///
- /// [`ReactionRemove`]: ../model/event/enum.Event.html#variant.ReactionRemove
- pub fn on_reaction_remove<F>(&mut self, handler: F)
- where F: Fn(Context, Reaction) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_reaction_remove = Some(Arc::new(handler));
- }
-
- /// Attached a handler for when a [`ReactionRemoveAll`] is received.
- ///
- /// [`ReactionRemoveAll`]: ../model/event/enum.Event.html#variant.ReactionRemoveAll
- pub fn on_reaction_remove_all<F>(&mut self, handler: F)
- where F: Fn(Context, ChannelId, MessageId) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_reaction_remove_all = Some(Arc::new(handler));
- }
-
- /// Register an event to be called whenever a Ready event is received.
- ///
- /// Registering a handler for the ready event is good for noting when your
- /// bot has established a connection to the gateway through a [`Shard`].
- ///
- /// **Note**: The Ready event is not guarenteed to be the first event you
- /// will receive by Discord. Do not actively rely on it.
- ///
- /// # Examples
- ///
- /// Print the [current user][`CurrentUser`]'s name on ready:
- ///
- /// ```rust,no_run
- /// use serenity::Client;
- /// use std::env;
- ///
- /// let token = env::var("DISCORD_BOT_TOKEN").unwrap();
- /// let mut client = Client::new(&token);
- ///
- /// client.on_ready(|_context, ready| {
- /// println!("{} is connected", ready.user.name);
- /// });
- /// ```
- ///
- /// [`CurrentUser`]: ../model/struct.CurrentUser.html
- /// [`Shard`]: gateway/struct.Shard.html
- pub fn on_ready<F>(&mut self, handler: F)
- where F: Fn(Context, Ready) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_ready = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`ChannelRecipientAdd`] is received.
- ///
- /// [`ChannelRecipientAdd`]: ../model/event/enum.Event.html#variant.ChannelRecipientAdd
- pub fn on_recipient_add<F>(&mut self, handler: F)
- where F: Fn(Context, ChannelId, User) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_recipient_addition = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`ChannelRecipientRemove`] is received.
- ///
- /// [`ChannelRecipientRemove`]: ../model/event/enum.Event.html#variant.ChannelRecipientRemove
- pub fn on_recipient_remove<F>(&mut self, handler: F)
- where F: Fn(Context, ChannelId, User) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_recipient_removal = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`Resumed`] is received.
- ///
- /// [`Resumed`]: ../model/event/enum.Event.html#variant.Resumed
- pub fn on_resume<F>(&mut self, handler: F)
- where F: Fn(Context, ResumedEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_resume = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`TypingStart`] is received.
- ///
- /// [`TypingStart`]: ../model/event/enum.Event.html#variant.TypingStart
- pub fn on_typing_start<F>(&mut self, handler: F)
- where F: Fn(Context, TypingStartEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_typing_start = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when an [`Unknown`] is received.
- ///
- /// [`Unknown`]: ../model/event/enum.Event.html#variant.Unknown
- pub fn on_unknown<F>(&mut self, handler: F)
- where F: Fn(Context, String, Value) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_unknown = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`VoiceServerUpdate`] is received.
- ///
- /// [`VoiceServerUpdate`]: ../model/event/enum.Event.html#variant.VoiceServerUpdate
- pub fn on_voice_server_update<F>(&mut self, handler: F)
- where F: Fn(Context, VoiceServerUpdateEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_voice_server_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`VoiceStateUpdate`] is received.
- ///
- /// [`VoiceStateUpdate`]: ../model/event/enum.Event.html#variant.VoiceStateUpdate
- pub fn on_voice_state_update<F>(&mut self, handler: F)
- where F: Fn(Context, Option<GuildId>, VoiceState) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_voice_state_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`WebhookUpdate`] is received.
- ///
- /// [`WebhookUpdate`]: ../model/event/enum.Event.html#variant.WebhookUpdate
- pub fn on_webhook_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, ChannelId) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_webhook_update = Some(Arc::new(handler));
- }
-
// Shard data layout is:
// 0: first shard number to initialize
// 1: shard number to initialize up to and including
@@ -1011,7 +592,7 @@ impl Client {
let monitor_info = feature_framework! {{
MonitorInfo {
data: self.data.clone(),
- event_store: self.event_store.clone(),
+ event_handler: self.event_handler.clone(),
framework: self.framework.clone(),
gateway_url: gateway_url.clone(),
shard: shard,
@@ -1021,7 +602,7 @@ impl Client {
} else {
MonitorInfo {
data: self.data.clone(),
- event_store: self.event_store.clone(),
+ event_handler: self.event_handler.clone(),
gateway_url: gateway_url.clone(),
shard: shard,
shard_info: shard_info,
@@ -1050,199 +631,6 @@ impl Client {
}
}
-#[cfg(feature="cache")]
-impl Client {
- /// Attaches a handler for when a [`ChannelUpdate`] is received.
- ///
- /// Optionally provides the version of the channel before the update.
- ///
- /// [`ChannelUpdate`]: ../model/event/enum.Event.html#variant.ChannelUpdate
- pub fn on_channel_update<F>(&mut self, handler: F)
- where F: Fn(Context, Option<Channel>, Channel) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildDelete`] is received.
- ///
- /// Returns a partial guild as well as - optionally - the full guild, with
- /// data like [`Role`]s. This can be `None` in the event that it was not in
- /// the [`Cache`].
- ///
- /// **Note**: The relevant guild is _removed_ from the Cache when this event
- /// is received. If you need to keep it, you can either re-insert it
- /// yourself back into the Cache or manage it in another way.
- ///
- /// [`GuildDelete`]: ../model/event/enum.Event.html#variant.GuildDelete
- /// [`Role`]: ../model/struct.Role.html
- /// [`Cache`]: ../cache/struct.Cache.html
- pub fn on_guild_delete<F>(&mut self, handler: F)
- where F: Fn(Context, PartialGuild, Option<Arc<RwLock<Guild>>>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_delete = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMemberRemove`] is received.
- ///
- /// Returns the user's associated `Member` object, _if_ it existed in the
- /// cache.
- ///
- /// [`GuildMemberRemove`]: ../model/event/enum.Event.html#variant.GuildMemberRemove
- pub fn on_guild_member_remove<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_member_removal = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMemberUpdate`] is received.
- ///
- /// [`GuildMemberUpdate`]: ../model/event/enum.Event.html#variant.GuildMemberUpdate
- pub fn on_guild_member_update<F>(&mut self, handler: F)
- where F: Fn(Context, Option<Member>, Member) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_member_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildRoleDelete`] is received.
- ///
- /// [`GuildRoleDelete`]: ../model/event/enum.Event.html#variant.GuildRoleDelete
- pub fn on_guild_role_delete<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_role_delete = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildRoleUpdate`] is received.
- ///
- /// The optional `Role` is the role prior to updating. This can be `None` if
- /// it did not exist in the [`Cache`] before the update.
- ///
- /// [`GuildRoleUpdate`]: ../model/event/enum.Event.html#variant.GuildRoleUpdate
- /// [`Cache`]: ../cache/struct.Cache.html
- pub fn on_guild_role_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_role_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildUpdate`] is received.
- ///
- /// [`GuildUpdate`]: ../model/event/enum.Event.html#variant.GuildUpdate
- pub fn on_guild_update<F>(&mut self, handler: F)
- where F: Fn(Context, Option<Arc<RwLock<Guild>>>, PartialGuild) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`UserUpdate`] is received.
- ///
- /// The old current user will be provided as well.
- ///
- /// [`UserUpdate`]: ../model/event/enum.Event.html#variant.UserUpdate
- pub fn on_user_update<F>(&mut self, handler: F)
- where F: Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_user_update = Some(Arc::new(handler));
- }
-}
-
-#[cfg(not(feature="cache"))]
-impl Client {
- /// Attaches a handler for when a [`ChannelUpdate`] is received.
- ///
- /// [`ChannelUpdate`]: ../model/event/enum.Event.html#variant.ChannelUpdate
- pub fn on_channel_update<F>(&mut self, handler: F)
- where F: Fn(Context, Channel) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_channel_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildDelete`] is received.
- ///
- /// [`GuildDelete`]: ../model/event/enum.Event.html#variant.GuildDelete
- /// [`Role`]: ../model/struct.Role.html
- /// [`Cache`]: ../cache/struct.Cache.html
- pub fn on_guild_delete<F>(&mut self, handler: F)
- where F: Fn(Context, PartialGuild) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_delete = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMemberRemove`] is received.
- ///
- /// Returns the user's associated `Member` object, _if_ it existed in the
- /// cache.
- ///
- /// [`GuildMemberRemove`]: ../model/event/enum.Event.html#variant.GuildMemberRemove
- pub fn on_guild_member_remove<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, User) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_member_removal = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildMemberUpdate`] is received.
- ///
- /// [`GuildMemberUpdate`]: ../model/event/enum.Event.html#variant.GuildMemberUpdate
- pub fn on_guild_member_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildMemberUpdateEvent) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_member_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildRoleDelete`] is received.
- ///
- /// [`GuildRoleDelete`]: ../model/event/enum.Event.html#variant.GuildRoleDelete
- pub fn on_guild_role_delete<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, RoleId) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_role_delete = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildRoleUpdate`] is received.
- ///
- /// [`GuildRoleUpdate`]: ../model/event/enum.Event.html#variant.GuildRoleUpdate
- /// [`Cache`]: ../cache/struct.Cache.html
- pub fn on_guild_role_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, Role) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_role_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`GuildUpdate`] is received.
- ///
- /// [`GuildUpdate`]: ../model/event/enum.Event.html#variant.GuildUpdate
- pub fn on_guild_update<F>(&mut self, handler: F)
- where F: Fn(Context, PartialGuild) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_guild_update = Some(Arc::new(handler));
- }
-
- /// Attaches a handler for when a [`UserUpdate`] is received.
- ///
- /// [`UserUpdate`]: ../model/event/enum.Event.html#variant.UserUpdate
- pub fn on_user_update<F>(&mut self, handler: F)
- where F: Fn(Context, CurrentUser) + Send + Sync + 'static {
- self.event_store.write()
- .unwrap()
- .on_user_update = Some(Arc::new(handler));
- }
-}
-
struct BootInfo {
gateway_url: Arc<Mutex<String>>,
shard_info: [u64; 2],
@@ -1250,9 +638,9 @@ struct BootInfo {
}
#[cfg(feature="framework")]
-struct MonitorInfo {
+struct MonitorInfo<H: EventHandler + Send + Sync + 'static> {
data: Arc<Mutex<ShareMap>>,
- event_store: Arc<RwLock<EventStore>>,
+ event_handler: Arc<H>,
framework: Arc<Mutex<Framework>>,
gateway_url: Arc<Mutex<String>>,
shard: Arc<Mutex<Shard>>,
@@ -1261,9 +649,9 @@ struct MonitorInfo {
}
#[cfg(not(feature="framework"))]
-struct MonitorInfo {
+struct MonitorInfo<H: EventHandler + Send + Sync + 'static> {
data: Arc<Mutex<ShareMap>>,
- event_store: Arc<RwLock<EventStore>>,
+ event_handler: Arc<H>,
gateway_url: Arc<Mutex<String>>,
shard: Arc<Mutex<Shard>>,
shard_info: [u64; 2],
@@ -1310,7 +698,7 @@ fn boot_shard(info: &BootInfo) -> Result<Shard> {
Err(Error::Client(ClientError::ShardBootFailure))
}
-fn monitor_shard(mut info: MonitorInfo) {
+fn monitor_shard<H: EventHandler + Send + Sync + 'static>(mut info: MonitorInfo<H>) {
handle_shard(&mut info);
loop {
@@ -1347,7 +735,7 @@ fn monitor_shard(mut info: MonitorInfo) {
error!("Completely failed to reboot shard");
}
-fn handle_shard(info: &mut MonitorInfo) {
+fn handle_shard<H: EventHandler + Send + Sync + 'static>(info: &mut MonitorInfo<H>) {
// This is currently all ducktape. Redo this.
loop {
{
@@ -1420,31 +808,31 @@ fn handle_shard(info: &mut MonitorInfo) {
&info.shard,
&info.framework,
&info.data,
- &info.event_store);
+ &info.event_handler);
} else {
dispatch(event,
&info.shard,
&info.data,
- &info.event_store);
+ &info.event_handler);
}}
}
}
-fn init_client(token: String) -> Client {
+fn init_client<H: EventHandler + Send + Sync + 'static>(token: String, handler: H) -> Client<H> {
http::set_token(&token);
let locked = Arc::new(Mutex::new(token));
feature_framework! {{
Client {
data: Arc::new(Mutex::new(ShareMap::custom())),
- event_store: Arc::new(RwLock::new(EventStore::default())),
+ event_handler: Arc::new(handler),
framework: Arc::new(Mutex::new(Framework::default())),
token: locked,
}
} else {
Client {
data: Arc::new(Mutex::new(ShareMap::custom())),
- event_store: Arc::new(RwLock::new(EventStore::default())),
+ event_handler: Arc::new(handler),
token: locked,
}
}}