use super::{ButtplugClientError, ButtplugClientMessageFuturePair, ButtplugServerMessageSender};
use buttplug_core::message::{ButtplugMessage, ButtplugMessageValidator, ButtplugServerMessageV4};
use dashmap::DashMap;
use log::*;
use std::sync::{
Arc,
atomic::{AtomicU32, Ordering},
};
pub struct ClientMessageSorter {
future_map: DashMap<u32, ButtplugServerMessageSender>,
current_id: Arc<AtomicU32>,
}
impl ClientMessageSorter {
pub fn register_future(&self, msg_fut: &mut ButtplugClientMessageFuturePair) {
let id = self.current_id.load(Ordering::Relaxed);
trace!("Setting message id to {}", id);
msg_fut.msg.set_id(id);
if let Some(sender) = msg_fut.sender.take() {
self.future_map.insert(id, sender);
}
self.current_id.store(id + 1, Ordering::Relaxed);
}
pub fn maybe_resolve_result(&self, msg: &ButtplugServerMessageV4) -> bool {
trace!("{:?}", msg);
let id = msg.id();
trace!("Trying to resolve message future for id {}.", id);
match self.future_map.remove(&id) {
Some((_, sender)) => {
trace!("Resolved id {} to a future.", id);
if let Err(e) = msg.is_valid() {
error!("Message not valid: {:?} - Error: {}", msg, e);
let _ = sender.send(Err(ButtplugClientError::ButtplugError(e.into())));
} else if let ButtplugServerMessageV4::Error(e) = msg {
let _ = sender.send(Err(e.original_error().into()));
} else {
let _ = sender.send(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)),
}
}
}