dittolive_ditto/presence/
observer.rsuse_prelude!();
use std::hash::Hash;
use ffi_sdk::{FfiDynPresenceCallback, FfiPresenceObserver};
use uuid::Uuid;
use crate::error::Result;
trait_alias! {
pub trait PresenceCallback = FnMut(&PresenceGraph) + Send + Sync + 'static
}
pub struct PresenceObserver {
pub(crate) handle: repr_c::Box<FfiPresenceObserver>,
}
impl PresenceObserver {
pub(crate) fn new<F>(ditto: &ffi_sdk::BoxedDitto, mut observer: F) -> Result<PresenceObserver>
where
F: PresenceCallback,
{
let ffi_callback: repr_c::Box<FfiDynPresenceCallback> = {
fn make_callback<F>(f: F) -> repr_c::Box<FfiDynPresenceCallback>
where
F: 'static + Send + FnMut(c_slice::Box<u8>),
{
Box::new(f).into()
}
make_callback(move |graph: c_slice::Box<u8>| {
let graph =
serde_json::from_slice(&graph).expect("should deserialize presence graph");
observer(&graph);
})
};
let handle = ffi_sdk::dittoffi_presence_register_observer_throws(ditto, ffi_callback)
.into_rust_result()?;
Ok(Self { handle })
}
pub fn cancel(&self) {
ffi_sdk::dittoffi_presence_observer_cancel(&self.handle);
}
pub fn is_cancelled(&self) -> bool {
ffi_sdk::dittoffi_presence_observer_is_cancelled(&self.handle)
}
fn id(&self) -> Uuid {
let buffer = ffi_sdk::dittoffi_presence_observer_id(&self.handle);
Uuid::from_slice(buffer.as_slice()).expect("bug: expected valid UUID")
}
}
impl Eq for PresenceObserver {}
impl PartialEq for PresenceObserver {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl Hash for PresenceObserver {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.id().hash(state);
}
}