rg3d_core/
sparse.rs

1use std::{
2    fmt::{Debug, Formatter},
3    marker::PhantomData,
4    sync::atomic::{AtomicUsize, Ordering},
5};
6
7pub struct AtomicIndex<T> {
8    index: AtomicUsize,
9    phantom: PhantomData<T>,
10}
11
12impl<T> Debug for AtomicIndex<T> {
13    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
14        write!(f, "AtomicIndex: {}", self.get())
15    }
16}
17
18unsafe impl<T> Send for AtomicIndex<T> {}
19unsafe impl<T> Sync for AtomicIndex<T> {}
20
21impl<T> Clone for AtomicIndex<T> {
22    fn clone(&self) -> Self {
23        Self {
24            index: AtomicUsize::new(self.index.load(Ordering::SeqCst)),
25            phantom: PhantomData,
26        }
27    }
28}
29
30impl<T> Default for AtomicIndex<T> {
31    fn default() -> Self {
32        Self::unassigned()
33    }
34}
35
36impl<T> AtomicIndex<T> {
37    pub fn unassigned() -> Self {
38        Self {
39            index: AtomicUsize::new(usize::MAX),
40            phantom: PhantomData,
41        }
42    }
43
44    fn new(index: usize) -> Self {
45        Self {
46            index: AtomicUsize::new(index),
47            phantom: PhantomData,
48        }
49    }
50
51    pub fn set(&self, index: usize) {
52        self.index.store(index, Ordering::SeqCst)
53    }
54
55    pub fn get(&self) -> usize {
56        self.index.load(Ordering::SeqCst)
57    }
58}
59
60pub struct SparseBuffer<T> {
61    vec: Vec<Option<T>>,
62    free: Vec<usize>,
63}
64
65impl<T> Default for SparseBuffer<T> {
66    fn default() -> Self {
67        Self {
68            vec: Default::default(),
69            free: Default::default(),
70        }
71    }
72}
73
74impl<T: Clone> Clone for SparseBuffer<T> {
75    fn clone(&self) -> Self {
76        Self {
77            vec: self.vec.clone(),
78            free: self.free.clone(),
79        }
80    }
81}
82
83impl<T> SparseBuffer<T> {
84    pub fn with_capacity(capacity: usize) -> Self {
85        Self {
86            vec: Vec::with_capacity(capacity),
87            free: vec![],
88        }
89    }
90
91    pub fn spawn(&mut self, payload: T) -> AtomicIndex<T> {
92        match self.free.pop() {
93            Some(free) => {
94                let old = self.vec[free].replace(payload);
95                debug_assert!(old.is_none());
96                AtomicIndex::new(free)
97            }
98            None => {
99                let index = AtomicIndex::new(self.vec.len());
100                self.vec.push(Some(payload));
101                index
102            }
103        }
104    }
105
106    pub fn free(&mut self, index: &AtomicIndex<T>) -> Option<T> {
107        self.free_raw(index.get())
108    }
109
110    pub fn free_raw(&mut self, index: usize) -> Option<T> {
111        match self.vec.get_mut(index) {
112            Some(entry) => match entry.take() {
113                Some(payload) => {
114                    self.free.push(index);
115                    Some(payload)
116                }
117                None => None,
118            },
119            None => None,
120        }
121    }
122
123    pub fn len(&self) -> usize {
124        self.vec.len()
125    }
126
127    pub fn is_empty(&self) -> bool {
128        self.filled() == 0
129    }
130
131    pub fn filled(&self) -> usize {
132        self.vec.len() - self.free.len()
133    }
134
135    pub fn is_index_valid(&self, index: &AtomicIndex<T>) -> bool {
136        self.get(index).is_some()
137    }
138
139    pub fn get(&self, index: &AtomicIndex<T>) -> Option<&T> {
140        self.get_raw(index.get())
141    }
142
143    pub fn get_mut(&mut self, index: &AtomicIndex<T>) -> Option<&mut T> {
144        self.get_mut_raw(index.get())
145    }
146
147    pub fn get_raw(&self, index: usize) -> Option<&T> {
148        self.vec.get(index).and_then(|entry| entry.as_ref())
149    }
150
151    pub fn get_mut_raw(&mut self, index: usize) -> Option<&mut T> {
152        self.vec.get_mut(index).and_then(|entry| entry.as_mut())
153    }
154
155    pub fn iter(&self) -> impl Iterator<Item = &T> {
156        self.vec.iter().filter_map(|entry| entry.as_ref())
157    }
158
159    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
160        self.vec.iter_mut().filter_map(|entry| entry.as_mut())
161    }
162
163    pub fn clear(&mut self) {
164        self.vec.clear();
165        self.free.clear();
166    }
167}