pub struct Watch<M: RawMutex, T: Clone, const N: usize> { /* private fields */ }
Expand description
The Watch
is a single-slot signaling primitive that allows multiple receivers to concurrently await
changes to the value. Unlike a Signal
, Watch
supports multiple receivers,
and unlike a PubSubChannel
, Watch
immediately overwrites the previous
value when a new one is sent, without waiting for all receivers to read the previous value.
This makes Watch
particularly useful when a single task updates a value or “state”, and multiple other tasks
need to be notified about changes to this value asynchronously. Receivers may “lose” stale values, as they are
always provided with the latest value.
Typically, Watch
instances are declared as static
, and a Sender
and Receiver
(or DynSender
and/or DynReceiver
) are obtained where relevant. An AnonReceiver
and DynAnonReceiver
are also available, which do not increase the receiver count for the
channel, and unwrapping is therefore not required, but it is not possible to .await
the channel.
use futures_executor::block_on;
use embassy_sync::watch::Watch;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
let f = async {
static WATCH: Watch<CriticalSectionRawMutex, u8, 2> = Watch::new();
// Obtain receivers and sender
let mut rcv0 = WATCH.receiver().unwrap();
let mut rcv1 = WATCH.dyn_receiver().unwrap();
let mut snd = WATCH.sender();
// No more receivers, and no update
assert!(WATCH.receiver().is_none());
assert_eq!(rcv1.try_changed(), None);
snd.send(10);
// Receive the new value (async or try)
assert_eq!(rcv0.changed().await, 10);
assert_eq!(rcv1.try_changed(), Some(10));
// No update
assert_eq!(rcv0.try_changed(), None);
assert_eq!(rcv1.try_changed(), None);
snd.send(20);
// Using `get` marks the value as seen
assert_eq!(rcv1.get().await, 20);
assert_eq!(rcv1.try_changed(), None);
// But `get` also returns when unchanged
assert_eq!(rcv1.get().await, 20);
assert_eq!(rcv1.get().await, 20);
};
block_on(f);
Implementations§
Source§impl<M: RawMutex, T: Clone, const N: usize> Watch<M, T, N>
impl<M: RawMutex, T: Clone, const N: usize> Watch<M, T, N>
Sourcepub fn dyn_sender(&self) -> DynSender<'_, T>
pub fn dyn_sender(&self) -> DynSender<'_, T>
Create a new DynSender
for the Watch
.
Sourcepub fn receiver(&self) -> Option<Receiver<'_, M, T, N>>
pub fn receiver(&self) -> Option<Receiver<'_, M, T, N>>
Try to create a new Receiver
for the Watch
. If the
maximum number of receivers has been reached, None
is returned.
Sourcepub fn dyn_receiver(&self) -> Option<DynReceiver<'_, T>>
pub fn dyn_receiver(&self) -> Option<DynReceiver<'_, T>>
Try to create a new DynReceiver
for the Watch
. If the
maximum number of receivers has been reached, None
is returned.
Sourcepub fn anon_receiver(&self) -> AnonReceiver<'_, M, T, N>
pub fn anon_receiver(&self) -> AnonReceiver<'_, M, T, N>
Try to create a new AnonReceiver
for the Watch
.
Sourcepub fn dyn_anon_receiver(&self) -> DynAnonReceiver<'_, T>
pub fn dyn_anon_receiver(&self) -> DynAnonReceiver<'_, T>
Try to create a new DynAnonReceiver
for the Watch
.
Sourcepub fn get_msg_id(&self) -> u64
pub fn get_msg_id(&self) -> u64
Returns the message ID of the latest message sent to the Watch
.
This counter is monotonic, and is incremented every time a new message is sent.
Trait Implementations§
Source§impl<M: RawMutex, T: Clone, const N: usize> WatchBehavior<T> for Watch<M, T, N>
impl<M: RawMutex, T: Clone, const N: usize> WatchBehavior<T> for Watch<M, T, N>
Source§fn try_get(&self, id: Option<&mut u64>) -> Option<T>
fn try_get(&self, id: Option<&mut u64>) -> Option<T>
Watch
, marking it as seen, if an id is given.Source§fn try_get_and(
&self,
id: Option<&mut u64>,
f: &mut dyn Fn(&T) -> bool,
) -> Option<T>
fn try_get_and( &self, id: Option<&mut u64>, f: &mut dyn Fn(&T) -> bool, ) -> Option<T>
Watch
if it matches the predicate function
f
, marking it as seen.Source§fn contains_value(&self) -> bool
fn contains_value(&self) -> bool
Watch
is been initialized with a value.