Implemented access cell for component and view
This commit is contained in:
@@ -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" }
|
||||||
|
|||||||
+35
-23
@@ -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>) {
|
||||||
let s = self.clone();
|
self.event_handlers.lock().unwrap().clear();
|
||||||
|
self.component.access({
|
||||||
std::thread::spawn({
|
let s = self.clone();
|
||||||
move || {
|
move |component| {
|
||||||
s.event_handlers.lock().unwrap().clear();
|
let component = component.clone();
|
||||||
let c = s.component.lock().unwrap().clone();
|
s.view.access({
|
||||||
*s.view.lock().unwrap() = c.call(&s);
|
let s = s.clone();
|
||||||
|
move |view| *view = component.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>(
|
||||||
|
|||||||
Reference in New Issue
Block a user