Access cell in event handlers
This commit is contained in:
+37
-24
@@ -19,7 +19,7 @@ use super::{scope::Scope, Component, ComponentImpl};
|
|||||||
pub struct Context {
|
pub struct Context {
|
||||||
component: AccessCell<Component>,
|
component: AccessCell<Component>,
|
||||||
view: AccessCell<View>,
|
view: AccessCell<View>,
|
||||||
event_handlers: Mutex<HashMap<TypeId, Vec<EventHandler>>>,
|
event_handlers: AccessCell<HashMap<TypeId, Vec<EventHandler>>>,
|
||||||
pub(crate) scopes: Mutex<Vec<Arc<Scope>>>,
|
pub(crate) scopes: Mutex<Vec<Arc<Scope>>>,
|
||||||
executor: Arc<dyn CommandExecutor>,
|
executor: Arc<dyn CommandExecutor>,
|
||||||
}
|
}
|
||||||
@@ -32,14 +32,15 @@ impl Context {
|
|||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
component: AccessCell::new(Arc::new(component)),
|
component: AccessCell::new(Arc::new(component)),
|
||||||
view: AccessCell::new(Arc::new(|_| {})),
|
view: AccessCell::new(Arc::new(|_| {})),
|
||||||
event_handlers: Mutex::new(HashMap::new()),
|
event_handlers: AccessCell::new(HashMap::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.event_handlers
|
||||||
|
.access(|event_handlers| event_handlers.clear());
|
||||||
self.component.access({
|
self.component.access({
|
||||||
let s = self.clone();
|
let s = self.clone();
|
||||||
move |component| {
|
move |component| {
|
||||||
@@ -53,10 +54,11 @@ impl Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn refresh_sync(self: &Arc<Self>) {
|
pub fn refresh_sync(self: &Arc<Self>) {
|
||||||
self.event_handlers.lock().unwrap().clear();
|
|
||||||
|
|
||||||
let (tx, rx) = std::sync::mpsc::channel::<()>();
|
let (tx, rx) = std::sync::mpsc::channel::<()>();
|
||||||
|
|
||||||
|
self.event_handlers
|
||||||
|
.access(|event_handlers| event_handlers.clear());
|
||||||
|
|
||||||
self.component.access({
|
self.component.access({
|
||||||
let s = self.clone();
|
let s = self.clone();
|
||||||
move |component| {
|
move |component| {
|
||||||
@@ -85,30 +87,37 @@ impl Context {
|
|||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
handler: F,
|
handler: F,
|
||||||
) {
|
) {
|
||||||
self.event_handlers
|
let new_handler: EventHandler = Arc::new(Mutex::new(
|
||||||
.lock()
|
move |ctx: &Arc<Context>, event: &dyn Any| {
|
||||||
.unwrap()
|
|
||||||
.entry(TypeId::of::<T>())
|
|
||||||
.or_insert_with(|| Vec::new())
|
|
||||||
.push(Arc::new(Mutex::new(
|
|
||||||
move |ctx: &Arc<Self>, event: &dyn Any| {
|
|
||||||
if let Some(e) = event.downcast_ref::<T>() {
|
if let Some(e) = event.downcast_ref::<T>() {
|
||||||
(handler)(ctx, e);
|
(handler)(ctx, e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)));
|
));
|
||||||
|
self.event_handlers.access(|event_handlers| {
|
||||||
|
event_handlers
|
||||||
|
.entry(TypeId::of::<T>())
|
||||||
|
.or_insert_with(Vec::new)
|
||||||
|
.push(new_handler);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_event<E: Any + 'static>(self: &Arc<Self>, event: &E) {
|
pub fn emit_event<E: Send + Sync + Any + 'static>(self: &Arc<Self>, event: E) {
|
||||||
if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::<E>()) {
|
let event = Arc::new(event);
|
||||||
for i in v {
|
let handlers_to_call: Vec<EventHandler> = {
|
||||||
(i.lock().unwrap())(self, event);
|
let guard = self.event_handlers.access_ref();
|
||||||
}
|
guard
|
||||||
|
.get(&TypeId::of::<E>())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default()
|
||||||
|
};
|
||||||
|
for h in &handlers_to_call {
|
||||||
|
(h.lock().unwrap())(self, event.as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
for scope in self.scopes.lock().unwrap().iter() {
|
for scope in self.scopes.lock().unwrap().iter() {
|
||||||
for (child, _) in scope.children.lock().unwrap().iter() {
|
for (child, _) in scope.children.lock().unwrap().iter() {
|
||||||
child.emit_event(event);
|
child.emit_event(event.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,16 +126,20 @@ impl Context {
|
|||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
event: &E,
|
event: &E,
|
||||||
) {
|
) {
|
||||||
if let Some(v) = self.event_handlers.lock().unwrap().get(&TypeId::of::<E>()) {
|
let handlers_to_call: Vec<EventHandler> = {
|
||||||
for i in v {
|
let guard = self.event_handlers.access_ref();
|
||||||
let i = i.clone();
|
guard
|
||||||
|
.get(&TypeId::of::<E>())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default()
|
||||||
|
};
|
||||||
|
for h in handlers_to_call {
|
||||||
let event = event.clone();
|
let event = event.clone();
|
||||||
let s = self.clone();
|
let s = self.clone();
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
(i.lock().unwrap())(&s, &event);
|
(h.lock().unwrap())(&s, &event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for scope in self.scopes.lock().unwrap().iter() {
|
for scope in self.scopes.lock().unwrap().iter() {
|
||||||
for (child, _) in scope.children.lock().unwrap().iter() {
|
for (child, _) in scope.children.lock().unwrap().iter() {
|
||||||
|
|||||||
+3
-2
@@ -192,7 +192,7 @@ pub fn use_sync_state<
|
|||||||
|
|
||||||
pub fn use_sync_effect<
|
pub fn use_sync_effect<
|
||||||
T: Send + Sync + 'static,
|
T: Send + Sync + 'static,
|
||||||
Ev: 'static,
|
Ev: Send + Sync + 'static,
|
||||||
E: Fn(&State<T>) -> Ev + Send + Sync + 'static,
|
E: Fn(&State<T>) -> Ev + Send + Sync + 'static,
|
||||||
>(
|
>(
|
||||||
cx: &Arc<Context>,
|
cx: &Arc<Context>,
|
||||||
@@ -205,7 +205,8 @@ pub fn use_sync_effect<
|
|||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
let cx = cx.clone();
|
let cx = cx.clone();
|
||||||
move || {
|
move || {
|
||||||
cx.emit_event(&encoder(&state));
|
let ev = encoder(&state);
|
||||||
|
cx.emit_event(ev);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
deps,
|
deps,
|
||||||
|
|||||||
Reference in New Issue
Block a user