Replace hashmaps with dashmaps

Signed-off-by: trivernis <trivernis@protonmail.com>
main
trivernis 3 years ago
parent 9d75afc8c1
commit 5818aa3133
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

119
Cargo.lock generated

@ -153,6 +153,17 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "dashmap"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8858831f7781322e539ea39e72449c46b059638250c14344fec8d0aa6e539c"
dependencies = [
"cfg-if",
"num_cpus",
"parking_lot",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.9.0" version = "0.9.0"
@ -358,6 +369,15 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "http" name = "http"
version = "0.2.6" version = "0.2.6"
@ -514,6 +534,16 @@ version = "0.2.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259"
[[package]]
name = "lock_api"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.16" version = "0.4.16"
@ -630,6 +660,16 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.10.0" version = "1.10.0"
@ -675,6 +715,29 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "parking_lot"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "995f667a6c822200b0433ac218e05582f0e2efa1b922a3fd2fbaadc5f87bab37"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
]
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.1.0" version = "2.1.0"
@ -910,6 +973,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "sct" name = "sct"
version = "0.6.1" version = "0.6.1"
@ -1024,6 +1093,7 @@ dependencies = [
name = "serenity-rich-interaction" name = "serenity-rich-interaction"
version = "0.2.6" version = "0.2.6"
dependencies = [ dependencies = [
"dashmap",
"futures", "futures",
"serde_json", "serde_json",
"serenity", "serenity",
@ -1051,6 +1121,12 @@ version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
[[package]]
name = "smallvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.4" version = "0.4.4"
@ -1515,6 +1591,49 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5acdd78cb4ba54c0045ac14f62d8f94a03d10047904ae2a40afa1e99d8f70825"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d"
[[package]]
name = "windows_i686_gnu"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed"
[[package]]
name = "windows_i686_msvc"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956"
[[package]]
name = "windows_x86_64_gnu"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4"
[[package]]
name = "windows_x86_64_msvc"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9"
[[package]] [[package]]
name = "winreg" name = "winreg"
version = "0.10.1" version = "0.10.1"

@ -21,6 +21,7 @@ thiserror = "1.0.30"
tracing= "0.1.33" tracing= "0.1.33"
futures = "0.3.21" futures = "0.3.21"
serde_json = "1.0.79" serde_json = "1.0.79"
dashmap = "5.2.0"
[dependencies.serenity] [dependencies.serenity]
version = "0.10.10" version = "0.10.10"

@ -2,14 +2,14 @@ use crate::error::Result;
use crate::events::RichEventHandler; use crate::events::RichEventHandler;
use crate::menu::traits::EventDrivenMessage; use crate::menu::traits::EventDrivenMessage;
use crate::menu::EventDrivenMessageContainer; use crate::menu::EventDrivenMessageContainer;
use dashmap::DashMap;
use serenity::client::ClientBuilder; use serenity::client::ClientBuilder;
use serenity::http::Http; use serenity::http::Http;
use serenity::model::channel::Message; use serenity::model::channel::Message;
use serenity::model::id::{ChannelId, MessageId}; use serenity::model::id::{ChannelId, MessageId};
use std::collections::HashMap; use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tokio::sync::Mutex;
pub static SHORT_TIMEOUT: Duration = Duration::from_secs(5); pub static SHORT_TIMEOUT: Duration = Duration::from_secs(5);
pub static MEDIUM_TIMEOUT: Duration = Duration::from_secs(20); pub static MEDIUM_TIMEOUT: Duration = Duration::from_secs(20);
@ -18,6 +18,28 @@ pub static EXTRA_LONG_TIMEOUT: Duration = Duration::from_secs(600);
pub type BoxedEventDrivenMessage = Box<dyn EventDrivenMessage>; pub type BoxedEventDrivenMessage = Box<dyn EventDrivenMessage>;
pub struct BoxedMessage(pub BoxedEventDrivenMessage);
impl<T: EventDrivenMessage + 'static> From<Box<T>> for BoxedMessage {
fn from(m: Box<T>) -> Self {
Self(m as Box<dyn EventDrivenMessage>)
}
}
impl Deref for BoxedMessage {
type Target = BoxedEventDrivenMessage;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for BoxedMessage {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct MessageHandle { pub struct MessageHandle {
pub channel_id: u64, pub channel_id: u64,
@ -61,7 +83,7 @@ impl<'a> RegisterRichInteractions for ClientBuilder<'a> {
/// Registers the rich interactions with a custom rich event handler /// Registers the rich interactions with a custom rich event handler
fn register_rich_interactions_with(self, rich_handler: RichEventHandler) -> Self { fn register_rich_interactions_with(self, rich_handler: RichEventHandler) -> Self {
self.type_map_insert::<EventDrivenMessageContainer>(Arc::new(Mutex::new(HashMap::new()))) self.type_map_insert::<EventDrivenMessageContainer>(Arc::new(DashMap::new()))
.raw_event_handler(rich_handler) .raw_event_handler(rich_handler)
} }
} }

@ -11,6 +11,9 @@ pub enum Error {
#[error("Serenity Rich Interaction is not fully initialized")] #[error("Serenity Rich Interaction is not fully initialized")]
Uninitialized, Uninitialized,
#[error("the cache is not available, therefore some required data is missing")]
NoCache,
#[error("{0}")] #[error("{0}")]
Msg(String), Msg(String),
} }

@ -1,5 +1,5 @@
use crate::core::MessageHandle; use crate::core::MessageHandle;
use crate::menu::{get_listeners_from_context, MessageRef}; use crate::menu::get_listeners_from_context;
use crate::Result; use crate::Result;
use serenity::client::Context; use serenity::client::Context;
use serenity::model::channel::Reaction; use serenity::model::channel::Reaction;
@ -21,30 +21,19 @@ pub async fn start_update_loop(ctx: &Context) -> Result<()> {
loop { loop {
{ {
tracing::debug!("Updating messages..."); tracing::debug!("Updating messages...");
let messages = {
let msgs_lock = event_messages.lock().await;
msgs_lock
.iter()
.map(|(k, v)| (*k, v.clone()))
.collect::<Vec<(MessageHandle, MessageRef)>>()
};
let mut frozen_messages = Vec::new(); let mut frozen_messages = Vec::new();
for (key, msg) in messages { for entry in event_messages.iter() {
let mut msg = msg.lock().await; let mut msg = entry.value().lock().await;
if let Err(e) = msg.update(&http).await { if let Err(e) = msg.update(&http).await {
tracing::error!("Failed to update message: {:?}", e); tracing::error!("Failed to update message: {:?}", e);
} }
if msg.is_frozen() { if msg.is_frozen() {
frozen_messages.push(key); frozen_messages.push(*entry.key());
} }
} }
{
let mut msgs_lock = event_messages.lock().await;
for key in frozen_messages { for key in frozen_messages {
msgs_lock.remove(&key); event_messages.remove(&key);
}
} }
tracing::debug!("Messages updated"); tracing::debug!("Messages updated");
} }
@ -63,16 +52,14 @@ pub async fn handle_message_delete(
message_id: MessageId, message_id: MessageId,
) -> Result<()> { ) -> Result<()> {
let mut affected_messages = Vec::new(); let mut affected_messages = Vec::new();
{
let listeners = get_listeners_from_context(ctx).await?; let listeners = get_listeners_from_context(ctx).await?;
let mut listeners_lock = listeners.lock().await;
let handle = MessageHandle::new(channel_id, message_id); let handle = MessageHandle::new(channel_id, message_id);
if let Some(msg) = listeners_lock.get(&handle) {
affected_messages.push(Arc::clone(msg)); if let Some(msg) = listeners.get(&handle) {
listeners_lock.remove(&handle); affected_messages.push(msg.value().clone());
} listeners.remove(&handle);
} }
for msg in affected_messages { for msg in affected_messages {
let mut msg = msg.lock().await; let mut msg = msg.lock().await;
msg.on_deleted(ctx).await?; msg.on_deleted(ctx).await?;
@ -89,18 +76,17 @@ pub async fn handle_message_delete_bulk(
message_ids: &Vec<MessageId>, message_ids: &Vec<MessageId>,
) -> Result<()> { ) -> Result<()> {
let mut affected_messages = Vec::new(); let mut affected_messages = Vec::new();
{
let listeners = get_listeners_from_context(ctx).await?; let listeners = get_listeners_from_context(ctx).await?;
let mut listeners_lock = listeners.lock().await;
for message_id in message_ids { for message_id in message_ids {
let handle = MessageHandle::new(channel_id, *message_id); let handle = MessageHandle::new(channel_id, *message_id);
if let Some(msg) = listeners_lock.get_mut(&handle) { if let Some(msg) = listeners.get(&handle) {
affected_messages.push(Arc::clone(msg)); affected_messages.push(msg.value().clone());
listeners_lock.remove(&handle); listeners.remove(&handle);
}
} }
} }
for msg in affected_messages { for msg in affected_messages {
let mut msg = msg.lock().await; let mut msg = msg.lock().await;
msg.on_deleted(ctx).await?; msg.on_deleted(ctx).await?;
@ -112,17 +98,14 @@ pub async fn handle_message_delete_bulk(
/// Fired when a reaction was added to a message /// Fired when a reaction was added to a message
#[tracing::instrument(level = "debug", skip(ctx))] #[tracing::instrument(level = "debug", skip(ctx))]
pub async fn handle_reaction_add(ctx: &Context, reaction: &Reaction) -> Result<()> { pub async fn handle_reaction_add(ctx: &Context, reaction: &Reaction) -> Result<()> {
let mut affected_messages = Vec::new();
{
let listeners = get_listeners_from_context(ctx).await?; let listeners = get_listeners_from_context(ctx).await?;
let mut listeners_lock = listeners.lock().await;
let handle = MessageHandle::new(reaction.channel_id, reaction.message_id); let handle = MessageHandle::new(reaction.channel_id, reaction.message_id);
if let Some(msg) = listeners_lock.get_mut(&handle) { let mut affected_messages = Vec::new();
affected_messages.push(Arc::clone(&msg)); if let Some(msg) = listeners.get(&handle) {
} affected_messages.push(msg.value().clone());
} }
for msg in affected_messages { for msg in affected_messages {
let mut msg = msg.lock().await; let mut msg = msg.lock().await;
msg.on_reaction_add(ctx, reaction.clone()).await?; msg.on_reaction_add(ctx, reaction.clone()).await?;
@ -134,17 +117,14 @@ pub async fn handle_reaction_add(ctx: &Context, reaction: &Reaction) -> Result<(
/// Fired when a reaction was added to a message /// Fired when a reaction was added to a message
#[tracing::instrument(level = "debug", skip(ctx))] #[tracing::instrument(level = "debug", skip(ctx))]
pub async fn handle_reaction_remove(ctx: &Context, reaction: &Reaction) -> Result<()> { pub async fn handle_reaction_remove(ctx: &Context, reaction: &Reaction) -> Result<()> {
let mut affected_messages = Vec::new();
{
let listeners = get_listeners_from_context(ctx).await?; let listeners = get_listeners_from_context(ctx).await?;
let mut listeners_lock = listeners.lock().await;
let handle = MessageHandle::new(reaction.channel_id, reaction.message_id); let handle = MessageHandle::new(reaction.channel_id, reaction.message_id);
if let Some(msg) = listeners_lock.get_mut(&handle) { let mut affected_messages = Vec::new();
affected_messages.push(Arc::clone(&msg)); if let Some(msg) = listeners.get(&handle) {
} affected_messages.push(msg.value().clone());
} }
for msg in affected_messages { for msg in affected_messages {
let mut msg = msg.lock().await; let mut msg = msg.lock().await;
msg.on_reaction_remove(ctx, reaction.clone()).await?; msg.on_reaction_remove(ctx, reaction.clone()).await?;

@ -1,5 +1,6 @@
use crate::events::event_callbacks; use crate::events::event_callbacks;
use crate::Result; use crate::Result;
use futures::future;
use serenity::async_trait; use serenity::async_trait;
use serenity::client::{Context, RawEventHandler}; use serenity::client::{Context, RawEventHandler};
use serenity::model::event; use serenity::model::event;
@ -51,21 +52,19 @@ impl RichEventHandler {
/// Handles a generic event /// Handles a generic event
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn handle_event<T: 'static + Send + Sync>(&self, ctx: Context, value: T) { async fn handle_event<T: 'static + Send + Sync>(&self, ctx: Context, value: T) {
let callbacks = self.callbacks.clone();
tokio::spawn(async move {
let value = value; let value = value;
if let Some(callbacks) = callbacks.get(&TypeId::of::<T>()) { if let Some(callbacks) = self.callbacks.get(&TypeId::of::<T>()) {
for callback in callbacks { let futures = callbacks
if let Some(cb) = callback.downcast_ref::<EventCallback<T>>() { .iter()
if let Err(e) = cb.run(&ctx, &value).await { .filter_map(|cb| cb.downcast_ref::<EventCallback<T>>())
tracing::error!("Error in event callback: {:?}", e); .map(|cb| cb.run(&ctx, &value));
} future::join_all(futures)
} .await
.into_iter()
.filter_map(Result::err)
.for_each(|e| tracing::error!("Error in event callback: {:?}", e));
} }
} }
});
}
pub fn add_event<T: 'static, F: 'static>(&mut self, cb: F) -> &mut Self pub fn add_event<T: 'static, F: 'static>(&mut self, cb: F) -> &mut Self
where where

@ -1,16 +1,16 @@
use crate::core::{BoxedEventDrivenMessage, MessageHandle}; use crate::core::{BoxedMessage, MessageHandle};
use crate::Error; use crate::Error;
use crate::Result; use crate::Result;
use dashmap::DashMap;
use serenity::client::Context; use serenity::client::Context;
use serenity::prelude::TypeMapKey; use serenity::prelude::TypeMapKey;
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
/// Container to store event driven messages in the serenity context data /// Container to store event driven messages in the serenity context data
pub struct EventDrivenMessageContainer; pub struct EventDrivenMessageContainer;
pub type MessageRef = Arc<Mutex<BoxedEventDrivenMessage>>; pub type MessageRef = Arc<Mutex<BoxedMessage>>;
pub type EventDrivenMessagesRef = Arc<Mutex<HashMap<MessageHandle, MessageRef>>>; pub type EventDrivenMessagesRef = Arc<DashMap<MessageHandle, MessageRef>>;
impl TypeMapKey for EventDrivenMessageContainer { impl TypeMapKey for EventDrivenMessageContainer {
type Value = EventDrivenMessagesRef; type Value = EventDrivenMessagesRef;

@ -35,10 +35,9 @@ pub async fn previous_page(ctx: &Context, menu: &mut Menu<'_>, _: Reaction) -> R
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
pub async fn close_menu(ctx: &Context, menu: &mut Menu<'_>, _: Reaction) -> Result<()> { pub async fn close_menu(ctx: &Context, menu: &mut Menu<'_>, _: Reaction) -> Result<()> {
menu.close(ctx.http()).await?; menu.close(ctx.http()).await?;
let listeners = get_listeners_from_context(&ctx).await?;
let mut listeners_lock = listeners.lock().await;
let message = menu.message.read().await; let message = menu.message.read().await;
listeners_lock.remove(&*message); let listeners = get_listeners_from_context(&ctx).await?;
listeners.remove(&*message);
Ok(()) Ok(())
} }

@ -66,20 +66,27 @@ impl ActionContainer {
/// A menu message /// A menu message
pub struct Menu<'a> { pub struct Menu<'a> {
pub message: Arc<RwLock<MessageHandle>>, pub(crate) message: Arc<RwLock<MessageHandle>>,
pub pages: Vec<Page<'a>>, pub pages: Vec<Page<'a>>,
pub current_page: usize, pub current_page: usize,
pub controls: HashMap<String, ActionContainer>, pub(crate) controls: HashMap<String, ActionContainer>,
pub timeout: Instant, pub timeout: Instant,
pub sticky: bool, pub sticky: bool,
pub data: TypeMap, pub data: TypeMap,
pub help_entries: HashMap<String, String>, pub(crate) help_entries: HashMap<String, String>,
owner: Option<UserId>, owner: Option<UserId>,
closed: bool, closed: bool,
listeners: EventDrivenMessagesRef, listeners: EventDrivenMessagesRef,
} }
impl Menu<'_> { impl<'a> Menu<'a> {
/// Returns the current page of the menu
pub fn get_current_page(&self) -> Result<&Page<'a>> {
self.pages
.get(self.current_page)
.ok_or(Error::PageNotFound(self.current_page))
}
/// Removes all reactions from the menu /// Removes all reactions from the menu
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
pub(crate) async fn close(&mut self, http: &Http) -> Result<()> { pub(crate) async fn close(&mut self, http: &Http) -> Result<()> {
@ -107,13 +114,7 @@ impl Menu<'_> {
let handle = self.message.read().await; let handle = self.message.read().await;
(*handle).clone() (*handle).clone()
}; };
let current_page = self let current_page = self.get_current_page()?.get().await?;
.pages
.get(self.current_page)
.cloned()
.ok_or(Error::PageNotFound(self.current_page))?
.get()
.await?;
let message = http let message = http
.send_message( .send_message(
@ -121,18 +122,12 @@ impl Menu<'_> {
&serde_json::to_value(current_page.0).unwrap(), &serde_json::to_value(current_page.0).unwrap(),
) )
.await?; .await?;
let mut controls = self
.controls
.clone()
.into_iter()
.collect::<Vec<(String, ActionContainer)>>();
controls.sort_by_key(|(_, a)| a.position);
for emoji in controls.into_iter().map(|(e, _)| e) { for control in &self.controls {
http.create_reaction( http.create_reaction(
message.channel_id.0, message.channel_id.0,
message.id.0, message.id.0,
&ReactionType::Unicode(emoji.clone()), &ReactionType::Unicode(control.0.clone()),
) )
.await?; .await?;
} }
@ -144,9 +139,8 @@ impl Menu<'_> {
}; };
{ {
tracing::debug!("Changing key of message"); tracing::debug!("Changing key of message");
let mut listeners_lock = self.listeners.lock().await; let menu = self.listeners.remove(&old_handle).unwrap();
let menu = listeners_lock.remove(&old_handle).unwrap(); self.listeners.insert(new_handle, menu.1);
listeners_lock.insert(new_handle, menu);
} }
tracing::debug!("Deleting original message"); tracing::debug!("Deleting original message");
http.delete_message(old_handle.channel_id, old_handle.message_id) http.delete_message(old_handle.channel_id, old_handle.message_id)
@ -165,16 +159,17 @@ impl<'a> EventDrivenMessage for Menu<'a> {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn update(&mut self, http: &Http) -> Result<()> { async fn update(&mut self, http: &Http) -> Result<()> {
tracing::trace!("Checking for menu timeout"); tracing::trace!("Checking for menu timeout");
if Instant::now() >= self.timeout { if Instant::now() >= self.timeout {
tracing::debug!("Menu timout reached. Closing menu."); tracing::debug!("Menu timout reached. Closing menu.");
self.close(http).await?; self.close(http).await?;
} else if self.sticky { } else if self.sticky {
tracing::debug!("Message is sticky. Checking for new messages in channel..."); tracing::debug!("Message is sticky. Checking for new messages in channel...");
let handle = { let handle = {
let handle = self.message.read().await; let handle = self.message.read().await;
(*handle).clone() (*handle).clone()
}; };
let channel_id = ChannelId(handle.channel_id); let channel_id = ChannelId(handle.channel_id);
let messages = channel_id let messages = channel_id
.messages(http, |p| p.after(handle.message_id).limit(1)) .messages(http, |p| p.after(handle.message_id).limit(1))
@ -191,8 +186,9 @@ impl<'a> EventDrivenMessage for Menu<'a> {
#[tracing::instrument(level = "debug", skip_all)] #[tracing::instrument(level = "debug", skip_all)]
async fn on_reaction_add(&mut self, ctx: &Context, reaction: Reaction) -> Result<()> { async fn on_reaction_add(&mut self, ctx: &Context, reaction: Reaction) -> Result<()> {
let current_user = ctx.http.get_current_user().await?; let current_user = ctx.http.get_current_user().await?;
let reaction_user_id = reaction.user_id.ok_or_else(|| Error::NoCache)?;
if reaction.user_id.unwrap().0 == current_user.id.0 { if reaction_user_id.0 == current_user.id.0 {
tracing::debug!("Reaction is from current user."); tracing::debug!("Reaction is from current user.");
return Ok(()); return Ok(());
} }
@ -200,8 +196,9 @@ impl<'a> EventDrivenMessage for Menu<'a> {
tracing::debug!("Deleting user reaction."); tracing::debug!("Deleting user reaction.");
reaction.delete(ctx).await?; reaction.delete(ctx).await?;
if let Some(owner) = self.owner { if let Some(owner) = self.owner {
if owner != reaction.user_id.unwrap() { if owner != reaction_user_id {
tracing::debug!( tracing::debug!(
"Menu has an owner and the reaction is not from the owner of the menu" "Menu has an owner and the reaction is not from the owner of the menu"
); );
@ -403,7 +400,7 @@ impl MenuBuilder {
.await?; .await?;
let message = channel_id.send_message(ctx, |_| &mut current_page).await?; let message = channel_id.send_message(ctx, |_| &mut current_page).await?;
let listeners = get_listeners_from_context(ctx).await?;
tracing::debug!("Sorting controls..."); tracing::debug!("Sorting controls...");
let mut controls = self let mut controls = self
.controls .controls
@ -415,6 +412,7 @@ impl MenuBuilder {
tracing::debug!("Creating menu..."); tracing::debug!("Creating menu...");
let message_handle = MessageHandle::new(message.channel_id, message.id); let message_handle = MessageHandle::new(message.channel_id, message.id);
let handle_lock = Arc::new(RwLock::new(message_handle)); let handle_lock = Arc::new(RwLock::new(message_handle));
let listeners = get_listeners_from_context(ctx).await?;
let menu = Menu { let menu = Menu {
message: Arc::clone(&handle_lock), message: Arc::clone(&handle_lock),
@ -431,11 +429,7 @@ impl MenuBuilder {
}; };
tracing::debug!("Storing menu to listeners..."); tracing::debug!("Storing menu to listeners...");
{ listeners.insert(message_handle, Arc::new(Mutex::new(Box::new(menu).into())));
let mut listeners_lock = listeners.lock().await;
tracing::trace!("Listeners locked.");
listeners_lock.insert(message_handle, Arc::new(Mutex::new(Box::new(menu))));
}
tracing::debug!("Adding controls..."); tracing::debug!("Adding controls...");
for (emoji, _) in controls { for (emoji, _) in controls {

Loading…
Cancel
Save