rapier3d/data/
coarena.rs

1use crate::data::arena::Index;
2
3#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
4#[derive(Clone, Debug, Default)]
5/// A container for data associated to item existing into another Arena.
6pub struct Coarena<T> {
7    data: Vec<(u32, T)>,
8}
9
10impl<T> Coarena<T> {
11    /// A coarena with no element.
12    pub fn new() -> Self {
13        Self { data: Vec::new() }
14    }
15
16    /// Pre-allocates capacity for `additional` extra elements in this arena.
17    pub fn reserve(&mut self, additional: usize) {
18        self.data.reserve(additional);
19    }
20
21    /// Iterates through all the elements of this coarena.
22    pub fn iter(&self) -> impl Iterator<Item = (Index, &T)> {
23        self.data
24            .iter()
25            .enumerate()
26            .filter(|(_, elt)| elt.0 != u32::MAX)
27            .map(|(i, elt)| (Index::from_raw_parts(i as u32, elt.0), &elt.1))
28    }
29
30    /// Gets a specific element from the coarena without specifying its generation number.
31    ///
32    /// It is strongly encouraged to use `Coarena::get` instead of this method because this method
33    /// can suffer from the ABA problem.
34    pub fn get_unknown_gen(&self, index: u32) -> Option<&T> {
35        self.data.get(index as usize).map(|(_, t)| t)
36    }
37
38    /// Gets a specific mutable element from the coarena without specifying its generation number.
39    ///
40    /// It is strongly encouraged to use `Coarena::get_mut` instead of this method because this method
41    /// can suffer from the ABA problem.
42    pub fn get_mut_unknown_gen(&mut self, index: u32) -> Option<&mut T> {
43        self.data.get_mut(index as usize).map(|(_, t)| t)
44    }
45
46    pub(crate) fn get_gen(&self, index: u32) -> Option<u32> {
47        self.data
48            .get(index as usize)
49            .map(|(generation, _)| *generation)
50    }
51
52    /// Deletes an element for the coarena and returns its value.
53    ///
54    /// This method will reset the value to the given `removed_value`.
55    pub fn remove(&mut self, index: Index, removed_value: T) -> Option<T> {
56        let (i, g) = index.into_raw_parts();
57        let data = self.data.get_mut(i as usize)?;
58        if g == data.0 {
59            data.0 = u32::MAX; // invalidate the generation number.
60            Some(std::mem::replace(&mut data.1, removed_value))
61        } else {
62            None
63        }
64    }
65
66    /// Gets a specific element from the coarena, if it exists.
67    pub fn get(&self, index: Index) -> Option<&T> {
68        let (i, g) = index.into_raw_parts();
69        self.data
70            .get(i as usize)
71            .and_then(|(gg, t)| if g == *gg { Some(t) } else { None })
72    }
73
74    /// Gets a mutable reference to a specific element from the coarena, if it exists.
75    pub fn get_mut(&mut self, index: Index) -> Option<&mut T> {
76        let (i, g) = index.into_raw_parts();
77        self.data
78            .get_mut(i as usize)
79            .and_then(|(gg, t)| if g == *gg { Some(t) } else { None })
80    }
81
82    /// Inserts an element into this coarena.
83    pub fn insert(&mut self, a: Index, value: T)
84    where
85        T: Clone + Default,
86    {
87        let (i1, g1) = a.into_raw_parts();
88
89        if self.data.len() <= i1 as usize {
90            self.data.resize(i1 as usize + 1, (u32::MAX, T::default()));
91        }
92
93        self.data[i1 as usize] = (g1, value);
94    }
95
96    /// Ensure that the given element exists in this coarena, and return its mutable reference.
97    pub fn ensure_element_exist(&mut self, a: Index, default: T) -> &mut T
98    where
99        T: Clone,
100    {
101        let (i1, g1) = a.into_raw_parts();
102
103        if self.data.len() <= i1 as usize {
104            self.data
105                .resize(i1 as usize + 1, (u32::MAX, default.clone()));
106        }
107
108        let data = &mut self.data[i1 as usize];
109
110        if data.0 != g1 {
111            *data = (g1, default);
112        }
113
114        &mut data.1
115    }
116
117    /// Ensure that elements at the two given indices exist in this coarena, and return their references.
118    ///
119    /// Missing elements are created automatically and initialized with the `default` value.
120    pub fn ensure_pair_exists(&mut self, a: Index, b: Index, default: T) -> (&mut T, &mut T)
121    where
122        T: Clone,
123    {
124        let (i1, g1) = a.into_raw_parts();
125        let (i2, g2) = b.into_raw_parts();
126
127        assert_ne!(i1, i2, "Cannot index the same object twice.");
128
129        let (elt1, elt2) = if i1 > i2 {
130            if self.data.len() <= i1 as usize {
131                self.data
132                    .resize(i1 as usize + 1, (u32::MAX, default.clone()));
133            }
134
135            let (left, right) = self.data.split_at_mut(i1 as usize);
136            (&mut right[0], &mut left[i2 as usize])
137        } else {
138            // i2 > i1
139            if self.data.len() <= i2 as usize {
140                self.data
141                    .resize(i2 as usize + 1, (u32::MAX, default.clone()));
142            }
143
144            let (left, right) = self.data.split_at_mut(i2 as usize);
145            (&mut left[i1 as usize], &mut right[0])
146        };
147
148        if elt1.0 != g1 {
149            *elt1 = (g1, default.clone());
150        }
151
152        if elt2.0 != g2 {
153            *elt2 = (g2, default);
154        }
155
156        (&mut elt1.1, &mut elt2.1)
157    }
158}