use crate::{
client::{
ButtplugClientError,
ButtplugClientMessageFuturePair,
ButtplugServerMessageStateShared,
},
core::message::{ButtplugCurrentSpecServerMessage, ButtplugMessage, ButtplugMessageValidator},
};
use dashmap::DashMap;
use std::sync::{
atomic::{AtomicU32, Ordering},
Arc,
};
pub struct ClientMessageSorter {
future_map: DashMap<u32, ButtplugServerMessageStateShared>,
current_id: Arc<AtomicU32>,
}
impl ClientMessageSorter {
pub fn register_future(&self, msg_fut: &mut ButtplugClientMessageFuturePair) {
let id = self.current_id.load(Ordering::SeqCst);
trace!("Setting message id to {}", id);
msg_fut.msg.set_id(id);
self.future_map.insert(id, msg_fut.waker.clone());
self.current_id.store(id + 1, Ordering::SeqCst);
}
pub fn maybe_resolve_result(&self, msg: &ButtplugCurrentSpecServerMessage) -> bool {
let id = msg.id();
trace!("Trying to resolve message future for id {}.", id);
match self.future_map.remove(&id) {
Some((_, state)) => {
trace!("Resolved id {} to a future.", id);
if let Err(e) = msg.is_valid() {
error!("Message not valid: {:?} - Error: {}", msg, e);
state.set_reply(Err(ButtplugClientError::ButtplugError(e.into())));
} else if let ButtplugCurrentSpecServerMessage::Error(e) = msg {
state.set_reply(Err(e.original_error().into()))
} else {
state.set_reply(Ok(msg.clone()))
}
true
}
None => {
trace!("Message id {} not found, considering it an event.", id);
false
}
}
}
}
impl Default for ClientMessageSorter {
fn default() -> Self {
Self {
future_map: DashMap::new(),
current_id: Arc::new(AtomicU32::new(1)),
}
}
}