aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorAustin Hellyer <[email protected]>2016-11-15 08:12:53 -0800
committerAustin Hellyer <[email protected]>2016-11-15 08:12:53 -0800
commitb0be1414dc75c8ace19fa033fd54046c71640c13 (patch)
tree7b125327e35b21506a8c25b54e1cb3a9dfe41e70 /src/client
parentDecode embed/role colours into Colour struct (diff)
downloadserenity-b0be1414dc75c8ace19fa033fd54046c71640c13.tar.xz
serenity-b0be1414dc75c8ace19fa033fd54046c71640c13.zip
State: on update, return old instances
When updating the State, return the old instance of removed/updated fields where possible, so that they can be used to send to event handlers as a "this is what it used to look like, this is what it looks like now" type of thing. Very descriptive, I know.
Diffstat (limited to 'src/client')
-rw-r--r--src/client/dispatch.rs85
-rw-r--r--src/client/event_store.rs16
-rw-r--r--src/client/mod.rs58
3 files changed, 81 insertions, 78 deletions
diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs
index 7efee75..985f03e 100644
--- a/src/client/dispatch.rs
+++ b/src/client/dispatch.rs
@@ -20,7 +20,10 @@ macro_rules! handler {
macro_rules! update {
($method:ident, $event:expr) => {
STATE.lock().unwrap().$method(&$event);
- }
+ };
+ ($method:ident, $event:expr, $old:expr) => {
+ STATE.lock().unwrap().$method(&$event, $old);
+ };
}
fn context(channel_id: Option<ChannelId>,
@@ -71,13 +74,7 @@ pub fn dispatch(event: Result<Event>,
},
Ok(Event::CallUpdate(event)) => {
if let Some(ref handler) = handler!(on_call_update, event_store) {
- let before = STATE
- .lock()
- .unwrap()
- .calls
- .get(&event.channel_id)
- .cloned();
- update!(update_with_call_update, event);
+ let before = update!(update_with_call_update, event, true);
let after = STATE
.lock()
.unwrap()
@@ -92,7 +89,7 @@ pub fn dispatch(event: Result<Event>,
(handler)(context, before, after);
});
} else {
- update!(update_with_call_update, event);
+ update!(update_with_call_update, event, false);
}
},
Ok(Event::ChannelCreate(event)) => {
@@ -226,15 +223,16 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::GuildDelete(event)) => {
- update!(update_with_guild_delete, 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);
+ (handler)(context, event.guild, full);
});
+ } else {
+ let _full = update!(update_with_guild_delete, event);
}
},
Ok(Event::GuildEmojisUpdate(event)) => {
@@ -245,7 +243,7 @@ pub fn dispatch(event: Result<Event>,
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event);
+ (handler)(context, event.guild_id, event.emojis);
});
}
},
@@ -255,7 +253,7 @@ pub fn dispatch(event: Result<Event>,
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event);
+ (handler)(context, event.guild_id);
});
}
},
@@ -272,30 +270,21 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::GuildMemberRemove(event)) => {
- update!(update_with_guild_member_remove, 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);
+ (handler)(context, event.guild_id, event.user, member);
});
+ } else {
+ let _member = update!(update_with_guild_member_remove, event);
}
},
Ok(Event::GuildMemberUpdate(event)) => {
if let Some(ref handler) = handler!(on_guild_member_update, event_store) {
- let before = STATE.lock()
- .unwrap()
- .guilds
- .get_mut(&event.guild_id)
- .map(|mut guild| {
- guild.members.remove(&event.user.id)
- }).and_then(|x| match x {
- Some(x) => Some(x),
- _ => None,
- });
- update!(update_with_guild_member_update, event);
+ 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
@@ -311,6 +300,8 @@ pub fn dispatch(event: Result<Event>,
thread::spawn(move || {
(handler)(context, before, after);
});
+ } else {
+ let _ = update!(update_with_guild_member_update, event, false);
}
},
Ok(Event::GuildMembersChunk(event)) => {
@@ -338,26 +329,25 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::GuildRoleDelete(event)) => {
- update!(update_with_guild_role_delete, 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);
+ (handler)(context, event.guild_id, event.role_id, role);
});
}
},
Ok(Event::GuildRoleUpdate(event)) => {
- update!(update_with_guild_role_update, event);
+ let before = update!(update_with_guild_role_update, 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, event.role);
+ (handler)(context, event.guild_id, before, event.role);
});
}
},
@@ -596,13 +586,9 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::UserGuildSettingsUpdate(event)) => {
- if let Some(ref handler) = handler!(on_user_guild_settings_update, event_store) {
- let before = STATE.lock()
- .unwrap()
- .guild_settings
- .remove(&event.settings.guild_id);
- update!(update_with_user_guild_settings_update, event);
+ let before = update!(update_with_user_guild_settings_update, 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();
@@ -612,19 +598,20 @@ pub fn dispatch(event: Result<Event>,
}
},
Ok(Event::UserNoteUpdate(event)) => {
+ let before = update!(update_with_user_note_update, 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, event.note);
+ (handler)(context, event.user_id, before, event.note);
});
}
},
Ok(Event::UserSettingsUpdate(event)) => {
if let Some(ref handler) = handler!(on_user_settings_update, event_store) {
- let before = STATE.lock().unwrap().settings.clone();
- update!(update_with_user_settings_update, event);
+ let before = update!(update_with_user_settings_update, event, true);
let after = STATE.lock().unwrap().settings.clone();
let context = context(None, conn, login_type);
@@ -634,19 +621,13 @@ pub fn dispatch(event: Result<Event>,
(handler)(context, before.unwrap(), after.unwrap());
});
} else {
- update!(update_with_user_settings_update, event);
+ update!(update_with_user_settings_update, event, false);
}
},
Ok(Event::UserUpdate(event)) => {
- if let Some(ref handler) = handler!(on_user_update, event_store) {
- // This is equivilant to performing a
- // `update_with_voice_state_update`, and will be more efficient.
- let before = {
- let mut state = STATE.lock().unwrap();
-
- mem::replace(&mut state.user, event.current_user.clone())
- };
+ let before = update!(update_with_user_update, event);
+ if let Some(ref handler) = handler!(on_user_update, event_store) {
let context = context(None, conn, login_type);
let handler = handler.clone();
@@ -673,7 +654,7 @@ pub fn dispatch(event: Result<Event>,
let handler = handler.clone();
thread::spawn(move || {
- (handler)(context, event);
+ (handler)(context, event.guild_id, event.voice_state);
});
}
},
diff --git a/src/client/event_store.rs b/src/client/event_store.rs
index 576fe29..387f9e7 100644
--- a/src/client/event_store.rs
+++ b/src/client/event_store.rs
@@ -38,16 +38,16 @@ 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>>,
- pub on_guild_delete: Option<Arc<Fn(Context, Guild) + Send + Sync + 'static>>,
- pub on_guild_emojis_update: Option<Arc<Fn(Context, GuildEmojisUpdateEvent) + Send + Sync + 'static>>,
- pub on_guild_integrations_update: Option<Arc<Fn(Context, GuildIntegrationsUpdateEvent) + Send + Sync + 'static>>,
+ pub on_guild_delete: Option<Arc<Fn(Context, Guild, Option<LiveGuild>) + 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>>,
- pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User) + Send + Sync + 'static>>,
+ pub on_guild_member_removal: Option<Arc<Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static>>,
pub on_guild_member_update: Option<Arc<Fn(Context, Option<Member>, Member) + 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>>,
- pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId) + Send + Sync + 'static>>,
- pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Role) + Send + Sync + 'static>>,
+ pub on_guild_role_delete: Option<Arc<Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static>>,
+ pub on_guild_role_update: Option<Arc<Fn(Context, GuildId, Option<Role>, 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 +59,7 @@ 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>>,
- pub on_note_update: Option<Arc<Fn(Context, UserId, String) + Send + Sync + 'static>>,
+ pub on_note_update: Option<Arc<Fn(Context, UserId, Option<String>, 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>>,
@@ -71,7 +71,7 @@ pub struct EventStore {
pub on_user_guild_settings_update: Option<Arc<Fn(Context, Option<UserGuildSettings>, UserGuildSettings) + Send + Sync + 'static>>,
pub on_user_update: Option<Arc<Fn(Context, CurrentUser, CurrentUser) + Send + Sync + 'static>>,
pub on_user_settings_update: Option<Arc<Fn(Context, UserSettings, UserSettings) + Send + Sync + 'static>>,
- pub on_voice_state_update: Option<Arc<Fn(Context, VoiceStateUpdateEvent) + 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 661d477..f270b31 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -475,9 +475,19 @@ impl Client {
/// Attaches a handler for when a [`GuilDelete`] is received.
///
- /// [`GuilDelete`]: ../model/enum.Event.html#variant.GuildDelete
+ /// 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) + Send + Sync + 'static {
+ where F: Fn(Context, Guild, Option<LiveGuild>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_delete = Some(Arc::new(handler));
@@ -485,9 +495,11 @@ impl Client {
/// Attaches a handler for when a [`GuildEmojisUpdate`] is received.
///
+ /// The `HashMap` of emojis is the new full list of emojis.
+ ///
/// [`GuildEmojisUpdate`]: ../model/enum.Event.html#variant.GuildEmojisUpdate
pub fn on_guild_emojis_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildEmojisUpdateEvent) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId, HashMap<EmojiId, Emoji>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_emojis_update = Some(Arc::new(handler));
@@ -497,7 +509,7 @@ impl Client {
///
/// [`GuildIntegrationsUpdate`]: ../model/enum.Event.html#variant.GuildIntegrationsUpdate
pub fn on_guild_integrations_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildIntegrationsUpdateEvent) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_integrations_update = Some(Arc::new(handler));
@@ -515,9 +527,12 @@ impl Client {
/// 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 {
+ where F: Fn(Context, GuildId, User, Option<Member>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_member_removal = Some(Arc::new(handler));
@@ -557,7 +572,7 @@ impl Client {
///
/// [`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 {
+ where F: Fn(Context, GuildId, RoleId, Option<Role>) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_role_delete = Some(Arc::new(handler));
@@ -565,9 +580,13 @@ impl Client {
/// 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 [`State`] before the update.
+ ///
/// [`GuildRoleUpdate`]: ../model/enum.Event.html#variant.GuildRoleUpdate
+ /// [`State`]: ../ext/state/struct.State.html
pub fn on_guild_role_update<F>(&mut self, handler: F)
- where F: Fn(Context, GuildId, Role) + Send + Sync + 'static {
+ where F: Fn(Context, GuildId, Option<Role>, Role) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_guild_role_update = Some(Arc::new(handler));
@@ -676,9 +695,12 @@ impl Client {
/// 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 {
+ where F: Fn(Context, UserId, Option<String>, String) + Send + Sync + 'static {
self.event_store.lock()
.unwrap()
.on_note_update = Some(Arc::new(handler));
@@ -866,16 +888,6 @@ impl Client {
.on_user_settings_update = Some(Arc::new(handler));
}
- /// Attaches a handler for when a [`VoiceStateUpdate`] is received.
- ///
- /// [`VoiceStateUpdate`]: ../model/enum.Event.html#variant.VoiceStateUpdate
- pub fn on_voice_state_update<F>(&mut self, handler: F)
- where F: Fn(Context, VoiceStateUpdateEvent) + Send + Sync + 'static {
- self.event_store.lock()
- .unwrap()
- .on_voice_state_update = Some(Arc::new(handler));
- }
-
/// Attaches a handler for when a [`VoiceServerUpdate`] is received.
///
/// [`VoiceServerUpdate`]: ../model/enum.Event.html#variant.VoiceServerUpdate
@@ -886,6 +898,16 @@ impl Client {
.on_voice_server_update = Some(Arc::new(handler));
}
+ /// Attaches a handler for when a [`VoiceStateUpdate`] is received.
+ ///
+ /// [`VoiceStateUpdate`]: ../model/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.lock()
+ .unwrap()
+ .on_voice_state_update = Some(Arc::new(handler));
+ }
+
/// Attaches a handler for when a [`WebhookUpdate`] is received.
///
/// [`WebhookUpdate`]: ../model/enum.Event.html#variant.WebhookUpdate