diff --git a/snowcap/api/rust/src/signal.rs b/snowcap/api/rust/src/signal.rs index fae195d04..edf4b227b 100644 --- a/snowcap/api/rust/src/signal.rs +++ b/snowcap/api/rust/src/signal.rs @@ -34,6 +34,9 @@ struct SignalEntry { callbacks: Vec HandlerPolicy + Sync + Send>>, } +/// [`Signaler`] implementation detail. +type SignalerState = HashMap<(TypeId, &'static str), Box>; + /// A typed signal handler. /// /// [`Signaler`]s holds handlers for signals in a type-erased way. Other types can @@ -49,9 +52,17 @@ struct SignalEntry { /// [emit]: Signaler::emit #[derive(Default, Clone, Debug)] pub struct Signaler { - entries: Arc>>>, + entries: Arc>, } +/// `WeakSignaler` is a non-owning version of [`Signaler`]. +/// +/// The actual signaler is accessed by calling [`upgrade`], which returns a [Option]<[Signaler]>. +/// +/// [`upgrade`]: WeakSignaler::upgrade +#[derive(Clone, Debug)] +pub struct WeakSignaler(Weak>); + impl Signaler { /// Creates a new default [`Signaler`]. pub fn new() -> Self { @@ -125,6 +136,11 @@ impl Signaler { } } + /// Create a [`WeakSignaler`]. + pub fn downgrade(&self) -> WeakSignaler { + WeakSignaler(Arc::downgrade(&self.entries)) + } + /// Returns the [`SignalEntry`] for a given type. fn get_entry<'a, S>( entries: &'a mut HashMap<(TypeId, &'static str), Box>, @@ -185,3 +201,12 @@ where .retain_mut(|cb| cb(signal.clone()) == HandlerPolicy::Keep); } } + +impl WeakSignaler { + /// Attempts to upgrade the `WeakSignaler` to a [`Signaler`]. + /// + /// Return [`None`] if the original signaler has since been dropped. + pub fn upgrade(&self) -> Option { + self.0.upgrade().map(|entries| Signaler { entries }) + } +}