vizia_core/storage/
style_set.rs
1#![allow(unused)]
2use crate::prelude::*;
3
4use vizia_storage::{SparseSetGeneric, SparseSetIndex};
5
6const INDEX_MASK: u32 = u32::MAX / 4;
7const INLINE_MASK: u32 = 1 << 31;
8const INHERITED_MASK: u32 = 1 << 30;
9
10#[derive(Debug, Clone, Copy, PartialEq)]
19struct DataIndex(u32);
20
21impl DataIndex {
22 pub fn inline(index: usize) -> Self {
25 assert!((index as u32) < INDEX_MASK);
26 let value = (index as u32) | INLINE_MASK;
27 Self(value)
28 }
29
30 pub fn inherited(self) -> Self {
31 let value = self.0;
32 Self(value | INHERITED_MASK)
33 }
34
35 pub fn shared(index: usize) -> Self {
38 assert!((index as u32) < INDEX_MASK);
39 Self(index as u32)
40 }
41
42 pub fn index(&self) -> usize {
44 (self.0 & INDEX_MASK) as usize
45 }
46
47 pub fn is_inline(&self) -> bool {
49 (self.0 & INLINE_MASK).rotate_left(1) != 0
50 }
51
52 pub fn is_inherited(&self) -> bool {
54 (self.0 & INHERITED_MASK).rotate_left(2) != 0
55 }
56
57 pub fn null() -> Self {
61 Self(u32::MAX >> 1)
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq)]
67struct Index {
68 data_index: DataIndex,
69 anim_index: u32,
70}
71
72impl Default for Index {
73 fn default() -> Self {
74 Index { data_index: DataIndex::null(), anim_index: u32::MAX }
75 }
76}
77
78impl SparseSetIndex for Index {
79 fn new(index: usize) -> Self {
80 Index { data_index: DataIndex::inline(index), anim_index: u32::MAX }
81 }
82
83 fn null() -> Self {
84 Self::default()
85 }
86
87 fn index(&self) -> usize {
88 self.data_index.index()
89 }
90}
91
92pub struct StyleSet<T> {
99 shared_data: SparseSetGeneric<Index, T>,
101 inline_data: SparseSetGeneric<Index, T>,
103}
104
105impl<T> Default for StyleSet<T> {
106 fn default() -> Self {
107 Self { shared_data: Default::default(), inline_data: Default::default() }
108 }
109}
110
111impl<T> StyleSet<T>
112where
113 T: 'static + std::fmt::Debug,
114{
115 pub fn new() -> Self {
117 Self::default()
118 }
119
120 pub fn insert(&mut self, entity: Entity, value: T) {
122 self.inline_data.insert(entity, value);
123 }
124
125 pub fn remove(&mut self, entity: Entity) -> Option<T> {
127 let entity_index = entity.index();
128
129 if entity_index < self.inline_data.sparse.len() {
130 let data_index = self.inline_data.sparse[entity_index].data_index;
131 if data_index.is_inline() && !data_index.is_inherited() {
132 self.inline_data.remove(entity)
133 } else {
134 self.inline_data.sparse[entity_index] = Index::null();
135 None
136 }
137 } else {
138 None
139 }
140 }
141
142 pub fn inherit_inline(&mut self, entity: Entity, parent: Entity) -> bool {
143 let entity_index = entity.index();
144 let parent_index = parent.index();
145
146 if parent_index < self.inline_data.sparse.len() {
147 let parent_sparse_index = self.inline_data.sparse[parent_index];
148
149 if parent_sparse_index.data_index.is_inline()
150 && parent_sparse_index.data_index.index() < self.inline_data.dense.len()
151 {
152 if entity_index >= self.inline_data.sparse.len() {
153 self.inline_data.sparse.resize(entity_index + 1, Index::null());
154 }
155
156 let entity_sparse_index = self.inline_data.sparse[entity_index];
157
158 if self.inline_data.sparse[entity_index].data_index.index()
159 != parent_sparse_index.data_index.index()
160 {
161 if entity_sparse_index.data_index.index() < self.inline_data.dense.len() {
162 if entity_sparse_index.data_index.is_inherited()
163 && entity_sparse_index.data_index.is_inline()
164 {
165 self.inline_data.sparse[entity_index] = Index {
166 data_index: DataIndex::inline(
167 parent_sparse_index.data_index.index(),
168 )
169 .inherited(),
170 anim_index: u32::MAX,
171 };
172 return true;
173 }
174 } else {
175 self.inline_data.sparse[entity_index] = Index {
176 data_index: DataIndex::inline(parent_sparse_index.data_index.index())
177 .inherited(),
178 anim_index: u32::MAX,
179 };
180 return true;
181 }
182 }
183 }
184 }
185
186 false
187 }
188
189 pub fn inherit_shared(&mut self, entity: Entity, parent: Entity) -> bool {
190 let entity_index = entity.index();
191 let parent_index = parent.index();
192
193 if parent_index < self.inline_data.sparse.len() {
194 let parent_sparse_index = self.inline_data.sparse[parent_index];
195
196 if !parent_sparse_index.data_index.is_inline()
197 && parent_sparse_index.data_index.index() < self.shared_data.dense.len()
198 {
199 if entity_index >= self.inline_data.sparse.len() {
200 self.inline_data.sparse.resize(entity_index + 1, Index::null());
201 }
202
203 let entity_sparse_index = self.inline_data.sparse[entity_index];
204
205 if !entity_sparse_index.data_index.is_inline()
206 && self.inline_data.sparse[entity_index].data_index.index()
207 != parent_sparse_index.data_index.index()
208 {
209 if entity_sparse_index.data_index.index() < self.shared_data.dense.len() {
210 if entity_sparse_index.data_index.is_inherited() {
211 self.inline_data.sparse[entity_index] = Index {
212 data_index: DataIndex::shared(
213 parent_sparse_index.data_index.index(),
214 )
215 .inherited(),
216 anim_index: u32::MAX,
217 };
218 return true;
219 }
220 } else {
221 self.inline_data.sparse[entity_index] = Index {
222 data_index: DataIndex::shared(parent_sparse_index.data_index.index())
223 .inherited(),
224 anim_index: u32::MAX,
225 };
226
227 return true;
228 }
229 }
230 }
231 }
232
233 false
234 }
235
236 pub fn clear_rules(&mut self) {
237 for _index in self.shared_data.sparse.iter() {
239 }
241
242 self.shared_data.clear();
243
244 for index in self.inline_data.sparse.iter_mut() {
245 if !index.data_index.is_inline() {
246 index.data_index = DataIndex::null();
247 }
248 }
249 }
250
251 pub(crate) fn insert_rule(&mut self, rule: Rule, value: T) {
252 self.shared_data.insert(rule, value);
253 }
254
255 pub fn get_inline(&self, entity: Entity) -> Option<&T> {
261 let entity_index = entity.index();
262 if entity_index < self.inline_data.sparse.len() {
263 let data_index = self.inline_data.sparse[entity_index].data_index;
264 if data_index.is_inline() {
265 return self.inline_data.get(entity);
266 }
267 }
268
269 None
270 }
271
272 pub fn get_inline_mut(&mut self, entity: Entity) -> Option<&mut T> {
274 let entity_index = entity.index();
275 if entity_index < self.inline_data.sparse.len() {
276 let data_index = self.inline_data.sparse[entity_index].data_index;
277 if data_index.is_inline() {
278 return self.inline_data.get_mut(entity);
279 }
280 }
281
282 None
283 }
284
285 pub fn get(&self, entity: Entity) -> Option<&T> {
297 let entity_index = entity.index();
298 if entity_index < self.inline_data.sparse.len() {
299 let data_index = self.inline_data.sparse[entity_index].data_index;
300 if data_index.is_inline() {
301 if data_index.index() < self.inline_data.dense.len() {
302 return Some(&self.inline_data.dense[data_index.index()].value);
303 }
304 } else if data_index.index() < self.shared_data.dense.len() {
305 return Some(&self.shared_data.dense[data_index.index()].value);
306 }
307 }
308
309 None
310 }
311
312 pub fn get_mut(&mut self, entity: Entity) -> Option<&mut T> {
313 let entity_index = entity.index();
314 if entity_index < self.inline_data.sparse.len() {
315 let data_index = self.inline_data.sparse[entity_index].data_index;
316 if data_index.is_inline() && data_index.index() < self.inline_data.dense.len() {
317 return Some(&mut self.inline_data.dense[data_index.index()].value);
318 }
319 }
320
321 None
322 }
323
324 pub(crate) fn link(&mut self, entity: Entity, rules: &[(Rule, u32)]) -> bool {
326 let entity_index = entity.index();
327
328 if entity_index < self.inline_data.sparse.len() {
330 let data_index = self.inline_data.sparse[entity_index].data_index;
331 if data_index.is_inline() && !data_index.is_inherited() {
333 return false;
334 }
335 }
336
337 for (rule, _) in rules {
339 if let Some(shared_data_index) = self.shared_data.dense_idx(*rule) {
340 if entity_index >= self.inline_data.sparse.len() {
342 self.inline_data.sparse.resize(entity_index + 1, Index::null());
343 }
344
345 let data_index = self.inline_data.sparse[entity_index].data_index;
346 if !data_index.is_inline() && data_index.index() == shared_data_index.index() {
348 return false;
349 }
350
351 self.inline_data.sparse[entity_index].data_index =
352 DataIndex::shared(shared_data_index.index());
353
354 return true;
355 }
356 }
357
358 if entity_index < self.inline_data.sparse.len() {
360 let data_index = self.inline_data.sparse[entity_index].data_index;
361 if !data_index.is_inline()
362 && !data_index.is_inherited()
363 && self.inline_data.sparse[entity_index].data_index != DataIndex::null()
364 {
365 self.inline_data.sparse[entity_index].data_index = DataIndex::null();
366 return true;
367 }
368 }
369
370 false
371 }
372}
373
374#[cfg(test)]
375mod tests {
376 use super::*;
377
378 #[test]
382 fn inline() {
383 let data_index = DataIndex::inline(5);
384 assert_eq!(data_index.0, INLINE_MASK + 5);
385 assert_eq!(data_index.index(), 5);
386 }
387
388 #[test]
390 #[should_panic]
391 fn invalid_inline() {
392 DataIndex::inline(usize::MAX);
393 }
394
395 #[test]
397 fn shared() {
398 let data_index = DataIndex::shared(5);
399 assert_eq!(data_index.0, 5);
400 assert_eq!(data_index.index(), 5);
401 }
402
403 #[test]
405 #[should_panic]
406 fn invalid_shared() {
407 DataIndex::shared(usize::MAX);
408 }
409
410 #[test]
412 fn is_inline() {
413 let data_index1 = DataIndex::inline(5);
414 assert!(data_index1.is_inline());
415 let data_index2 = DataIndex::shared(5);
416 assert!(!data_index2.is_inline());
417 }
418
419 #[test]
421 fn null() {
422 let data_index = DataIndex::null();
423 assert_eq!(data_index.0, 2147483647);
424 }
425
426 #[test]
430 fn new() {
431 let animatable_storage = StyleSet::<f32>::new();
432 assert!(animatable_storage.inline_data.is_empty());
433 assert!(animatable_storage.shared_data.is_empty());
434 }
435
436 #[test]
438 fn insert_inline() {
439 let mut animatable_storage = StyleSet::new();
440 animatable_storage.insert(Entity::root(), 5.0);
441 }
443}