iris: share resource handle bookkeeping
This commit is contained in:
1 parent
51719ed121
commit
1be6cc2248
9 files changed
+631
-217
No files matched your search
+36
-5
@@ -5,6 +5,10 @@ pub struct SlotId {
|
||||
}
|
||||
|
||||
impl SlotId {
|
||||
pub(crate) fn slot(self) -> u32 {
|
||||
self.idx
|
||||
}
|
||||
|
||||
/// A stable, collision-free `u64` encoding of this id -- for a caller
|
||||
/// (accesskit's `NodeId`, today) that wants a flat integer key rather
|
||||
/// than the two `u32`s. `idx` is offset by one so no real id ever
|
||||
@@ -18,6 +22,7 @@ impl SlotId {
|
||||
pub struct SlotVec<T> {
|
||||
data: Vec<(u32, Option<T>)>,
|
||||
free: Vec<u32>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<T> SlotVec<T> {
|
||||
@@ -25,11 +30,12 @@ impl<T> SlotVec<T> {
|
||||
Self {
|
||||
data: Default::default(),
|
||||
free: Default::default(),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, x: T) -> SlotId {
|
||||
if let Some(idx) = self.free.pop() {
|
||||
let id = if let Some(idx) = self.free.pop() {
|
||||
let (genr, data) = &mut self.data[idx as usize];
|
||||
*data = Some(x);
|
||||
SlotId { idx, genr: *genr }
|
||||
@@ -38,14 +44,35 @@ impl<T> SlotVec<T> {
|
||||
let genr = 0;
|
||||
self.data.push((genr, Some(x)));
|
||||
SlotId { idx, genr }
|
||||
}
|
||||
};
|
||||
self.len += 1;
|
||||
id
|
||||
}
|
||||
|
||||
pub fn free(&mut self, id: SlotId) {
|
||||
let _ = self.remove(id);
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, id: SlotId) -> Option<T> {
|
||||
self.remove_inner(id, true)
|
||||
}
|
||||
|
||||
pub fn remove_unrecycled(&mut self, id: SlotId) -> Option<T> {
|
||||
self.remove_inner(id, false)
|
||||
}
|
||||
|
||||
fn remove_inner(&mut self, id: SlotId, recycle: bool) -> Option<T> {
|
||||
let (genr, data) = &mut self.data[id.idx as usize];
|
||||
if *genr != id.genr {
|
||||
return None;
|
||||
}
|
||||
*genr += 1;
|
||||
*data = None;
|
||||
self.free.push(id.idx);
|
||||
let value = data.take()?;
|
||||
self.len -= 1;
|
||||
if recycle {
|
||||
self.free.push(id.idx);
|
||||
}
|
||||
Some(value)
|
||||
}
|
||||
|
||||
pub fn get(&self, id: SlotId) -> Option<&T> {
|
||||
@@ -65,7 +92,7 @@ impl<T> SlotVec<T> {
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len() - self.free.len()
|
||||
self.len
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
@@ -75,6 +102,10 @@ impl<T> SlotVec<T> {
|
||||
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
|
||||
self.data.iter_mut().filter_map(|(_, value)| value.as_mut())
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for SlotVec<T> {
|
||||
|
||||
Reference in new issue
Block a user