diff options
| author | acdenisSK <[email protected]> | 2017-06-28 19:38:51 +0200 |
|---|---|---|
| committer | acdenisSK <[email protected]> | 2017-06-28 19:38:51 +0200 |
| commit | ea432af97a87b8a3d673a1f40fe06cde4d84e146 (patch) | |
| tree | 1afbc7d396f83e1eea0550b848764a14832c277a /src/client/dispatch.rs | |
| parent | Add reaction actions (#115) (diff) | |
| download | serenity-ea432af97a87b8a3d673a1f40fe06cde4d84e146.tar.xz serenity-ea432af97a87b8a3d673a1f40fe06cde4d84e146.zip | |
Merge branch "trait-based-event-handling"
Diffstat (limited to 'src/client/dispatch.rs')
| -rw-r--r-- | src/client/dispatch.rs | 520 |
1 files changed, 220 insertions, 300 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)); }, } } |