switch away from handles to refs that must be upgraded once
This commit is contained in:
@@ -1,15 +1,27 @@
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use crate::{
|
||||
IdLike, Widget, WidgetData, WidgetId,
|
||||
IdLike, Widget, WidgetData, WidgetHandle, WidgetId, WidgetRef,
|
||||
util::{DynBorrower, HashSet, SlotVec, forget_mut, to_mut},
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Widgets {
|
||||
pub needs_redraw: HashSet<WidgetId>,
|
||||
vec: SlotVec<WidgetData>,
|
||||
send: Sender<WidgetId>,
|
||||
pub(crate) waiting: HashSet<WidgetId>,
|
||||
}
|
||||
|
||||
impl Widgets {
|
||||
pub fn new(send: Sender<WidgetId>) -> Self {
|
||||
Self {
|
||||
needs_redraw: Default::default(),
|
||||
vec: Default::default(),
|
||||
waiting: Default::default(),
|
||||
send,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_updates(&self) -> bool {
|
||||
!self.needs_redraw.is_empty()
|
||||
}
|
||||
@@ -37,20 +49,37 @@ impl Widgets {
|
||||
|
||||
pub fn get<I: IdLike>(&self, id: &I) -> Option<&I::Widget>
|
||||
where
|
||||
I::Widget: Sized,
|
||||
I::Widget: Sized + Widget,
|
||||
{
|
||||
self.get_dyn(id.id())?.as_any().downcast_ref()
|
||||
}
|
||||
|
||||
pub fn get_mut<I: IdLike>(&mut self, id: &I) -> Option<&mut I::Widget>
|
||||
where
|
||||
I::Widget: Sized,
|
||||
I::Widget: Sized + Widget,
|
||||
{
|
||||
self.get_dyn_mut(id.id())?.as_any_mut().downcast_mut()
|
||||
}
|
||||
|
||||
pub fn add<W: Widget>(&mut self, widget: W) -> WidgetId {
|
||||
self.vec.add(WidgetData::new(widget))
|
||||
pub fn add_strong<W: Widget>(&mut self, widget: W) -> WidgetHandle<W> {
|
||||
let id = self.vec.add(WidgetData::new(widget));
|
||||
WidgetHandle::new(id, self.send.clone())
|
||||
}
|
||||
|
||||
pub fn add_weak<W: Widget>(&mut self, widget: W) -> WidgetRef<W> {
|
||||
let id = self.vec.add(WidgetData::new(widget));
|
||||
self.waiting.insert(id);
|
||||
WidgetRef::new(id)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn upgrade<W: ?Sized>(&mut self, rf: WidgetRef<W>) -> WidgetHandle<W> {
|
||||
if !self.waiting.remove(&rf.id()) {
|
||||
let label = self.label(rf);
|
||||
let id = rf.id();
|
||||
panic!("widget '{label}' ({id:?}) was already added\ncannot add a widget twice; consider creating two")
|
||||
}
|
||||
WidgetHandle::new(rf.id(), self.send.clone())
|
||||
}
|
||||
|
||||
pub fn data(&self, id: impl IdLike) -> Option<&WidgetData> {
|
||||
|
||||
Reference in New Issue
Block a user