improved state management
This commit is contained in:
+3
-3
@@ -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();
|
||||||
|
|||||||
+82
-15
@@ -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 {
|
||||||
.downcast_ref::<Mutex<S>>()
|
self.manager.store.lock().unwrap()[&self.id]
|
||||||
.unwrap()
|
.downcast_ref::<Mutex<S>>()
|
||||||
.lock()
|
.unwrap()
|
||||||
.unwrap() = val;
|
.lock()
|
||||||
}
|
.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user