Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion snowcap/api/rust/src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ struct SignalEntry<S> {
callbacks: Vec<Arc<dyn Fn(S) -> HandlerPolicy + Sync + Send>>,
}

/// [`Signaler`] implementation detail.
type SignalerState = HashMap<(TypeId, &'static str), Box<dyn Any + Sync + Send>>;

/// A typed signal handler.
///
/// [`Signaler`]s holds handlers for signals in a type-erased way. Other types can
Expand All @@ -49,9 +52,17 @@ struct SignalEntry<S> {
/// [emit]: Signaler::emit
#[derive(Default, Clone, Debug)]
pub struct Signaler {
entries: Arc<Mutex<HashMap<(TypeId, &'static str), Box<dyn Any + Sync + Send>>>>,
entries: Arc<Mutex<SignalerState>>,
}

/// `WeakSignaler` is a non-owning version of [`Signaler`].
///
/// The actual signaler is accessed by calling [`upgrade`], which returns a <code>[Option]<[Signaler]></code>.
///
/// [`upgrade`]: WeakSignaler::upgrade
#[derive(Clone, Debug)]
pub struct WeakSignaler(Weak<Mutex<SignalerState>>);

impl Signaler {
/// Creates a new default [`Signaler`].
pub fn new() -> Self {
Expand Down Expand Up @@ -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<dyn Any + Sync + Send>>,
Expand Down Expand Up @@ -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<Signaler> {
self.0.upgrade().map(|entries| Signaler { entries })
}
}
Loading