nuit_core/state/
state.rs

1use std::{cell::RefCell, rc::Rc};
2
3use crate::{Animation, Binding, Storage};
4
5use super::StateKey;
6
7/// A wrapper around a value managed by nuit.
8#[derive(Clone)]
9pub struct State<T> {
10    initial_value: T,
11    storage: RefCell<Option<Rc<Storage>>>,
12    key: RefCell<Option<StateKey>>,
13}
14
15impl<T> State<T> where T: 'static + Clone {
16    pub fn new(initial_value: impl Into<T>) -> Self {
17        Self {
18            initial_value: initial_value.into(),
19            storage: RefCell::new(None),
20            key: RefCell::new(None),
21        }
22    }
23
24    pub fn is_linked(&self) -> bool {
25        self.storage.borrow().is_some() && self.key.borrow().is_some()
26    }
27
28    pub fn link(&self, storage: Rc<Storage>, key: StateKey) {
29        *self.storage.borrow_mut() = Some(storage.clone());
30        *self.key.borrow_mut() = Some(key.clone());
31
32        storage.initialize_if_needed(key, || self.initial_value.clone());
33    }
34
35    pub fn get(&self) -> T {
36        let storage = self.storage.borrow();
37        let storage = storage.as_ref().expect("Storage not linked prior to get");
38        storage.get::<T>(self.key.borrow().as_ref().unwrap())
39    }
40
41    fn add_change(&self, value: impl Into<T>, animation: Option<Animation>) {
42        let storage = self.storage.borrow();
43        let storage = storage.as_ref().expect("Storage not linked prior to set");
44        storage.add_change(self.key.borrow().clone().unwrap(), value.into(), animation);
45    }
46
47    pub fn set(&self, value: impl Into<T>) {
48        self.add_change(value, None)
49    }
50
51    pub fn set_with(&self, animation: Animation, value: impl Into<T>) {
52        self.add_change(value, Some(animation))
53    }
54
55    pub fn binding(&self) -> Binding<T> {
56        let self1 = self.clone();
57        let self2 = self.clone();
58        Binding::new(
59            move || self1.get(),
60            move |value| self2.set(value),
61        )
62    }
63}
64
65impl<T> Default for State<T> where T: 'static + Default + Clone {
66    fn default() -> Self {
67        Self::new(T::default())
68    }
69}