Implemented access cell for component and view

This commit is contained in:
2026-01-31 13:02:22 +01:00
parent d8f24d7eec
commit 17f78b86f4
2 changed files with 36 additions and 23 deletions
+1
View File
@@ -23,6 +23,7 @@ path = "src/main.rs"
cc = "1.0" cc = "1.0"
[dependencies] [dependencies]
access-cell = "0.1.3"
crossterm = "0.28.1" crossterm = "0.28.1"
figlet-rs = "0.1.5" figlet-rs = "0.1.5"
osui-macros = { path = "macros" } osui-macros = { path = "macros" }
+34 -22
View File
@@ -4,6 +4,8 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use access_cell::AccessCell;
use crate::{ use crate::{
component::EventHandler, component::EventHandler,
engine::{Command, CommandExecutor}, engine::{Command, CommandExecutor},
@@ -15,9 +17,9 @@ use crate::{
use super::{scope::Scope, Component, ComponentImpl}; use super::{scope::Scope, Component, ComponentImpl};
pub struct Context { pub struct Context {
component: Mutex<Component>, component: AccessCell<Component>,
view: AccessCell<View>,
event_handlers: Mutex<HashMap<TypeId, Vec<EventHandler>>>, event_handlers: Mutex<HashMap<TypeId, Vec<EventHandler>>>,
view: Mutex<View>,
pub(crate) scopes: Mutex<Vec<Arc<Scope>>>, pub(crate) scopes: Mutex<Vec<Arc<Scope>>>,
executor: Arc<dyn CommandExecutor>, executor: Arc<dyn CommandExecutor>,
} }
@@ -28,45 +30,55 @@ impl Context {
executor: Arc<dyn CommandExecutor>, executor: Arc<dyn CommandExecutor>,
) -> Arc<Self> { ) -> Arc<Self> {
Arc::new(Self { Arc::new(Self {
component: Mutex::new(Arc::new(component)), component: AccessCell::new(Arc::new(component)),
view: AccessCell::new(Arc::new(|_| {})),
event_handlers: Mutex::new(HashMap::new()), event_handlers: Mutex::new(HashMap::new()),
view: Mutex::new(Arc::new(|_| {})),
scopes: Mutex::new(Vec::new()), scopes: Mutex::new(Vec::new()),
executor, executor,
}) })
} }
pub fn refresh(self: &Arc<Self>) { pub fn refresh(self: &Arc<Self>) {
self.event_handlers.lock().unwrap().clear();
self.component.access({
let s = self.clone(); let s = self.clone();
move |component| {
std::thread::spawn({ let component = component.clone();
move || { s.view.access({
s.event_handlers.lock().unwrap().clear(); let s = s.clone();
let c = s.component.lock().unwrap().clone(); move |view| *view = component.call(&s)
*s.view.lock().unwrap() = c.call(&s); })
} }
}); });
} }
pub fn refresh_atomic(self: &Arc<Self>) -> Arc<Mutex<bool>> { pub fn refresh_sync(self: &Arc<Self>) {
let s = self.clone(); self.event_handlers.lock().unwrap().clear();
let done = Arc::new(Mutex::new(false));
std::thread::spawn({ let (tx, rx) = std::sync::mpsc::channel::<()>();
let done = done.clone();
move || { self.component.access({
s.event_handlers.lock().unwrap().clear(); let s = self.clone();
let c = s.component.lock().unwrap().clone(); move |component| {
*s.view.lock().unwrap() = c.call(&s); let component = component.clone();
*done.lock().unwrap() = true;
s.view.access({
let s = s.clone();
let tx = tx.clone();
move |view| {
*view = component.call(&s);
let _ = tx.send(()); // signal completion
}
});
} }
}); });
done // BLOCK until view closure finishes
let _ = rx.recv();
} }
pub fn get_view(self: &Arc<Self>) -> View { pub fn get_view(self: &Arc<Self>) -> View {
self.view.lock().unwrap().clone() self.view.access_ref().clone()
} }
pub fn on_event<T: Any + 'static, F: Fn(&Arc<Self>, &T) + Send + Sync + 'static>( pub fn on_event<T: Any + 'static, F: Fn(&Arc<Self>, &T) + Send + Sync + 'static>(