improved state management

This commit is contained in:
2025-06-28 11:30:09 -05:00
parent fd73514a7b
commit bb0ef3adc4
2 changed files with 85 additions and 18 deletions
+3 -3
View File
@@ -29,20 +29,20 @@ fn init(states: &Arc<StateManager>) {
fn app(states: &Arc<StateManager>, screen: &mut Screen) { fn app(states: &Arc<StateManager>, screen: &mut Screen) {
screen.events.set_state_manager(states.clone()); screen.events.set_state_manager(states.clone());
let count = states.use_state(0); let mut count = states.use_state(0);
screen screen
.draw(Rect(0xffffff)) .draw(Rect(0xffffff))
.component(Transform::center().dimensions(30, 3)); .component(Transform::center().dimensions(30, 3));
screen screen
.draw(format!("Count: {}", count.get())) .draw(format!("Count: {count}"))
.component(Transform::center()); .component(Transform::center());
screen.events.on( screen.events.on(
move |events: &Arc<EventManager>, event: &KeyEvent| match event.code { move |events: &Arc<EventManager>, event: &KeyEvent| match event.code {
crossterm::event::KeyCode::Enter => { crossterm::event::KeyCode::Enter => {
count.set(count.get() + 1); count += 1;
} }
_ => { _ => {
events.close(); events.close();
+78 -11
View File
@@ -1,7 +1,9 @@
use std::{ use std::{
any::Any, any::Any,
collections::HashMap, collections::HashMap,
fmt::Display,
marker::PhantomData, marker::PhantomData,
ops::{Add, AddAssign, Div, Sub, SubAssign},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
@@ -61,31 +63,96 @@ impl StateManager {
} }
} }
impl<S: 'static + Clone + Send + Sync> State<S> { impl<S: 'static> State<S> {
pub fn dirty(&self) { pub fn dirty(&self) {
*self.manager.dirty.lock().unwrap() = true; *self.manager.dirty.lock().unwrap() = true;
} }
}
pub fn get(&self) -> S { impl<S: Display + 'static> Display for State<S> {
let store = self.manager.store.lock().unwrap(); fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let x = store[&self.id] self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>() .downcast_ref::<Mutex<S>>()
.unwrap() .unwrap()
.lock() .lock()
.unwrap() .unwrap()
.clone(); .fmt(f)
x
} }
}
pub fn set(&self, val: S) { impl<S: Add + Clone + 'static> Add<S> for State<S> {
{ type Output = <S as Add>::Output;
let store = self.manager.store.lock().unwrap();
*store[&self.id] fn add(self, rhs: S) -> Self::Output {
self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>() .downcast_ref::<Mutex<S>>()
.unwrap() .unwrap()
.lock() .lock()
.unwrap() = val; .unwrap()
.clone()
.add(rhs)
} }
}
impl<S: Sub + Clone + 'static> Sub<S> for State<S> {
type Output = <S as Sub>::Output;
fn sub(self, rhs: S) -> Self::Output {
self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>()
.unwrap()
.lock()
.unwrap()
.clone()
.sub(rhs)
}
}
impl<S: Div + Clone + 'static> Div<S> for State<S> {
type Output = <S as Div>::Output;
fn div(self, rhs: S) -> Self::Output {
self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>()
.unwrap()
.lock()
.unwrap()
.clone()
.div(rhs)
}
}
impl<S: AddAssign + 'static> AddAssign<S> for State<S> {
fn add_assign(&mut self, rhs: S) {
self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>()
.unwrap()
.lock()
.unwrap()
.add_assign(rhs);
self.dirty(); self.dirty();
} }
} }
impl<S: SubAssign + 'static> SubAssign<S> for State<S> {
fn sub_assign(&mut self, rhs: S) {
self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>()
.unwrap()
.lock()
.unwrap()
.sub_assign(rhs);
self.dirty();
}
}
impl<S: PartialEq<S> + 'static> PartialEq<S> for State<S> {
fn eq(&self, other: &S) -> bool {
self.manager.store.lock().unwrap()[&self.id]
.downcast_ref::<Mutex<S>>()
.unwrap()
.lock()
.unwrap()
.eq(other)
}
}