maycoon_core/app/update.rs
1use bitflags::bitflags;
2use std::sync::atomic::{AtomicU8, Ordering};
3use std::sync::Arc;
4
5bitflags! {
6 /// Update bitflags to define which part of the App should Update.
7 ///
8 /// Possible values:
9 /// - **EVAL** - Re-evaluate the widget tree.
10 /// - **DRAW** - Re-draw the widget tree.
11 /// - **LAYOUT** - Re-layout the widget tree.
12 /// - **FORCE** - Force the App to re-evaluate, re-draw and re-layout the widget tree.
13 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14 pub struct Update: u8 {
15 /// Re-evaluate the widget tree.
16 const EVAL = 0b00000001;
17 /// Re-draw the widget tree.
18 const DRAW = 0b00000010;
19 /// Re-layout the widget tree.
20 const LAYOUT = 0b00000100;
21 /// Force the App to re-evaluate, re-draw and re-layout the widget tree.
22 const FORCE = 0b00001000;
23 }
24}
25
26/// Manages updates for the application lifecycle.
27///
28/// It's using atomic operations to ensure lockless thread-safety.
29#[derive(Clone, Debug)]
30pub struct UpdateManager {
31 update: Arc<AtomicU8>,
32}
33
34impl UpdateManager {
35 /// Creates a new `UpdateManager`.
36 pub fn new() -> Self {
37 Self {
38 update: Arc::new(AtomicU8::new(0)),
39 }
40 }
41
42 /// Inserts the given `Update` into the `UpdateManager` using bitwise OR.
43 pub fn insert(&self, update: Update) {
44 self.update.fetch_or(update.bits(), Ordering::AcqRel);
45 }
46
47 /// Removes the given `Update` from the `UpdateManager` using bitwise AND.
48 pub fn remove(&self, update: Update) {
49 self.update.fetch_and(!update.bits(), Ordering::AcqRel);
50 }
51
52 /// Returns the current `Update` of the `UpdateManager`.
53 pub fn get(&self) -> Update {
54 Update::from_bits(self.update.load(Ordering::Acquire))
55 .expect("failed to decode update bits")
56 }
57
58 /// Sets the current `Update` of the `UpdateManager`.
59 pub fn set(&self, update: Update) {
60 self.update.store(update.bits(), Ordering::Release);
61 }
62
63 /// Clears the current `Update` flags of the `UpdateManager`.
64 pub fn clear(&self) {
65 self.update.store(0, Ordering::Release);
66 }
67}
68
69impl Default for UpdateManager {
70 fn default() -> Self {
71 Self::new()
72 }
73}