I'm currently making a gui library (for fun) and I'm wondering how to go about state management, I tried wrapping T
in an Arc<RefCell>
but I'm finding it hard to access the inner value while also being able to mutate it.
#[derive(Debug)]
pub struct State<T>{
value:Arc<RefCell<T>>
}
impl<T> State<T>{
pub fn new(value:T) -> Self{
Self{
value:Arc::new(RefCell::new(value))
}
}
/// Get a reference to the stateful value
pub fn get(&self) -> Arc<RefCell<T>>{
self.value.clone()
}
pub fn set(&self,value:T){
self.value.replace(value);
}
}
#[test]
fn state(){
let state = State::new(10);
let k = state.get();
let v = state.get();
let a = k.borrow();
dbg!(&k);
dbg!(&v);
state.set(20); // Panics here
dbg!(&a);
dbg!(&k);
dbg!(&v);
}
I know RefCell
panics when trying to mutate the inner value while it's already borrowed. What I (think I) want is a way to have a reference &T
to any value and be able to change that reference state.update(||{})
, to produce something like this
let count = State::new(1);
let main = hstack! {
Button::new(minus().color(hex!("#FFFFFF"))),
Text::new(&format!("{count}")), // Display the counter
Button::new(plus().color(hex!("#FFFFFF")))
.on_click(||{
count.update(|value| value+=1 ) Increment the count here
}),
}
.spacing(24)
.fill()
.align_center();
I don't know if this is even possible it feels like it's inherently unsafe to do, so I'm not sure if this is the right approach, but resources on this topic are scarce.