From 123f3e6e2bffd064946b3f3fc4229064fcd9155c Mon Sep 17 00:00:00 2001 From: shadow cat Date: Thu, 11 Dec 2025 01:34:14 -0500 Subject: [PATCH] stuffff --- core/src/layout/event.rs | 17 +++++++++++++++++ core/src/layout/painter.rs | 4 ++-- core/src/layout/ui.rs | 2 +- core/src/layout/widget/data.rs | 21 ++++++--------------- core/src/layout/widget/handle.rs | 6 +++--- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/core/src/layout/event.rs b/core/src/layout/event.rs index 3a59ba0..0ed7fe3 100644 --- a/core/src/layout/event.rs +++ b/core/src/layout/event.rs @@ -53,10 +53,27 @@ pub trait EventManager: Any + Send + Sync { fn undraw(&mut self, ui: UiId, inst: &WidgetInstance); } +impl Handle { + 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 EventManager for Events { /// 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 fn remove(&mut self, id: WidgetId) -> Box { let contents = self.map.remove(&id); for ui in self.active.values_mut() { diff --git a/core/src/layout/painter.rs b/core/src/layout/painter.rs index deb2b8c..b10659f 100644 --- a/core/src/layout/painter.rs +++ b/core/src/layout/painter.rs @@ -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); }); } diff --git a/core/src/layout/ui.rs b/core/src/layout/ui.rs index 0c142ba..648b052 100644 --- a/core/src/layout/ui.rs +++ b/core/src/layout/ui.rs @@ -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); }); } diff --git a/core/src/layout/widget/data.rs b/core/src/layout/widget/data.rs index a72795a..f792b92 100644 --- a/core/src/layout/widget/data.rs +++ b/core/src/layout/widget/data.rs @@ -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 { @@ -14,16 +14,10 @@ pub struct WidgetData { } impl WidgetData { - pub(crate) fn event_managers(&self) -> impl Iterator> { - 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> { + self.event_managers + .iter() + .map(|id| EVENT_TYPES.lock().unwrap().get_mut(id).unwrap().clone()) } } @@ -31,10 +25,7 @@ impl Drop for WidgetData { 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); } } } diff --git a/core/src/layout/widget/handle.rs b/core/src/layout/widget/handle.rs index 20b2016..a08dc48 100644 --- a/core/src/layout/widget/handle.rs +++ b/core/src/layout/widget/handle.rs @@ -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)) { 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) } } }