pub struct SharedState<Data> { /* private fields */ }
Expand description
A type that allows you to share information across your application easily. Get immutable and mutable access to the data and subscribe to changes.
§Panics
SharedState
uses a RwLock
internally.
If you use Self::read()
and Self::write()
in the same scope
your code might be stuck in a deadlock or panic.
Implementations§
sourcepub const fn new() -> Self
pub const fn new() -> Self
Create a new SharedState
variable.
The data will be initialized lazily on the first access.
§Example
use relm4::SharedState;
static STATE: SharedState<MyData> = SharedState::new();
sourcepub fn subscribe<Msg, F>(&self, sender: &Sender<Msg>, f: F)
pub fn subscribe<Msg, F>(&self, sender: &Sender<Msg>, f: F)
Subscribe to a shared state type.
Any subscriber will be notified with a message every time
you modify the shared state using Self::get_mut()
.
use relm4::SharedState;
static STATE: SharedState<u8> = SharedState::new();
let (sender, receiver) = relm4::channel();
// Every time we modify the data, we will receive
// the updated value as a message.
STATE.subscribe(&sender, |data| *data);
{
let mut data = STATE.write();
*data += 1;
}
assert_eq!(receiver.recv_sync().unwrap(), 1);
sourcepub fn subscribe_optional<Msg, F>(&self, sender: &Sender<Msg>, f: F)
pub fn subscribe_optional<Msg, F>(&self, sender: &Sender<Msg>, f: F)
An alternative version of subscribe()
that only send a message if
the closure returns Some
.
sourcepub fn read(&self) -> SharedStateReadGuard<'_, Data>
pub fn read(&self) -> SharedStateReadGuard<'_, Data>
Get immutable access to the shared data.
Returns a RAII guard which will release this thread’s shared access once it is dropped.
The calling thread will be blocked until there are no more writers
which hold the lock (see RwLock
).
§Panics
This function will panic if the internal RwLock
is poisoned.
A RwLock
is poisoned whenever a writer panics while holding an exclusive lock.
The failure will occur immediately after the lock has been acquired.
Also, this function might panic when called if the lock is already held by the current thread.
sourcepub fn try_read(
&self,
) -> Result<SharedStateReadGuard<'_, Data>, TryLockError<RwLockReadGuard<'_, Data>>>
pub fn try_read( &self, ) -> Result<SharedStateReadGuard<'_, Data>, TryLockError<RwLockReadGuard<'_, Data>>>
sourcepub fn write(&self) -> SharedStateWriteGuard<'_, Data>
pub fn write(&self) -> SharedStateWriteGuard<'_, Data>
Get mutable access to the shared data.
Returns a RAII guard which will notify all subscribers and release this thread’s shared access once it is dropped.
This function will not return while other writers or other readers
currently have access to the internal lock (see RwLock
).
§Panics
This function will panic if the internal RwLock
is poisoned.
A RwLock
is poisoned whenever a writer panics while holding an exclusive lock.
The failure will occur immediately after the lock has been acquired.
Also, this function might panic when called if the lock is already held by the current thread.
§Example
static STATE: SharedState<u8> = SharedState::new();
// Overwrite the current value with 1
*STATE.write() = 1;
§Panic example
static STATE: SharedState<u8> = SharedState::new();
let read_guard = STATE.read();
// This is fine
let another_read_guard = STATE.read();
// This might panic or result in a dead lock
// because you cannot read and write at the same time.
// To solve this, drop all read guards on this thread first.
let another_write_guard = STATE.write();
Examples found in repository?
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>, _root: &Self::Root) {
match msg {
AppMsg::StartGame(index) => {
self.start_index = Some(index);
sender.command(|sender, _| async move {
for i in (1..4).rev() {
*GAME_STATE.write() = GameState::Countdown(i);
relm4::tokio::time::sleep(Duration::from_millis(1000)).await;
}
*GAME_STATE.write() = GameState::Running;
for _ in 0..20 {
relm4::tokio::time::sleep(Duration::from_millis(500)).await;
sender.send(false).unwrap();
}
relm4::tokio::time::sleep(Duration::from_millis(1000)).await;
sender.send(true).unwrap();
});
}
AppMsg::StopGame => {
*GAME_STATE.write() = GameState::Guessing;
}
AppMsg::SelectedGuess(index) => {
*GAME_STATE.write() = GameState::End(index == self.start_index.take().unwrap());
}
}
}
sourcepub fn try_write(
&self,
) -> Result<SharedStateWriteGuard<'_, Data>, TryLockError<RwLockWriteGuard<'_, Data>>>
pub fn try_write( &self, ) -> Result<SharedStateWriteGuard<'_, Data>, TryLockError<RwLockWriteGuard<'_, Data>>>
sourcepub fn get_mut(&mut self) -> &mut Data
pub fn get_mut(&mut self) -> &mut Data
Get mutable access to the shared data.
Since this call borrows the SharedState
mutably,
no actual locking needs to take place, but the mutable
borrow statically guarantees no locks exist.
This method will not notify any subscribers!
§Panics
This function will panic if the internal RwLock
is poisoned.
A RwLock
is poisoned whenever a writer panics while holding an exclusive lock.
The failure will occur immediately after the lock has been acquired.
sourcepub fn read_inner(&self) -> RwLockReadGuard<'_, Data>
pub fn read_inner(&self) -> RwLockReadGuard<'_, Data>
Get immutable access to the shared data.
This method will not notify any subscribers!
§Panics
This function will panic if the internal RwLock
is poisoned.
A RwLock
is poisoned whenever a writer panics while holding an exclusive lock.
The failure will occur immediately after the lock has been acquired.
Also, this function might panic when called if the lock is already held by the current thread.
sourcepub fn write_inner(&self) -> RwLockWriteGuard<'_, Data>
pub fn write_inner(&self) -> RwLockWriteGuard<'_, Data>
Get mutable access to the shared data.
This method will not notify any subscribers!
§Panics
This function will panic if the internal RwLock
is poisoned.
A RwLock
is poisoned whenever a writer panics while holding an exclusive lock.
The failure will occur immediately after the lock has been acquired.
Also, this function might panic when called if the lock is already held by the current thread.