This commit is contained in:
2025-12-11 01:34:14 -05:00
parent baaeb6b027
commit 123f3e6e2b
5 changed files with 29 additions and 21 deletions

View File

@@ -53,10 +53,27 @@ pub trait EventManager: Any + Send + Sync {
fn undraw(&mut self, ui: UiId, inst: &WidgetInstance); fn undraw(&mut self, ui: UiId, inst: &WidgetInstance);
} }
impl Handle<dyn EventManager> {
pub fn remove(&mut self, id: WidgetId) {
let mut s = self.get_mut();
// refer to s.remove documentation for why drop order
let contents = s.remove(id);
drop(s);
drop(contents);
}
pub fn draw(&mut self, ui: UiId, inst: &WidgetInstance) {
self.get_mut().draw(ui, inst);
}
pub fn undraw(&mut self, ui: UiId, inst: &WidgetInstance) {
self.get_mut().undraw(ui, inst);
}
}
impl<E: Event, Ctx: 'static> EventManager for Events<E, Ctx> { impl<E: Event, Ctx: 'static> EventManager for Events<E, Ctx> {
/// so... there is a deadlock if this is called in WidgetData::drop /// so... there is a deadlock if this is called in WidgetData::drop
/// and some function in here owns another WidgetId /// and some function in here owns another WidgetId
/// so for now you need to drop the lock on self, THEN drop the contents /// so for now you need to drop the lock on self, THEN drop the contents
/// which is implemented for Handle<dyn EventManager>
fn remove(&mut self, id: WidgetId) -> Box<dyn Any> { fn remove(&mut self, id: WidgetId) -> Box<dyn Any> {
let contents = self.map.remove(&id); let contents = self.map.remove(&id);
for ui in self.active.values_mut() { for ui in self.active.values_mut() {

View File

@@ -294,7 +294,7 @@ impl<'a> PainterCtx<'a> {
} }
// run events // run events
id.map_event_managers(|m| { id.map_event_managers(|mut m| {
m.draw(self.ui_id, &instance); m.draw(self.ui_id, &instance);
}); });
self.active.insert(id, instance); self.active.insert(id, instance);
@@ -328,7 +328,7 @@ impl<'a> PainterCtx<'a> {
inst.textures.clear(); inst.textures.clear();
self.textures.free(); self.textures.free();
if undraw { if undraw {
id.map_event_managers(|m| { id.map_event_managers(|mut m| {
m.undraw(self.ui_id, inst); m.undraw(self.ui_id, inst);
}); });
} }

View File

@@ -46,7 +46,7 @@ impl Ui {
fn redraw_all(&mut self) { fn redraw_all(&mut self) {
for (id, inst) in self.data.active.drain() { for (id, inst) in self.data.active.drain() {
id.map_event_managers(|m| { id.map_event_managers(|mut m| {
m.undraw(self.id, &inst); m.undraw(self.id, &inst);
}); });
} }

View File

@@ -2,7 +2,7 @@ use std::{any::TypeId, sync::mpsc::Sender};
use crate::{ use crate::{
layout::{EVENT_TYPES, EventManager, WIDGETS, WidgetId, WidgetUpdate}, layout::{EVENT_TYPES, EventManager, WIDGETS, WidgetId, WidgetUpdate},
util::{HashSet, RefGuardMut}, util::{Handle, HashSet},
}; };
pub struct WidgetData<W: ?Sized> { pub struct WidgetData<W: ?Sized> {
@@ -14,16 +14,10 @@ pub struct WidgetData<W: ?Sized> {
} }
impl<W: ?Sized> WidgetData<W> { impl<W: ?Sized> WidgetData<W> {
pub(crate) fn event_managers(&self) -> impl Iterator<Item = RefGuardMut<'_, dyn EventManager>> { pub(crate) fn event_managers(&self) -> impl Iterator<Item = Handle<dyn EventManager>> {
self.event_managers.iter().map(|id| { self.event_managers
EVENT_TYPES .iter()
.lock() .map(|id| EVENT_TYPES.lock().unwrap().get_mut(id).unwrap().clone())
.unwrap()
.get_mut(id)
.unwrap()
.clone()
.get_take_mut()
})
} }
} }
@@ -31,10 +25,7 @@ impl<W: ?Sized> Drop for WidgetData<W> {
fn drop(&mut self) { fn drop(&mut self) {
WIDGETS.remove(self.id); WIDGETS.remove(self.id);
for mut m in self.event_managers() { for mut m in self.event_managers() {
// refer to src/layout/event.rs for why this is like this m.remove(self.id);
let stuff = m.remove(self.id);
drop(m);
drop(stuff);
} }
} }
} }

View File

@@ -164,12 +164,12 @@ impl WidgetId {
WidgetRef::new(self) WidgetRef::new(self)
} }
pub(crate) fn map_event_managers(&self, f: impl Fn(&mut dyn EventManager)) { pub(crate) fn map_event_managers(&self, f: impl Fn(Handle<dyn EventManager>)) {
let Some(data) = self.weak().data() else { let Some(data) = self.weak().data() else {
return; return;
}; };
for mut m in data.event_managers() { for m in data.event_managers() {
f(&mut *m) f(m)
} }
} }
} }