slightly improved state management

This commit is contained in:
2024-12-18 23:43:17 +01:00
parent 1c67eaa3a2
commit 97141eae77
4 changed files with 92 additions and 47 deletions
+57 -38
View File
@@ -1,49 +1,68 @@
use crate::prelude::*; pub mod counter_example {
use crate::prelude::*;
pub fn todo_app() -> Element { pub fn app() -> Element {
let todo = vec!["Todo", "Hovering", "Completed", "Foo", "Bar"]; let count = State::new(0);
rsx! { rsx! {
@SetStyle(todo_styling()) button {
on_click: fn(_, _, _) @count {
count += 1;
},
text { class: "title", static "Todo list app made with OSUI" } "The current count is: {count}"
text { class: "title", "{}", "-".repeat(crossterm::terminal::size().unwrap().0 as usize) } }
for (t in todo) {
ersx!(button { class: "todo", on_click: fn(btn: &mut Button, _, _) {
btn.class = if btn.class == "todo" {
"complete"
} else {
"todo"
};
}, "{t}" } )
} }
} }
} }
pub fn todo_styling() -> Css { pub mod todo_example {
css! { use crate::prelude::*;
"todo" { pub fn todo_app() -> Element {
x: 0 px, let todo = vec!["Todo", "Hovering", "Completed", "Foo", "Bar"];
y: Auto,
color: Red, rsx! {
@SetStyle(todo_styling())
text { class: "title", static "Todo list app made with OSUI" }
text { class: "title", "{}", "-".repeat(crossterm::terminal::size().unwrap().0 as usize) }
for (t in todo) {
ersx!(button { class: "todo", on_click: fn(btn: &mut Button, _, _) {
btn.class = if btn.class == "todo" {
"complete"
} else {
"todo"
};
}, "{t}" } )
}
} }
"todo": "hover" { }
color: Blue,
} pub fn todo_styling() -> Css {
"complete" { css! {
x: 0 px, "todo" {
y: Auto, x: 0 px,
color: Green, y: Auto,
} color: Red,
"complete": "hover" { }
color: Cyan "todo": "hover" {
} color: Blue,
"title" { }
x: 0 px, "complete" {
y: Auto, x: 0 px,
} y: Auto,
"title": "hover" { color: Green,
color: Blue }
"complete": "hover" {
color: Cyan
}
"title" {
x: 0 px,
y: Auto,
}
"title": "hover" {
color: Blue
}
} }
} }
} }
+25 -2
View File
@@ -22,6 +22,7 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
fmt::Debug, fmt::Debug,
ops::{AddAssign, SubAssign},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
@@ -97,6 +98,8 @@ pub struct Writer {
written: (u16, u16), written: (u16, u16),
} }
pub struct State<T>(Arc<Mutex<T>>);
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
/// Enums /// Enums
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
@@ -387,7 +390,6 @@ impl<T> std::fmt::Debug for Handler<T> {
} }
} }
pub struct State<T>(Arc<Mutex<T>>);
impl<T> State<T> { impl<T> State<T> {
pub fn new<'a>(v: T) -> State<T> { pub fn new<'a>(v: T) -> State<T> {
State(Arc::new(Mutex::new(v))) State(Arc::new(Mutex::new(v)))
@@ -395,7 +397,7 @@ impl<T> State<T> {
pub fn use_state<'a>(&'a self) -> std::sync::MutexGuard<'a, T> { pub fn use_state<'a>(&'a self) -> std::sync::MutexGuard<'a, T> {
self.0.lock().unwrap() self.0.lock().unwrap()
} }
pub fn copy_state<'a>(&'a self) -> State<T> { pub fn clone<'a>(&'a self) -> State<T> {
State(Arc::clone(&self.0)) State(Arc::clone(&self.0))
} }
} }
@@ -409,3 +411,24 @@ impl<T: std::fmt::Display> std::fmt::Display for State<T> {
} }
} }
} }
impl<T: AddAssign> AddAssign<T> for State<T> {
fn add_assign(&mut self, rhs: T) {
*self.0.lock().unwrap() += rhs;
}
}
impl<T: SubAssign> SubAssign<T> for State<T> {
fn sub_assign(&mut self, rhs: T) {
*self.0.lock().unwrap() -= rhs;
}
}
impl<T: PartialEq> PartialEq<T> for State<T> {
fn eq(&self, other: &T) -> bool {
self.use_state().eq(other)
}
fn ne(&self, other: &T) -> bool {
self.use_state().ne(other)
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
use osui::{examples::todo_app, launch}; use osui::{examples::counter_example::app, launch};
fn main() { fn main() {
launch!(todo_app()); launch!(app());
} }
+8 -5
View File
@@ -40,12 +40,15 @@ macro_rules! parse_rsx_param {
osui::parse_rsx_param!($elem, $($($rest)*)?); osui::parse_rsx_param!($elem, $($($rest)*)?);
}; };
($elem:expr, $($k:ident).+: fn($($params:tt)*) @$($v:ident),* $code:block $(, $($rest:tt)*)?) => { ($elem:expr, $($k:ident).+: fn($($params:tt)*) $(@$($v:ident),+)? $code:block $(, $($rest:tt)*)?) => {
$elem.$($k).+ = $crate::Handler::new({ $elem.$($k).+ = $crate::Handler::new({
$( $($(
let $v = $v.copy_state(); #[allow(unused_mut)]
)* let mut $v = $v.clone();
move |$($params)*| $code )+)?
move |$($params)*| {
$code
}
}); });
osui::parse_rsx_param!($elem, $($($rest)*)?); osui::parse_rsx_param!($elem, $($($rest)*)?);
}; };