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);
}
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> {
/// so... there is a deadlock if this is called in WidgetData::drop
/// and some function in here owns another WidgetId
/// 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> {
let contents = self.map.remove(&id);
for ui in self.active.values_mut() {

View File

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

View File

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

View File

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

View File

@@ -164,12 +164,12 @@ impl WidgetId {
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 {
return;
};
for mut m in data.event_managers() {
f(&mut *m)
for m in data.event_managers() {
f(m)
}
}
}