|
|
|
@ -19,6 +19,7 @@ use std::collections::{BTreeMap};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages");
|
|
|
|
|
id_type!(BroadcastID; "Each broadcast message has a unique ID.");
|
|
|
|
|
|
|
|
|
|
/// Signal the shutdown method to the supervisor.
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
|
|
|
|
@ -82,11 +83,13 @@ pub(super) struct Supervisor
|
|
|
|
|
///
|
|
|
|
|
/// These objects can be cloned and downcasted, becaause they are atomically refcounted if that is more desireable.
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
#[repr(transparent)]
|
|
|
|
|
pub struct ServiceEventObject(Arc<dyn Any + Send + Sync + 'static>);
|
|
|
|
|
shim_debug!(ServiceEventObject);
|
|
|
|
|
|
|
|
|
|
/// A weak reference to a `ServiceEventObject`.
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
#[repr(transparent)]
|
|
|
|
|
pub struct ServiceEventObjectRef(Weak<dyn Any + Send + Sync + 'static>);
|
|
|
|
|
shim_debug!(ServiceEventObjectRef);
|
|
|
|
|
|
|
|
|
@ -110,11 +113,21 @@ impl ServiceEventObjectRef
|
|
|
|
|
None => Err(self),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Check if the object has not been destroyed yet.
|
|
|
|
|
pub fn is_alive(&self) -> bool
|
|
|
|
|
{
|
|
|
|
|
self.0.strong_count() > 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl ServiceEventObject
|
|
|
|
|
{
|
|
|
|
|
pub fn clone_inner(&self) -> Self
|
|
|
|
|
{
|
|
|
|
|
Self(Arc::from(self.0.clone_dyn_any_sync()))
|
|
|
|
|
}
|
|
|
|
|
/// Get a weak reference counted handle to the object, without cloning the object itself.
|
|
|
|
|
pub fn clone_weak(&self) -> ServiceEventObjectRef
|
|
|
|
|
{
|
|
|
|
@ -125,7 +138,7 @@ impl ServiceEventObject
|
|
|
|
|
///
|
|
|
|
|
/// This will fail if:
|
|
|
|
|
/// * The downcasted type is invalid
|
|
|
|
|
#[inline] pub fn downcast_clone<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<T>
|
|
|
|
|
#[inline] pub fn downcast_clone<T: Any + Clone + Send + Sync + 'static>(&self) -> Option<T>
|
|
|
|
|
{
|
|
|
|
|
self.downcast_ref::<T>().map(|x| *x.clone_dyn_any().downcast().unwrap())
|
|
|
|
|
}
|
|
|
|
@ -134,7 +147,7 @@ impl ServiceEventObject
|
|
|
|
|
/// This will fail if:
|
|
|
|
|
/// * The downcasted type is invalid
|
|
|
|
|
/// * There are other references to this object (created through `clone_ref()`.).
|
|
|
|
|
pub fn try_into_downcast<T: AnyCloneable + Send + Sync + 'static>(self) -> Result<T, Self>
|
|
|
|
|
pub fn try_into_downcast<T: Any + Send + Sync + 'static>(self) -> Result<T, Self>
|
|
|
|
|
{
|
|
|
|
|
match Arc::downcast(self.0)
|
|
|
|
|
{
|
|
|
|
@ -153,12 +166,12 @@ impl ServiceEventObject
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Try to downcast the object into a concrete type
|
|
|
|
|
#[inline] pub fn is<T: AnyCloneable + Send + Sync + 'static>(&self) -> bool
|
|
|
|
|
#[inline] pub fn is<T: Any + Send + Sync + 'static>(&self) -> bool
|
|
|
|
|
{
|
|
|
|
|
self.0.as_ref().is::<T>()
|
|
|
|
|
}
|
|
|
|
|
/// Try to downcast the object into a concrete type
|
|
|
|
|
#[inline] pub fn downcast_ref<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T>
|
|
|
|
|
#[inline] pub fn downcast_ref<T: Any + Send + Sync + 'static>(&self) -> Option<&T>
|
|
|
|
|
{
|
|
|
|
|
self.0.as_ref().downcast_ref::<T>()
|
|
|
|
|
}
|
|
|
|
@ -168,7 +181,11 @@ impl ServiceEventObject
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
|
|
|
|
|
pub enum ServiceEventKind
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// Does nothing.
|
|
|
|
|
///
|
|
|
|
|
/// # Associated object
|
|
|
|
|
/// `()`.
|
|
|
|
|
Ping,
|
|
|
|
|
/// Does nothing.
|
|
|
|
|
///
|
|
|
|
|
/// # Associated object
|
|
|
|
@ -190,6 +207,8 @@ cfg_if!{
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct ServiceEvent
|
|
|
|
|
{
|
|
|
|
|
bc_id: BroadcastID,
|
|
|
|
|
|
|
|
|
|
kind: ServiceEventKind,
|
|
|
|
|
directed: Option<SESet<ServiceSubID>>,
|
|
|
|
|
obj: Option<ServiceEventObject>,
|
|
|
|
@ -197,8 +216,29 @@ pub struct ServiceEvent
|
|
|
|
|
|
|
|
|
|
impl ServiceEvent
|
|
|
|
|
{
|
|
|
|
|
/// Create a new event to be broadcast
|
|
|
|
|
fn new<T>(kind: ServiceEventKind, directed: Option<impl IntoIterator<Item=ServiceSubID>>, obj: Option<T>) -> Self
|
|
|
|
|
where T: Any + Send + Sync + 'static
|
|
|
|
|
{
|
|
|
|
|
Self {
|
|
|
|
|
bc_id: BroadcastID::id_new(),
|
|
|
|
|
kind,
|
|
|
|
|
directed: directed.map(|x| x.into_iter().collect()).and_then(|n: SESet<_>| if n.len() < 1 {
|
|
|
|
|
None
|
|
|
|
|
} else {
|
|
|
|
|
Some(n)
|
|
|
|
|
}),
|
|
|
|
|
obj: obj.map(|x| ServiceEventObject(Arc::new(x))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline] pub fn id(&self) -> &BroadcastID
|
|
|
|
|
{
|
|
|
|
|
&self.bc_id
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The kind of this event.
|
|
|
|
|
pub fn kind(&self) -> ServiceEventKind
|
|
|
|
|
#[inline] pub fn kind(&self) -> ServiceEventKind
|
|
|
|
|
{
|
|
|
|
|
self.kind
|
|
|
|
|
}
|
|
|
|
|