diff options
| author | Austin Hellyer <[email protected]> | 2016-11-15 11:36:53 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-11-15 11:36:53 -0800 |
| commit | 5ccfaaa3b1a030b1fd0dcd364bdae001347d36e4 (patch) | |
| tree | 7cf531e4790109d6d7edd26bc5b483378d5ba5ac /src/client | |
| parent | Embed Author: everything but 'name' is optional (diff) | |
| download | serenity-5ccfaaa3b1a030b1fd0dcd364bdae001347d36e4.tar.xz serenity-5ccfaaa3b1a030b1fd0dcd364bdae001347d36e4.zip | |
Add state/framework/etc. conditional compile flags
This adds conditional compilation for the following features, in
addition to the voice conditional compilation flag:
- extras (message builder)
- framework
- methods
- state
These 4 are enabled _by default_, while the `voice` feature flag is
disabled.
Disabling the state will allow incredibly low-memory bots.
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/connection.rs | 19 | ||||
| -rw-r--r-- | src/client/context.rs | 27 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 430 | ||||
| -rw-r--r-- | src/client/event_store.rs | 27 | ||||
| -rw-r--r-- | src/client/mod.rs | 398 |
5 files changed, 600 insertions, 301 deletions
diff --git a/src/client/connection.rs b/src/client/connection.rs index d1e37e5..4862667 100644 --- a/src/client/connection.rs +++ b/src/client/connection.rs @@ -36,25 +36,6 @@ use ::model::{ #[cfg(feature="voice")] use ::ext::voice::Manager as VoiceManager; -#[cfg(feature="voice")] -macro_rules! connection { - ($($name1:ident: $val1:expr),*; $($name2:ident: $val2:expr,)*) => { - Connection { - $($name1: $val1,)* - $($name2: $val2,)* - } - } -} - -#[cfg(not(feature="voice"))] -macro_rules! connection { - ($($name1:ident: $val1:expr),*; $($name2:ident: $val2:expr,)*) => { - Connection { - $($name1: $val1,)* - } - } -} - #[doc(hidden)] pub enum Status { SendMessage(Value), diff --git a/src/client/context.rs b/src/client/context.rs index 0507bc3..6443efa 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use std::io::Read; use std::sync::{Arc, Mutex}; use super::connection::Connection; -use super::{STATE, http}; +use super::http; use super::login_type::LoginType; use ::utils::builder::{ CreateInvite, @@ -19,6 +19,9 @@ use ::internal::prelude::*; use ::model::*; use ::utils; +#[cfg(feature = "state")] +use super::STATE; + #[derive(Clone)] pub struct Context { channel_id: Option<ChannelId>, @@ -553,7 +556,7 @@ impl Context { let guild_id = guild_id.into(); let role_id = role_id.into(); - let map = { + let map = feature_state! {{ let state = STATE.lock().unwrap(); let role = if let Some(role) = { @@ -565,7 +568,9 @@ impl Context { }; f(EditRole::new(role)).0.build() - }; + } else { + f(EditRole::default()).0.build() + }}; http::edit_role(guild_id.0, role_id.0, map) } @@ -601,9 +606,11 @@ impl Context { where C: Into<ChannelId> { let channel_id = channel_id.into(); - if let Some(channel) = STATE.lock().unwrap().find_channel(channel_id) { - return Ok(channel.clone()) - } + feature_state_enabled! {{ + if let Some(channel) = STATE.lock().unwrap().find_channel(channel_id) { + return Ok(channel.clone()) + } + }} http::get_channel(channel_id.0) } @@ -612,13 +619,13 @@ impl Context { -> Result<HashMap<ChannelId, PublicChannel>> where G: Into<GuildId> { let guild_id = guild_id.into(); - { + feature_state_enabled! {{ let state = STATE.lock().unwrap(); if let Some(guild) = state.find_guild(guild_id) { return Ok(guild.channels.clone()); } - } + }} let mut channels = HashMap::new(); @@ -677,13 +684,13 @@ impl Context { let guild_id = guild_id.into(); let user_id = user_id.into(); - { + feature_state_enabled! {{ let state = STATE.lock().unwrap(); if let Some(member) = state.find_member(guild_id, user_id) { return Ok(member.clone()); } - } + }} http::get_member(guild_id.0, user_id.0) } diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 6295bc9..fa41ddc 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -2,11 +2,16 @@ use std::sync::{Arc, Mutex}; use std::thread; use super::event_store::EventStore; use super::login_type::LoginType; -use super::{STATE, Connection, Context}; -use ::ext::framework::Framework; +use super::{Connection, Context}; use ::internal::prelude::*; use ::model::{ChannelId, Event, Message}; +#[cfg(feature="framework")] +use ::ext::framework::Framework; + +#[cfg(feature = "state")] +use super::STATE; + macro_rules! handler { ($field:ident, $event_store:ident) => { $event_store.lock() @@ -19,10 +24,14 @@ macro_rules! handler { macro_rules! update { ($method:ident, $event:expr) => { - STATE.lock().unwrap().$method(&$event); + feature_state_enabled! {{ + STATE.lock().unwrap().$method(&$event) + }} }; ($method:ident, $event:expr, $old:expr) => { - STATE.lock().unwrap().$method(&$event, $old); + feature_state_enabled! {{ + STATE.lock().unwrap().$method(&$event, $old) + }} }; } @@ -32,14 +41,72 @@ fn context(channel_id: Option<ChannelId>, Context::new(channel_id, conn, login_type) } -#[allow(cyclomatic_complexity)] +#[cfg(feature="framework")] pub fn dispatch(event: Result<Event>, conn: Arc<Mutex<Connection>>, framework: Arc<Mutex<Framework>>, login_type: LoginType, event_store: Arc<Mutex<EventStore>>) { match event { - Ok(Event::CallCreate(event)) => { + Ok(Event::MessageCreate(event)) => { + let context = context(Some(event.message.channel_id), + conn, + login_type); + let mut framework = framework.lock().expect("framework poisoned"); + + if framework.initialized { + dispatch_message(context.clone(), + event.message.clone(), + event_store); + + framework.dispatch(context, event.message); + } else { + dispatch_message(context, event.message, event_store); + } + }, + Ok(other) => handle_event(other, conn, login_type, event_store), + Err(_why) => {}, + } +} + +#[cfg(not(feature="framework"))] +pub fn dispatch(event: Result<Event>, + conn: Arc<Mutex<Connection>>, + login_type: LoginType, + event_store: Arc<Mutex<EventStore>>) { + match event { + Ok(Event::MessageCreate(event)) => { + let context = context(Some(event.message.channel_id), + conn, + login_type); + dispatch_message(context.clone(), + event.message.clone(), + event_store); + }, + Ok(other) => handle_event(other, conn, login_type, event_store), + Err(_why) => {}, + } +} + +fn dispatch_message(context: Context, + message: Message, + event_store: Arc<Mutex<EventStore>>) { + if let Some(ref handler) = handler!(on_message, event_store) { + let handler = handler.clone(); + + thread::spawn(move || { + (handler)(context, message); + }); + } +} + +#[allow(cyclomatic_complexity)] +fn handle_event(event: Event, + conn: Arc<Mutex<Connection>>, + login_type: LoginType, + event_store: Arc<Mutex<EventStore>>) { + match event { + Event::CallCreate(event) => { if let Some(ref handler) = handler!(on_call_create, event_store) { update!(update_with_call_create, event); @@ -53,7 +120,7 @@ pub fn dispatch(event: Result<Event>, update!(update_with_call_create, event); } }, - Ok(Event::CallDelete(event)) => { + Event::CallDelete(event) => { if let Some(ref handler) = handler!(on_call_delete, event_store) { let call = STATE .lock() @@ -72,27 +139,35 @@ pub fn dispatch(event: Result<Event>, update!(update_with_call_delete, event); } }, - Ok(Event::CallUpdate(event)) => { + Event::CallUpdate(event) => { if let Some(ref handler) = handler!(on_call_update, event_store) { - let before = update!(update_with_call_update, event, true); - let after = STATE - .lock() - .unwrap() - .calls - .get(&event.channel_id) - .cloned(); - let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, before, after); - }); + feature_state! {{ + let before = update!(update_with_call_update, event, true); + let after = STATE + .lock() + .unwrap() + .calls + .get(&event.channel_id) + .cloned(); + + thread::spawn(move || { + (handler)(context, before, after); + }); + } else { + thread::spawn(move || { + (handler)(context, event); + }); + }} } else { - update!(update_with_call_update, event, false); + feature_state_enabled! {{ + update!(update_with_call_update, event, false); + }} } }, - Ok(Event::ChannelCreate(event)) => { + Event::ChannelCreate(event) => { if let Some(ref handler) = handler!(on_channel_create, event_store) { update!(update_with_channel_create, event); let context = context(Some(event.channel.id()), @@ -107,7 +182,7 @@ pub fn dispatch(event: Result<Event>, update!(update_with_channel_create, event); } }, - Ok(Event::ChannelDelete(event)) => { + Event::ChannelDelete(event) => { if let Some(ref handler) = handler!(on_channel_delete, event_store) { update!(update_with_channel_delete, event); let context = context(None, conn, login_type); @@ -120,7 +195,7 @@ pub fn dispatch(event: Result<Event>, update!(update_with_channel_delete, event); } }, - Ok(Event::ChannelPinsAck(event)) => { + Event::ChannelPinsAck(event) => { if let Some(ref handler) = handler!(on_channel_pins_ack, event_store) { let context = context(Some(event.channel_id), conn, @@ -132,7 +207,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ChannelPinsUpdate(event)) => { + Event::ChannelPinsUpdate(event) => { if let Some(ref handler) = handler!(on_channel_pins_update, event_store) { let context = context(Some(event.channel_id), conn, @@ -144,7 +219,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ChannelRecipientAdd(event)) => { + Event::ChannelRecipientAdd(event) => { update!(update_with_channel_recipient_add, event); if let Some(ref handler) = handler!(on_channel_recipient_addition, event_store) { @@ -158,7 +233,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ChannelRecipientRemove(event)) => { + Event::ChannelRecipientRemove(event) => { update!(update_with_channel_recipient_remove, event); if let Some(ref handler) = handler!(on_channel_recipient_removal, event_store) { @@ -172,7 +247,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ChannelUpdate(event)) => { + Event::ChannelUpdate(event) => { if let Some(ref handler) = handler!(on_channel_update, event_store) { let before = STATE.lock() .unwrap() @@ -190,7 +265,7 @@ pub fn dispatch(event: Result<Event>, update!(update_with_channel_update, event); } }, - Ok(Event::GuildBanAdd(event)) => { + Event::GuildBanAdd(event) => { if let Some(ref handler) = handler!(on_guild_ban_addition, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -200,7 +275,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildBanRemove(event)) => { + Event::GuildBanRemove(event) => { if let Some(ref handler) = handler!(on_guild_ban_removal, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -210,7 +285,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildCreate(event)) => { + Event::GuildCreate(event) => { update!(update_with_guild_create, event); if let Some(ref handler) = handler!(on_guild_create, event_store) { @@ -222,20 +297,29 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildDelete(event)) => { + Event::GuildDelete(event) => { if let Some(ref handler) = handler!(on_guild_delete, event_store) { - let full = update!(update_with_guild_delete, event); let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, event.guild, full); - }); + feature_state! {{ + let full = update!(update_with_guild_delete, event); + + thread::spawn(move || { + (handler)(context, event.guild, full); + }); + } else { + thread::spawn(move || { + (handler)(context, event.guild); + }); + }} } else { - let _full = update!(update_with_guild_delete, event); + feature_state_enabled! {{ + let _full = update!(update_with_guild_delete, event); + }} } }, - Ok(Event::GuildEmojisUpdate(event)) => { + Event::GuildEmojisUpdate(event) => { update!(update_with_guild_emojis_update, event); if let Some(ref handler) = handler!(on_guild_emojis_update, event_store) { @@ -247,7 +331,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildIntegrationsUpdate(event)) => { + Event::GuildIntegrationsUpdate(event) => { if let Some(ref handler) = handler!(on_guild_integrations_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -257,7 +341,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildMemberAdd(event)) => { + Event::GuildMemberAdd(event) => { update!(update_with_guild_member_add, event); if let Some(ref handler) = handler!(on_guild_member_addition, event_store) { @@ -269,42 +353,58 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildMemberRemove(event)) => { + Event::GuildMemberRemove(event) => { if let Some(ref handler) = handler!(on_guild_member_removal, event_store) { - let member = update!(update_with_guild_member_remove, event); let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, event.guild_id, event.user, member); - }); + feature_state! {{ + let member = update!(update_with_guild_member_remove, event); + + thread::spawn(move || { + (handler)(context, event.guild_id, event.user, member); + }); + } else { + thread::spawn(move || { + (handler)(context, event.guild_id, event.user); + }); + }} } else { - let _member = update!(update_with_guild_member_remove, event); + feature_state_enabled! {{ + let _member = update!(update_with_guild_member_remove, event); + }} } }, - Ok(Event::GuildMemberUpdate(event)) => { + Event::GuildMemberUpdate(event) => { if let Some(ref handler) = handler!(on_guild_member_update, event_store) { - let before = update!(update_with_guild_member_update, event, true); - - // This is safe, as the update would have created the member - // if it did not exist. Thus, there _should_ be no way that this - // could fail under any circumstance. - let after = STATE.lock() - .unwrap() - .find_member(event.guild_id, event.user.id) - .unwrap() - .clone(); let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, before, after); - }); + feature_state! {{ + let before = update!(update_with_guild_member_update, event); + + // This is safe, as the update would have created the member + // if it did not exist. Thus, there _should_ be no way that this + // could fail under any circumstance. + let after = STATE.lock() + .unwrap() + .find_member(event.guild_id, event.user.id) + .unwrap() + .clone(); + + thread::spawn(move || { + (handler)(context, before, after); + }); + } else { + thread::spawn(move || { + (handler)(context, event); + }); + }} } else { - let _ = update!(update_with_guild_member_update, event, false); + let _ = update!(update_with_guild_member_update, event); } }, - Ok(Event::GuildMembersChunk(event)) => { + Event::GuildMembersChunk(event) => { update!(update_with_guild_members_chunk, event); if let Some(ref handler) = handler!(on_guild_members_chunk, event_store) { @@ -316,7 +416,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildRoleCreate(event)) => { + Event::GuildRoleCreate(event) => { update!(update_with_guild_role_create, event); if let Some(ref handler) = handler!(on_guild_role_create, event_store) { @@ -328,30 +428,51 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildRoleDelete(event)) => { + Event::GuildRoleDelete(event) => { if let Some(ref handler) = handler!(on_guild_role_delete, event_store) { - let role = update!(update_with_guild_role_delete, event); let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, event.guild_id, event.role_id, role); - }); + feature_state! {{ + let role = update!(update_with_guild_role_delete, event); + + thread::spawn(move || { + (handler)(context, event.guild_id, event.role_id, role); + }); + } else { + thread::spawn(move || { + (handler)(context, event.guild_id, event.role_id); + }); + }} + } else { + feature_state_enabled! {{ + let _role = update!(update_with_guild_role_delete, event); + }} } }, - Ok(Event::GuildRoleUpdate(event)) => { - let before = update!(update_with_guild_role_update, event); - + Event::GuildRoleUpdate(event) => { if let Some(ref handler) = handler!(on_guild_role_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, event.guild_id, before, event.role); - }); + feature_state! {{ + let before = update!(update_with_guild_role_update, event); + + thread::spawn(move || { + (handler)(context, event.guild_id, before, event.role); + }); + } else { + thread::spawn(move || { + (handler)(context, event.guild_id, event.role); + }); + }} + } else { + feature_state_enabled! {{ + let _before = update!(update_with_guild_role_update, event); + }} } }, - Ok(Event::GuildSync(event)) => { + Event::GuildSync(event) => { if let Some(ref handler) = handler!(on_guild_sync, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -361,7 +482,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildUnavailable(event)) => { + Event::GuildUnavailable(event) => { update!(update_with_guild_unavailable, event); if let Some(ref handler) = handler!(on_guild_unavailable, event_store) { @@ -373,7 +494,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::GuildUpdate(event)) => { + Event::GuildUpdate(event) => { if let Some(ref handler) = handler!(on_guild_update, event_store) { let before = STATE.lock() .unwrap() @@ -391,7 +512,7 @@ pub fn dispatch(event: Result<Event>, update!(update_with_guild_update, event); } } - Ok(Event::MessageAck(event)) => { + Event::MessageAck(event) => { if let Some(ref handler) = handler!(on_message_ack, event_store) { let context = context(Some(event.channel_id), conn, @@ -403,23 +524,9 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::MessageCreate(event)) => { - let context = context(Some(event.message.channel_id), - conn, - login_type); - let mut framework = framework.lock().expect("framework poisoned"); - - if framework.initialized { - dispatch_message(context.clone(), - event.message.clone(), - event_store); - - framework.dispatch(context, event.message); - } else { - dispatch_message(context, event.message, event_store); - } - }, - Ok(Event::MessageDeleteBulk(event)) => { + // Already handled by the framework check macro + Event::MessageCreate(_event) => {}, + Event::MessageDeleteBulk(event) => { if let Some(ref handler) = handler!(on_message_delete_bulk, event_store) { let context = context(Some(event.channel_id), conn, @@ -431,7 +538,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::MessageDelete(event)) => { + Event::MessageDelete(event) => { if let Some(ref handler) = handler!(on_message_delete, event_store) { let context = context(Some(event.channel_id), conn, @@ -443,7 +550,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::MessageUpdate(event)) => { + Event::MessageUpdate(event) => { if let Some(ref handler) = handler!(on_message_update, event_store) { let context = context(Some(event.channel_id), conn, @@ -455,7 +562,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::PresencesReplace(event)) => { + Event::PresencesReplace(event) => { update!(update_with_presences_replace, event); if let Some(handler) = handler!(on_presence_replace, event_store) { @@ -467,7 +574,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::PresenceUpdate(event)) => { + Event::PresenceUpdate(event) => { update!(update_with_presence_update, event); if let Some(handler) = handler!(on_presence_update, event_store) { @@ -479,7 +586,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ReactionAdd(event)) => { + Event::ReactionAdd(event) => { if let Some(ref handler) = handler!(on_reaction_add, event_store) { let context = context(Some(event.reaction.channel_id), conn, @@ -491,7 +598,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ReactionRemove(event)) => { + Event::ReactionRemove(event) => { if let Some(ref handler) = handler!(on_reaction_remove, event_store) { let context = context(Some(event.reaction.channel_id), conn, @@ -503,7 +610,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::ReactionRemoveAll(event)) => { + Event::ReactionRemoveAll(event) => { if let Some(ref handler) = handler!(on_reaction_remove_all, event_store) { let context = context(Some(event.channel_id), conn, @@ -515,7 +622,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::Ready(event)) => { + Event::Ready(event) => { if let Some(ref handler) = handler!(on_ready, event_store) { update!(update_with_ready, event); @@ -529,7 +636,7 @@ pub fn dispatch(event: Result<Event>, update!(update_with_ready, event); } }, - Ok(Event::RelationshipAdd(event)) => { + Event::RelationshipAdd(event) => { update!(update_with_relationship_add, event); if let Some(ref handler) = handler!(on_relationship_addition, event_store) { @@ -541,7 +648,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::RelationshipRemove(event)) => { + Event::RelationshipRemove(event) => { update!(update_with_relationship_remove, event); if let Some(ref handler) = handler!(on_relationship_removal, event_store) { @@ -553,7 +660,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::Resumed(event)) => { + Event::Resumed(event) => { if let Some(ref handler) = handler!(on_resume, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -563,7 +670,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::TypingStart(event)) => { + Event::TypingStart(event) => { if let Some(ref handler) = handler!(on_typing_start, event_store) { let context = context(Some(event.channel_id), conn, @@ -575,7 +682,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::Unknown(event)) => { + Event::Unknown(event) => { if let Some(ref handler) = handler!(on_unknown, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -585,58 +692,96 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::UserGuildSettingsUpdate(event)) => { - let before = update!(update_with_user_guild_settings_update, event); - + Event::UserGuildSettingsUpdate(event) => { if let Some(ref handler) = handler!(on_user_guild_settings_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, before, event.settings); - }); + feature_state! {{ + let before = update!(update_with_user_guild_settings_update, event); + + thread::spawn(move || { + (handler)(context, before, event.settings); + }); + } else { + thread::spawn(move || { + (handler)(context, event.settings); + }); + }} + } else { + feature_state_enabled! {{ + let _before = update!(update_with_user_guild_settings_update, event); + }} } }, - Ok(Event::UserNoteUpdate(event)) => { - let before = update!(update_with_user_note_update, event); - + Event::UserNoteUpdate(event) => { if let Some(ref handler) = handler!(on_note_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, event.user_id, before, event.note); - }); + feature_state! {{ + let before = update!(update_with_user_note_update, event); + + thread::spawn(move || { + (handler)(context, event.user_id, before, event.note); + }); + } else { + thread::spawn(move || { + (handler)(context, event.user_id, event.note); + }); + }} + } else { + feature_state_enabled! {{ + let _before = update!(update_with_user_note_update, event); + }} } }, - Ok(Event::UserSettingsUpdate(event)) => { + Event::UserSettingsUpdate(event) => { if let Some(ref handler) = handler!(on_user_settings_update, event_store) { - let before = update!(update_with_user_settings_update, event, true); - let after = STATE.lock().unwrap().settings.clone(); - let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, before.unwrap(), after.unwrap()); - }); + feature_state! {{ + let before = update!(update_with_user_settings_update, event, true); + let after = STATE.lock().unwrap().settings.clone(); + + thread::spawn(move || { + (handler)(context, before.unwrap(), after.unwrap()); + }); + } else { + thread::spawn(move || { + (handler)(context, event); + }); + }} } else { - update!(update_with_user_settings_update, event, false); + feature_state_enabled! {{ + update!(update_with_user_settings_update, event, false); + }} } }, - Ok(Event::UserUpdate(event)) => { - let before = update!(update_with_user_update, event); - + Event::UserUpdate(event) => { if let Some(ref handler) = handler!(on_user_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); - thread::spawn(move || { - (handler)(context, before, event.current_user); - }); + feature_state! {{ + let before = update!(update_with_user_update, event); + + thread::spawn(move || { + (handler)(context, before, event.current_user); + }); + } else { + thread::spawn(move || { + (handler)(context, event.current_user); + }); + }} + } else { + feature_state_enabled! {{ + let _before = update!(update_with_user_update, event); + }} } }, - Ok(Event::VoiceServerUpdate(event)) => { + Event::VoiceServerUpdate(event) => { if let Some(ref handler) = handler!(on_voice_server_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -646,7 +791,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::VoiceStateUpdate(event)) => { + Event::VoiceStateUpdate(event) => { update!(update_with_voice_state_update, event); if let Some(ref handler) = handler!(on_voice_state_update, event_store) { @@ -658,7 +803,7 @@ pub fn dispatch(event: Result<Event>, }); } }, - Ok(Event::WebhookUpdate(event)) => { + Event::WebhookUpdate(event) => { if let Some(ref handler) = handler!(on_webhook_update, event_store) { let context = context(None, conn, login_type); let handler = handler.clone(); @@ -668,18 +813,5 @@ pub fn dispatch(event: Result<Event>, }); } }, - Err(_why) => {}, - } -} - -fn dispatch_message(context: Context, - message: Message, - event_store: Arc<Mutex<EventStore>>) { - if let Some(ref handler) = handler!(on_message, event_store) { - let handler = handler.clone(); - - thread::spawn(move || { - (handler)(context, message); - }); } } diff --git a/src/client/event_store.rs b/src/client/event_store.rs index 387f9e7..98d874b 100644 --- a/src/client/event_store.rs +++ b/src/client/event_store.rs @@ -27,7 +27,10 @@ use ::model::*; pub struct EventStore { pub on_call_create: Option<Arc<Fn(Context, Call) + Send + Sync + 'static>>, pub on_call_delete: Option<Arc<Fn(Context, Option<Call>) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_call_update: Option<Arc<Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_call_update: Option<Arc<Fn(Context, CallUpdateEvent) + Send + Sync + 'static>>, pub on_channel_create: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>, pub on_channel_delete: Option<Arc<Fn(Context, Channel) + Send + Sync + 'static>>, pub on_channel_pins_ack: Option<Arc<Fn(Context, ChannelPinsAckEvent) + Send + Sync + 'static>>, @@ -38,16 +41,31 @@ pub struct EventStore { pub on_guild_ban_addition: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>, pub on_guild_ban_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>, pub on_guild_create: Option<Arc<Fn(Context, LiveGuild) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_guild_delete: Option<Arc<Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_guild_delete: Option<Arc<Fn(Context, Guild) + Send + Sync + 'static>>, pub on_guild_emojis_update: Option<Arc<Fn(Context, GuildId, HashMap<EmojiId, Emoji>) + Send + Sync + 'static>>, pub on_guild_integrations_update: Option<Arc<Fn(Context, GuildId) + Send + Sync + 'static>>, pub on_guild_member_addition: Option<Arc<Fn(Context, GuildId, Member) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_guild_member_update: Option<Arc<Fn(Context, Option<Member>, Member) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_guild_member_update: Option<Arc<Fn(Context, GuildMemberUpdateEvent) + Send + Sync + 'static>>, pub on_guild_members_chunk: Option<Arc<Fn(Context, GuildId, HashMap<UserId, Member>) + Send + Sync + 'static>>, pub on_guild_role_create: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>, pub on_guild_sync: Option<Arc<Fn(Context, GuildSyncEvent) + Send + Sync + 'static>>, pub on_guild_unavailable: Option<Arc<Fn(Context, GuildId) + Send + Sync + 'static>>, pub on_guild_update: Option<Arc<Fn(Context, Option<LiveGuild>, Guild) + Send + Sync + 'static>>, @@ -59,7 +77,10 @@ pub struct EventStore { pub on_reaction_remove: Option<Arc<Fn(Context, Reaction) + Send + Sync + 'static>>, pub on_reaction_remove_all: Option<Arc<Fn(Context, ChannelId, MessageId) + Send + Sync + 'static>>, pub on_message_update: Option<Arc<Fn(Context, MessageUpdateEvent) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_note_update: Option<Arc<Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_note_update: Option<Arc<Fn(Context, UserId, String) + Send + Sync + 'static>>, pub on_presence_replace: Option<Arc<Fn(Context, Vec<Presence>) + Send + Sync + 'static>>, pub on_presence_update: Option<Arc<Fn(Context, PresenceUpdateEvent) + Send + Sync + 'static>>, pub on_ready: Option<Arc<Fn(Context, Ready) + Send + Sync + 'static>>, @@ -69,8 +90,14 @@ pub struct EventStore { pub on_typing_start: Option<Arc<Fn(Context, TypingStartEvent) + Send + Sync + 'static>>, pub on_unknown: Option<Arc<Fn(Context, String, BTreeMap<String, Value>) + Send + Sync + 'static>>, pub on_user_guild_settings_update: Option<Arc<Fn(Context, Option<UserGuildSettings>, UserGuildSettings) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_user_update: Option<Arc<Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_user_update: Option<Arc<Fn(Context, CurrentUser) + Send + Sync + 'static>>, + #[cfg(feature = "state")] pub on_user_settings_update: Option<Arc<Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static>>, + #[cfg(not(feature = "state"))] + pub on_user_settings_update: Option<Arc<Fn(Context, UserSettingsUpdateEvent) + Send + Sync + 'static>>, pub on_voice_server_update: Option<Arc<Fn(Context, VoiceServerUpdateEvent) + Send + Sync + 'static>>, pub on_voice_state_update: Option<Arc<Fn(Context, Option<GuildId>, VoiceState) + Send + Sync + 'static>>, pub on_webhook_update: Option<Arc<Fn(Context, GuildId, ChannelId) + Send + Sync + 'static>>, diff --git a/src/client/mod.rs b/src/client/mod.rs index f270b31..77f1086 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -57,11 +57,16 @@ use std::collections::{BTreeMap, HashMap}; use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; -use ::ext::framework::Framework; -use ::ext::state::State; use ::internal::prelude::*; use ::model::*; +#[cfg(feature = "framework")] +use ::ext::framework::Framework; + +#[cfg(feature = "state")] +use ::ext::state::State; + +#[cfg(feature = "state")] lazy_static! { /// The STATE is a mutable lazily-initialized static binding. It can be /// accessed across any function and in any context. @@ -220,6 +225,7 @@ pub enum ClientError { pub struct Client { pub connections: Vec<Arc<Mutex<Connection>>>, event_store: Arc<Mutex<EventStore>>, + #[cfg(feature="framework")] framework: Arc<Mutex<Framework>>, login_type: LoginType, token: String, @@ -271,6 +277,7 @@ impl Client { /// /// [`on_message`]: #method.on_message /// [framework docs]: ../ext/framework/index.html + #[cfg(feature="framework")] pub fn with_framework<F>(&mut self, f: F) where F: FnOnce(Framework) -> Framework + Send + Sync + 'static { self.framework = Arc::new(Mutex::new(f(Framework::default()))); @@ -403,16 +410,6 @@ impl Client { .on_call_delete = Some(Arc::new(handler)); } - /// Attaches a handler for when a [`CallUpdate`] is received. - /// - /// [`CallUpdate`]: ../model/enum.Event.html#variant.CallUpdate - pub fn on_call_update<F>(&mut self, handler: F) - where F: Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static { - self.event_store.lock() - .unwrap() - .on_call_update = Some(Arc::new(handler)); - } - /// Attaches a handler for when a [`ChannelCreate`] is received. /// /// [`ChannelCreate`]: ../model/enum.Event.html#variant.ChannelCreate @@ -473,26 +470,6 @@ impl Client { .on_guild_create = Some(Arc::new(handler)); } - /// Attaches a handler for when a [`GuilDelete`] 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 [`State`]. - /// - /// **Note**: The relevant guild is _removed_ from the State when this event - /// is received. If you need to keep it, you can either re-insert it - /// yourself back into the State or manage it in another way. - /// - /// [`GuildDelete`]: ../model/enum.Event.html#variant.GuildDelete - /// [`Role`]: ../model/struct.Role.html - /// [`State`]: ../ext/state/struct.State.html - pub fn on_guild_delete<F>(&mut self, handler: F) - where F: Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static { - self.event_store.lock() - .unwrap() - .on_guild_delete = Some(Arc::new(handler)); - } - /// Attaches a handler for when a [`GuildEmojisUpdate`] is received. /// /// The `HashMap` of emojis is the new full list of emojis. @@ -525,29 +502,6 @@ impl Client { .on_guild_member_addition = 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 - /// state. - /// - /// [`GuildMemberRemove`]: ../model/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.lock() - .unwrap() - .on_guild_member_removal = Some(Arc::new(handler)); - } - - /// Attaches a handler for when a [`GuildMemberUpdate`] is received. - /// - /// [`GuildMemberUpdate`]: ../model/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.lock() - .unwrap() - .on_guild_member_update = Some(Arc::new(handler)); - } - /// Attaches a handler for when a [`GuildMembersChunk`] is received. /// /// [`GuildMembersChunk`]: ../model/enum.Event.html#variant.GuildMembersChunk @@ -568,16 +522,6 @@ impl Client { .on_guild_role_create = Some(Arc::new(handler)); } - /// Attaches a handler for when a [`GuildRoleDelete`] is received. - /// - /// [`GuildRoleDelete`]: ../model/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.lock() - .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 @@ -693,19 +637,6 @@ impl Client { .on_message_update = Some(Arc::new(handler)); } - /// Attaches a handler for when a [`UserNoteUpdate`] is received. - /// - /// Optionally returns the old note for the [`User`], if one existed. - /// - /// [`User`]: ../model/struct.User.html - /// [`UserNoteUpdate`]: ../model/enum.Event.html#variant.UserNoteUpdate - pub fn on_note_update<F>(&mut self, handler: F) - where F: Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static { - self.event_store.lock() - .unwrap() - .on_note_update = Some(Arc::new(handler)); - } - /// Attaches a handler for when a [`PresencesReplace`] is received. /// /// [`PresencesReplace`]: ../model/enum.Event.html#variant.PresencesReplace @@ -733,7 +664,7 @@ impl Client { where F: Fn(Context, Reaction) + Send + Sync + 'static { self.event_store.lock() .unwrap() - .on_reaction_add = Some(Arc::new(handler)) + .on_reaction_add = Some(Arc::new(handler)); } /// Attached a handler for when a [`ReactionRemove`] is received. @@ -743,7 +674,7 @@ impl Client { where F: Fn(Context, Reaction) + Send + Sync + 'static { self.event_store.lock() .unwrap() - .on_reaction_remove = Some(Arc::new(handler)) + .on_reaction_remove = Some(Arc::new(handler)); } /// Attached a handler for when a [`ReactionRemoveAll`] is received. @@ -753,7 +684,7 @@ impl Client { where F: Fn(Context, ChannelId, MessageId) + Send + Sync + 'static { self.event_store.lock() .unwrap() - .on_reaction_remove_all = Some(Arc::new(handler)) + .on_reaction_remove_all = Some(Arc::new(handler)); } /// Register an event to be called whenever a Ready event is received. @@ -868,26 +799,6 @@ impl Client { .on_user_guild_settings_update = Some(Arc::new(handler)); } - /// Attaches a handler for when a [`UserUpdate`] is received. - /// - /// [`UserUpdate`]: ../model/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.lock() - .unwrap() - .on_user_update = Some(Arc::new(handler)); - } - - /// Attaches a handler for when a [`UserSettingsUpdate`] is received. - /// - /// [`UserSettingsUpdate`]: ../model/enum.Event.html#variant.UserSettingsUpdate - pub fn on_user_settings_update<F>(&mut self, handler: F) - where F: Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static { - self.event_store.lock() - .unwrap() - .on_user_settings_update = Some(Arc::new(handler)); - } - /// Attaches a handler for when a [`VoiceServerUpdate`] is received. /// /// [`VoiceServerUpdate`]: ../model/enum.Event.html#variant.VoiceServerUpdate @@ -936,28 +847,47 @@ impl Client { Ok((connection, ready)) => { self.connections.push(Arc::new(Mutex::new(connection))); - STATE.lock() - .unwrap() - .update_with_ready(&ready); + feature_state_enabled! {{ + STATE.lock() + .unwrap() + .update_with_ready(&ready); + }} match self.connections.last() { Some(connection) => { - dispatch(Ok(Event::Ready(ready)), - connection.clone(), - self.framework.clone(), - self.login_type, - self.event_store.clone()); + feature_framework! {{ + dispatch(Ok(Event::Ready(ready)), + connection.clone(), + self.framework.clone(), + self.login_type, + self.event_store.clone()); + } { + dispatch(Ok(Event::Ready(ready)), + connection.clone(), + self.login_type, + self.event_store.clone()); + }} let connection_clone = connection.clone(); let event_store = self.event_store.clone(); - let framework = self.framework.clone(); let login_type = self.login_type; - thread::spawn(move || { - handle_connection(connection_clone, - framework, - login_type, - event_store); - }); + + feature_framework! {{ + let framework = self.framework.clone(); + + thread::spawn(move || { + handle_connection(connection_clone, + framework, + login_type, + event_store) + }); + } { + thread::spawn(move || { + handle_connection(connection_clone, + login_type, + event_store) + }); + }} }, None => return Err(Error::Client(ClientError::ConnectionUnknown)), } @@ -986,6 +916,201 @@ impl Client { } } +#[cfg(feature = "state")] +impl Client { + /// Attaches a handler for when a [`CallUpdate`] is received. + /// + /// [`CallUpdate`]: ../model/enum.Event.html#variant.CallUpdate + pub fn on_call_update<F>(&mut self, handler: F) + where F: Fn(Context, Option<Call>, Option<Call>) + Send + Sync + 'static { + self.event_store.lock() + .unwrap() + .on_call_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 [`State`]. + /// + /// **Note**: The relevant guild is _removed_ from the State when this event + /// is received. If you need to keep it, you can either re-insert it + /// yourself back into the State or manage it in another way. + /// + /// [`GuildDelete`]: ../model/enum.Event.html#variant.GuildDelete + /// [`Role`]: ../model/struct.Role.html + /// [`State`]: ../ext/state/struct.State.html + pub fn on_guild_delete<F>(&mut self, handler: F) + where F: Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static { + self.event_store.lock() + .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 + /// state. + /// + /// [`GuildMemberRemove`]: ../model/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.lock() + .unwrap() + .on_guild_member_removal = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`GuildMemberUpdate`] is received. + /// + /// [`GuildMemberUpdate`]: ../model/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.lock() + .unwrap() + .on_guild_member_update = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`GuildRoleDelete`] is received. + /// + /// [`GuildRoleDelete`]: ../model/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.lock() + .unwrap() + .on_guild_role_delete = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`UserNoteUpdate`] is received. + /// + /// Optionally returns the old note for the [`User`], if one existed. + /// + /// [`User`]: ../model/struct.User.html + /// [`UserNoteUpdate`]: ../model/enum.Event.html#variant.UserNoteUpdate + pub fn on_note_update<F>(&mut self, handler: F) + where F: Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static { + self.event_store.lock() + .unwrap() + .on_note_update = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`UserSettingsUpdate`] is received. + /// + /// The old user settings will be provided as well. + /// + /// [`UserSettingsUpdate`]: ../model/enum.Event.html#variant.UserSettingsUpdate + pub fn on_user_settings_update<F>(&mut self, handler: F) + where F: Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static { + self.event_store.lock() + .unwrap() + .on_user_settings_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/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.lock() + .unwrap() + .on_user_update = Some(Arc::new(handler)); + } +} + +#[cfg(not(feature = "state"))] +impl Client { + /// Attaches a handler for when a [`CallUpdate`] is received. + /// + /// [`CallUpdate`]: ../model/enum.Event.html#variant.CallUpdate + pub fn on_call_update<F>(&mut self, handler: F) + where F: Fn(Context, CallUpdateEvent) + Send + Sync + 'static { + self.event_store.lock() + .unwrap() + .on_call_update = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`GuildDelete`] is received. + /// + /// [`GuildDelete`]: ../model/enum.Event.html#variant.GuildDelete + /// [`Role`]: ../model/struct.Role.html + /// [`State`]: ../ext/state/struct.State.html + pub fn on_guild_delete<F>(&mut self, handler: F) + where F: Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static { + self.event_store.lock() + .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 + /// state. + /// + /// [`GuildMemberRemove`]: ../model/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.lock() + .unwrap() + .on_guild_member_removal = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`GuildMemberUpdate`] is received. + /// + /// [`GuildMemberUpdate`]: ../model/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.lock() + .unwrap() + .on_guild_member_update = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`GuildRoleDelete`] is received. + /// + /// [`GuildRoleDelete`]: ../model/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.lock() + .unwrap() + .on_guild_role_delete = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`UserNoteUpdate`] is received. + /// + /// Optionally returns the old note for the [`User`], if one existed. + /// + /// [`User`]: ../model/struct.User.html + /// [`UserNoteUpdate`]: ../model/enum.Event.html#variant.UserNoteUpdate + pub fn on_note_update<F>(&mut self, handler: F) + where F: Fn(Context, UserId, String) + Send + Sync + 'static { + self.event_store.lock() + .unwrap() + .on_note_update = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`UserSettingsUpdate`] is received. + /// + /// [`UserSettingsUpdate`]: ../model/enum.Event.html#variant.UserSettingsUpdate + pub fn on_user_settings_update<F>(&mut self, handler: F) + where F: Fn(Context, UserSettingsEvent) + Send + Sync + 'static { + self.event_store.lock() + .unwrap() + .on_user_settings_update = Some(Arc::new(handler)); + } + + /// Attaches a handler for when a [`UserUpdate`] is received. + /// + /// [`UserUpdate`]: ../model/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.lock() + .unwrap() + .on_user_update = Some(Arc::new(handler)); + } +} + +#[cfg(feature="framework")] fn handle_connection(connection: Arc<Mutex<Connection>>, framework: Arc<Mutex<Framework>>, login_type: LoginType, @@ -1005,18 +1130,45 @@ fn handle_connection(connection: Arc<Mutex<Connection>>, } } +#[cfg(not(feature="framework"))] +fn handle_connection(connection: Arc<Mutex<Connection>>, + login_type: LoginType, + event_store: Arc<Mutex<EventStore>>) { + loop { + let event = { + let mut connection = connection.lock().unwrap(); + + connection.receive() + }; + + dispatch(event, + connection.clone(), + login_type, + event_store.clone()); + } +} + fn login(token: &str, login_type: LoginType) -> Client { let token = token.to_owned(); http::set_token(&token); - Client { - connections: Vec::default(), - event_store: Arc::new(Mutex::new(EventStore::default())), - framework: Arc::new(Mutex::new(Framework::default())), - login_type: login_type, - token: token.to_owned(), - } + feature_framework! {{ + Client { + connections: Vec::default(), + event_store: Arc::new(Mutex::new(EventStore::default())), + framework: Arc::new(Mutex::new(Framework::default())), + login_type: login_type, + token: token.to_owned(), + } + } { + Client { + connections: Vec::default(), + event_store: Arc::new(Mutex::new(EventStore::default())), + login_type: login_type, + token: token.to_owned(), + } + }} } /// Validates that a token is likely in a valid format. |