diff options
| author | Austin Hellyer <[email protected]> | 2016-12-05 07:46:22 -0800 |
|---|---|---|
| committer | Austin Hellyer <[email protected]> | 2016-12-05 07:46:22 -0800 |
| commit | ccb9d16e5dbe965e5a604e1cb402cd3bc7de0df5 (patch) | |
| tree | b7eed1952ae14f215074452c3e3d1bc081a89b0a | |
| parent | Add more Context docs+permission requirements (diff) | |
| download | serenity-ccb9d16e5dbe965e5a604e1cb402cd3bc7de0df5.tar.xz serenity-ccb9d16e5dbe965e5a604e1cb402cd3bc7de0df5.zip | |
Add a ShareMap across contexts
The context now exposes, through the Client, a `data` field, which can
be accessed safely across contexts. This allows for a custom "shared
state" without the need for (ab)using lazy-static.rs.
Refer to example 06 for an example on how to use shared data.
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | examples/06_command_framework/Cargo.toml | 3 | ||||
| -rw-r--r-- | examples/06_command_framework/src/main.rs | 44 | ||||
| -rw-r--r-- | src/client/context.rs | 8 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 99 | ||||
| -rw-r--r-- | src/client/mod.rs | 35 | ||||
| -rw-r--r-- | src/lib.rs | 1 |
7 files changed, 147 insertions, 44 deletions
@@ -21,6 +21,7 @@ lazy_static = "0.2" log = "0.3" serde_json = "0.8" time = "0.1" +typemap = "0.3" websocket = "0.17" [dependencies.cookie] diff --git a/examples/06_command_framework/Cargo.toml b/examples/06_command_framework/Cargo.toml index 481dd6f..a73f940 100644 --- a/examples/06_command_framework/Cargo.toml +++ b/examples/06_command_framework/Cargo.toml @@ -3,6 +3,9 @@ name = "06_command_framework" version = "0.1.0" authors = ["my name <[email protected]>"] +[dependencies] +typemap = "0.3" + [dependencies.serenity] features = ["framework", "methods"] version = "0.1" diff --git a/examples/06_command_framework/src/main.rs b/examples/06_command_framework/src/main.rs index b399dff..0943d81 100644 --- a/examples/06_command_framework/src/main.rs +++ b/examples/06_command_framework/src/main.rs @@ -10,11 +10,21 @@ #[macro_use] extern crate serenity; +extern crate typemap; use serenity::client::Context; use serenity::Client; use serenity::model::Message; +use std::collections::HashMap; use std::env; +use std::fmt::Write; +use typemap::Key; + +struct CommandCounter; + +impl Key for CommandCounter { + type Value = HashMap<String, u64>; +} fn main() { // Configure the client with your Discord bot token in the environment. @@ -22,6 +32,11 @@ fn main() { .expect("Expected a token in the environment"); let mut client = Client::login_bot(&token); + { + let mut data = client.data.lock().unwrap(); + data.insert::<CommandCounter>(HashMap::default()); + } + client.on_ready(|_context, ready| { println!("{} is connected!", ready.user.name); }); @@ -51,16 +66,26 @@ fn main() { // You can not use this to determine whether a command should be // executed. Instead, `set_check` is provided to give you this // functionality. - .before(|_context, message, command_name| { + .before(|context, message, command_name| { println!("Got command '{}' by user '{}'", command_name, message.author.name); + + // Increment the number of times this command has been run once. If + // the command's name does not exist in the counter, add a default + // value of 0. + let mut data = context.data.lock().unwrap(); + let counter = data.get_mut::<CommandCounter>().unwrap(); + let entry = counter.entry(command_name.clone()).or_insert(0); + *entry += 1; }) // Very similar to `before`, except this will be called directly _after_ // command execution. .after(|_context, _message, command_name| { println!("Processed command '{}'", command_name) }) + .on("commands", commands) + .set_check("commands", owner_check) .on("ping", ping_command) .set_check("ping", owner_check) // Ensure only the owner can run this .on("emoji cat", cat_command) @@ -84,12 +109,27 @@ fn main() { // This may bring more features available for commands in the future. See the // "multiply" command below for some of the power that the `command!` macro can // bring. -command!(cat_command(context, _msg, _arg) { +command!(cat_command(context, _msg, _args) { if let Err(why) = context.say(":cat:") { println!("Eror sending message: {:?}", why); } }); +command!(commands(context, _msg, _args) { + let mut contents = "Commands used:\n".to_owned(); + + let data = context.data.lock().unwrap(); + let counter = data.get::<CommandCounter>().unwrap(); + + for (k, v) in counter { + let _ = write!(contents, "- {name}: {amount}\n", name=k, amount=v); + } + + if let Err(why) = context.say(&contents) { + println!("Error sending message: {:?}", why); + } +}); + fn dog_command(context: &Context, _msg: &Message, _args: Vec<String>) { if let Err(why) = context.say(":dog:") { println!("Error sending message: {:?}", why); diff --git a/src/client/context.rs b/src/client/context.rs index 4fca519..af90447 100644 --- a/src/client/context.rs +++ b/src/client/context.rs @@ -6,6 +6,7 @@ use std::sync::{Arc, Mutex}; use super::gateway::Shard; use super::rest::{self, GuildPagination}; use super::login_type::LoginType; +use typemap::ShareMap; use ::utils::builder::{ CreateEmbed, CreateInvite, @@ -82,6 +83,11 @@ pub struct Context { /// /// [`on_message`]: struct.Client.html#method.on_message pub channel_id: Option<ChannelId>, + /// A clone of [`Client::data`]. Refer to its documentation for more + /// information. + /// + /// [`Client::data`]: struct.Client.html#method.data + pub data: Arc<Mutex<ShareMap>>, /// The associated shard which dispatched the event handler. /// /// Note that if you are sharding, in relevant terms, this is the shard @@ -101,9 +107,11 @@ impl Context { #[doc(hidden)] pub fn new(channel_id: Option<ChannelId>, shard: Arc<Mutex<Shard>>, + data: Arc<Mutex<ShareMap>>, login_type: LoginType) -> Context { Context { channel_id: channel_id, + data: data, shard: shard, login_type: login_type, } diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 44832cc..3207a0a 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -4,6 +4,7 @@ use super::event_store::EventStore; use super::login_type::LoginType; use super::Context; use super::gateway::Shard; +use typemap::ShareMap; use ::model::event::Event; use ::model::{ChannelId, Message}; @@ -38,20 +39,23 @@ macro_rules! update { fn context(channel_id: Option<ChannelId>, conn: Arc<Mutex<Shard>>, + data: Arc<Mutex<ShareMap>>, login_type: LoginType) -> Context { - Context::new(channel_id, conn, login_type) + Context::new(channel_id, conn, data, login_type) } #[cfg(feature="framework")] pub fn dispatch(event: Event, conn: Arc<Mutex<Shard>>, framework: Arc<Mutex<Framework>>, + data: Arc<Mutex<ShareMap>>, login_type: LoginType, event_store: Arc<RwLock<EventStore>>) { match event { Event::MessageCreate(event) => { let context = context(Some(event.message.channel_id), conn, + data, login_type); let mut framework = framework.lock().expect("framework poisoned"); @@ -65,7 +69,7 @@ pub fn dispatch(event: Event, dispatch_message(context, event.message, event_store); } }, - other => handle_event(other, conn, login_type, event_store), + other => handle_event(other, conn, data, login_type, event_store), } } @@ -73,17 +77,19 @@ pub fn dispatch(event: Event, pub fn dispatch(event: Event, conn: Arc<Mutex<Shard>>, login_type: LoginType, + data: Arc<Mutex<ShareMap>>, event_store: Arc<RwLock<EventStore>>) { match event { Event::MessageCreate(event) => { let context = context(Some(event.message.channel_id), conn, + data, login_type); dispatch_message(context.clone(), event.message.clone(), event_store); }, - other => handle_event(other, conn, login_type, event_store), + other => handle_event(other, conn, data, login_type, event_store), } } @@ -102,6 +108,7 @@ fn dispatch_message(context: Context, #[allow(cyclomatic_complexity)] fn handle_event(event: Event, conn: Arc<Mutex<Shard>>, + data: Arc<Mutex<ShareMap>>, login_type: LoginType, event_store: Arc<RwLock<EventStore>>) { match event { @@ -109,7 +116,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_call_create, event_store) { update!(update_with_call_create, event); - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -121,7 +128,7 @@ fn handle_event(event: Event, }, Event::CallDelete(event) => { if let Some(ref handler) = handler!(on_call_delete, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -141,7 +148,7 @@ fn handle_event(event: Event, }, Event::CallUpdate(event) => { if let Some(ref handler) = handler!(on_call_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -172,6 +179,7 @@ fn handle_event(event: Event, update!(update_with_channel_create, event); let context = context(Some(event.channel.id()), conn, + data, login_type); let handler = handler.clone(); @@ -185,7 +193,7 @@ fn handle_event(event: 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); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -199,6 +207,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_channel_pins_ack, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -211,6 +220,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_channel_pins_update, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -225,6 +235,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_channel_recipient_addition, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -239,6 +250,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_channel_recipient_removal, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -251,6 +263,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_channel_update, event_store) { let context = context(Some(event.channel.id()), conn, + data, login_type); let handler = handler.clone(); @@ -275,7 +288,7 @@ fn handle_event(event: Event, }, Event::FriendSuggestionCreate(event) => { if let Some(ref handler) = handler!(on_friend_suggestion_create, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -285,7 +298,7 @@ fn handle_event(event: Event, }, Event::FriendSuggestionDelete(event) => { if let Some(ref handler) = handler!(on_friend_suggestion_delete, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -295,7 +308,7 @@ fn handle_event(event: Event, }, Event::GuildBanAdd(event) => { if let Some(ref handler) = handler!(on_guild_ban_addition, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -305,7 +318,7 @@ fn handle_event(event: Event, }, Event::GuildBanRemove(event) => { if let Some(ref handler) = handler!(on_guild_ban_removal, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -317,7 +330,7 @@ fn handle_event(event: Event, update!(update_with_guild_create, event); if let Some(ref handler) = handler!(on_guild_create, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -327,7 +340,7 @@ fn handle_event(event: Event, }, Event::GuildDelete(event) => { if let Some(ref handler) = handler!(on_guild_delete, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -351,7 +364,7 @@ fn handle_event(event: Event, update!(update_with_guild_emojis_update, event); if let Some(ref handler) = handler!(on_guild_emojis_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -361,7 +374,7 @@ fn handle_event(event: Event, }, Event::GuildIntegrationsUpdate(event) => { if let Some(ref handler) = handler!(on_guild_integrations_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -373,7 +386,7 @@ fn handle_event(event: Event, update!(update_with_guild_member_add, event); if let Some(ref handler) = handler!(on_guild_member_addition, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -383,7 +396,7 @@ fn handle_event(event: Event, }, Event::GuildMemberRemove(event) => { if let Some(ref handler) = handler!(on_guild_member_removal, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -405,7 +418,7 @@ fn handle_event(event: Event, }, Event::GuildMemberUpdate(event) => { if let Some(ref handler) = handler!(on_guild_member_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -436,7 +449,7 @@ fn handle_event(event: Event, update!(update_with_guild_members_chunk, event); if let Some(ref handler) = handler!(on_guild_members_chunk, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -448,7 +461,7 @@ fn handle_event(event: Event, update!(update_with_guild_role_create, event); if let Some(ref handler) = handler!(on_guild_role_create, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -458,7 +471,7 @@ fn handle_event(event: Event, }, Event::GuildRoleDelete(event) => { if let Some(ref handler) = handler!(on_guild_role_delete, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -480,7 +493,7 @@ fn handle_event(event: Event, }, Event::GuildRoleUpdate(event) => { if let Some(ref handler) = handler!(on_guild_role_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -502,7 +515,7 @@ fn handle_event(event: Event, }, Event::GuildSync(event) => { if let Some(ref handler) = handler!(on_guild_sync, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -514,7 +527,7 @@ fn handle_event(event: Event, update!(update_with_guild_unavailable, event); if let Some(ref handler) = handler!(on_guild_unavailable, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -524,7 +537,7 @@ fn handle_event(event: Event, }, Event::GuildUpdate(event) => { if let Some(ref handler) = handler!(on_guild_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -551,6 +564,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_message_ack, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -565,6 +579,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_message_delete_bulk, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -577,6 +592,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_message_delete, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -589,6 +605,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_message_update, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -601,7 +618,7 @@ fn handle_event(event: Event, update!(update_with_presences_replace, event); if let Some(handler) = handler!(on_presence_replace, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -613,7 +630,7 @@ fn handle_event(event: Event, update!(update_with_presence_update, event); if let Some(handler) = handler!(on_presence_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -625,6 +642,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_reaction_add, event_store) { let context = context(Some(event.reaction.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -637,6 +655,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_reaction_remove, event_store) { let context = context(Some(event.reaction.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -649,6 +668,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_reaction_remove_all, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -661,7 +681,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_ready, event_store) { update!(update_with_ready, event); - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -675,7 +695,7 @@ fn handle_event(event: Event, update!(update_with_relationship_add, event); if let Some(ref handler) = handler!(on_relationship_addition, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -687,7 +707,7 @@ fn handle_event(event: Event, update!(update_with_relationship_remove, event); if let Some(ref handler) = handler!(on_relationship_removal, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -697,7 +717,7 @@ fn handle_event(event: Event, }, Event::Resumed(event) => { if let Some(ref handler) = handler!(on_resume, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -709,6 +729,7 @@ fn handle_event(event: Event, if let Some(ref handler) = handler!(on_typing_start, event_store) { let context = context(Some(event.channel_id), conn, + data, login_type); let handler = handler.clone(); @@ -719,7 +740,7 @@ fn handle_event(event: Event, }, Event::Unknown(event) => { if let Some(ref handler) = handler!(on_unknown, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -729,7 +750,7 @@ fn handle_event(event: 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 context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -751,7 +772,7 @@ fn handle_event(event: Event, }, Event::UserNoteUpdate(event) => { if let Some(ref handler) = handler!(on_note_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -773,7 +794,7 @@ fn handle_event(event: Event, }, Event::UserSettingsUpdate(event) => { if let Some(ref handler) = handler!(on_user_settings_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -796,7 +817,7 @@ fn handle_event(event: Event, }, Event::UserUpdate(event) => { if let Some(ref handler) = handler!(on_user_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); feature_cache! {{ @@ -818,7 +839,7 @@ fn handle_event(event: Event, }, Event::VoiceServerUpdate(event) => { if let Some(ref handler) = handler!(on_voice_server_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -830,7 +851,7 @@ fn handle_event(event: Event, update!(update_with_voice_state_update, event); if let Some(ref handler) = handler!(on_voice_state_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { @@ -840,7 +861,7 @@ fn handle_event(event: Event, }, Event::WebhookUpdate(event) => { if let Some(ref handler) = handler!(on_webhook_update, event_store) { - let context = context(None, conn, login_type); + let context = context(None, conn, data, login_type); let handler = handler.clone(); thread::spawn(move || { diff --git a/src/client/mod.rs b/src/client/mod.rs index 0369677..cf67b5b 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -42,6 +42,7 @@ use std::collections::{BTreeMap, HashMap}; use std::sync::{Arc, Mutex, RwLock}; use std::thread; use std::time::Duration; +use typemap::ShareMap; use websocket::client::Receiver; use websocket::stream::WebSocketStream; use ::internal::prelude::{Error, Result, Value}; @@ -150,6 +151,23 @@ lazy_static! { /// [`Event::MessageCreate`]: ../model/event/enum.Event.html#variant.MessageCreate /// [sharding docs]: gateway/index.html#sharding pub struct Client { + /// A ShareMap which requires types to be Send + Sync. This is a map that + /// can be safely shared across contexts. + /// + /// The purpose of the data field is to be accessible and persistent across + /// contexts; that is, data can be modified by one context, and will persist + /// through the future and be accessible through other contexts. This is + /// useful for anything that should "live" through the program: counters, + /// database connections, custom user caches, etc. + /// + /// In the meaning of a context, this data can be accessed through + /// [`Context::data`]. + /// + /// Refer to [example 06] for an example on using the `data` field. + /// + /// [`Context::data`]: struct.Context.html#method.data + /// [example 06]: https://github.com/zeyla/serenity.rs/tree/master/examples/06_command_framework + pub data: Arc<Mutex<ShareMap>>, /// A vector of all active shards that have received their [`Event::Ready`] /// payload, and have dispatched to [`on_ready`] if an event handler was /// configured. @@ -773,18 +791,21 @@ impl Client { dispatch(Event::Ready(ready), shard.clone(), self.framework.clone(), + self.data.clone(), self.login_type, self.event_store.clone()); } else { dispatch(Event::Ready(ready), shard.clone(), + self.data.clone(), self.login_type, self.event_store.clone()); }} - let shard_clone = shard.clone(); + let data_clone = self.data.clone(); let event_store = self.event_store.clone(); let login_type = self.login_type; + let shard_clone = shard.clone(); feature_framework! {{ let framework = self.framework.clone(); @@ -792,6 +813,7 @@ impl Client { thread::spawn(move || { handle_shard(shard_clone, framework, + data_clone, login_type, event_store, receiver) @@ -799,6 +821,7 @@ impl Client { } else { thread::spawn(move || { handle_shard(shard_clone, + data_clone, login_type, event_store, receiver) @@ -1125,6 +1148,7 @@ impl Client { #[cfg(feature="framework")] fn handle_shard(shard: Arc<Mutex<Shard>>, framework: Arc<Mutex<Framework>>, + data: Arc<Mutex<ShareMap>>, login_type: LoginType, event_store: Arc<RwLock<EventStore>>, mut receiver: Receiver<WebSocketStream>) { @@ -1146,6 +1170,7 @@ fn handle_shard(shard: Arc<Mutex<Shard>>, dispatch(event, shard.clone(), framework.clone(), + data.clone(), login_type, event_store.clone()); } @@ -1153,6 +1178,7 @@ fn handle_shard(shard: Arc<Mutex<Shard>>, #[cfg(not(feature="framework"))] fn handle_shard(shard: Arc<Mutex<Shard>>, + data: Arc<Mutex<ShareMap>>, login_type: LoginType, event_store: Arc<RwLock<EventStore>>, mut receiver: Receiver<WebSocketStream>) { @@ -1173,6 +1199,7 @@ fn handle_shard(shard: Arc<Mutex<Shard>>, dispatch(event, shard.clone(), + data.clone(), login_type, event_store.clone()); } @@ -1185,17 +1212,19 @@ fn login(token: &str, login_type: LoginType) -> Client { feature_framework! {{ Client { - shards: Vec::default(), + data: Arc::new(Mutex::new(ShareMap::custom())), event_store: Arc::new(RwLock::new(EventStore::default())), framework: Arc::new(Mutex::new(Framework::default())), login_type: login_type, + shards: Vec::default(), token: token.to_owned(), } } else { Client { - shards: Vec::default(), + data: Arc::new(Mutex::new(ShareMap::custom())), event_store: Arc::new(RwLock::new(EventStore::default())), login_type: login_type, + shards: Vec::default(), token: token.to_owned(), } }} @@ -145,6 +145,7 @@ extern crate hyper; extern crate multipart; extern crate serde_json; extern crate time; +extern crate typemap; extern crate websocket; #[cfg(feature="voice")] |