makepad_platform/
id_pool.rs1use std::{
2 cell::RefCell,
3 rc::Rc,
4 ops::Deref,
5 ops::DerefMut,
6};
7
8#[derive(Clone, Default, Debug, PartialEq)]
9pub struct IdPoolFree(Rc<RefCell<Vec<usize >> >);
10
11#[derive(Default, Debug)]
12pub struct IdPool<T> where T: Default {
13 pub pool: Vec<IdPoolItem<T >>,
14 pub free: IdPoolFree
15}
16
17#[derive(Debug, PartialEq)]
18pub struct IdPoolItem<T> {
19 pub item: T,
20 pub generation: u64,
21}
22
23impl<T> Deref for IdPoolItem<T> {
24 type Target = T;
25 fn deref(&self) -> &Self::Target {&self.item}
26}
27
28impl<T> DerefMut for IdPoolItem<T> {
29 fn deref_mut(&mut self) -> &mut Self::Target {&mut self.item}
30}
31
32#[derive(Debug, PartialEq)]
33pub struct PoolId {
34 pub id: usize,
35 pub generation: u64,
36 pub free: IdPoolFree
37}
38
39impl Drop for PoolId {
40 fn drop(&mut self) {
41 self.free.0.borrow_mut().push(self.id)
42 }
43}
44
45impl<T> IdPool<T> where T: Default {
46 pub fn alloc(&mut self) -> PoolId {
47 let last_from_free_pool = self.free.0.borrow_mut().pop();
48 if let Some(id) = last_from_free_pool {
49 self.pool[id].generation += 1;
50 PoolId {
51 id,
52 generation: self.pool[id].generation,
53 free: self.free.clone()
54 }
55 }
56 else {
57 self.alloc_new(None)
58 }
59 }
60
61 pub fn alloc_new(&mut self, item: Option<T>) -> PoolId {
62 let id = self.pool.len();
63 self.pool.push(IdPoolItem {
64 generation: 0,
65 item: item.unwrap_or_else(|| T::default())
66 });
67 PoolId {
68 id,
69 generation: 0,
70 free: self.free.clone()
71 }
72 }
73
74 pub fn alloc_with_reuse_filter<F>(&mut self, mut filter: F, item: T) -> (PoolId, Option<T>)
88 where F: FnMut(&IdPoolItem<T>) -> bool {
89 let maybe_free_id = self.free.0.borrow_mut()
90 .iter()
91 .enumerate()
92 .find_map(|(index, &id)| {
93 if filter(&self.pool[id]) {
94 Some((index, id))
95 } else {
96 None
97 }
98 });
99
100 if let Some((index, id)) = maybe_free_id {
101 self.free.0.borrow_mut().remove(index);
102 self.pool[id].generation += 1;
103 let old_item = std::mem::replace(&mut self.pool[id].item, item);
104
105 let pool_id = PoolId {
106 id,
107 generation: self.pool[id].generation,
108 free: self.free.clone()
109 };
110 (pool_id, Some(old_item))
111 } else {
112 (self.alloc_new(Some(item)), None)
113 }
114 }
115}