webrender/prim_store/
storage.rs1use std::{ops, marker::PhantomData, u32};
6use crate::util::Recycler;
7
8#[derive(Debug, Hash)]
9#[cfg_attr(feature = "capture", derive(Serialize))]
10#[cfg_attr(feature = "replay", derive(Deserialize))]
11pub struct Index<T>(pub u32, PhantomData<T>);
12
13impl<T> Index<T> {
14 pub fn from_u32(idx: u32) -> Self {
17 Index(idx, PhantomData)
18 }
19}
20
21impl<T> Clone for Index<T> {
24 fn clone(&self) -> Self { *self }
25}
26
27impl<T> Copy for Index<T> {}
28
29impl<T> PartialEq for Index<T> {
30 fn eq(&self, other: &Self) -> bool {
31 self.0 == other.0
32 }
33}
34
35impl<T> Index<T> {
36 fn new(idx: usize) -> Self {
37 debug_assert!(idx < u32::max_value() as usize);
38 Index(idx as u32, PhantomData)
39 }
40
41 pub const INVALID: Index<T> = Index(u32::MAX, PhantomData);
42 pub const UNUSED: Index<T> = Index(u32::MAX-1, PhantomData);
43}
44
45#[derive(Debug)]
46pub struct OpenRange<T> {
47 start: Index<T>,
48}
49
50#[derive(Debug)]
51#[cfg_attr(feature = "capture", derive(Serialize))]
52pub struct Range<T> {
53 pub start: Index<T>,
54 pub end: Index<T>,
55}
56
57impl<T> Clone for Range<T> {
60 fn clone(&self) -> Self {
61 Range { start: self.start, end: self.end }
62 }
63}
64impl<T> Copy for Range<T> {}
65
66impl<T> Range<T> {
67 pub fn empty() -> Self {
69 Range {
70 start: Index::new(0),
71 end: Index::new(0),
72 }
73 }
74
75 pub fn is_empty(self) -> bool {
77 self.start.0 >= self.end.0
78 }
79}
80
81#[cfg_attr(feature = "capture", derive(Serialize))]
82pub struct Storage<T> {
83 data: Vec<T>,
84 #[cfg(debug_assertions)]
89 open_count: u32,
90}
91
92impl<T> Storage<T> {
93 pub fn new(initial_capacity: usize) -> Self {
94 Storage {
95 data: Vec::with_capacity(initial_capacity),
96 #[cfg(debug_assertions)]
97 open_count: 0,
98 }
99 }
100
101 pub fn len(&self) -> usize {
102 self.data.len()
103 }
104
105 pub fn clear(&mut self) {
106 #[cfg(debug_assertions)]
107 debug_assert_eq!(
108 self.open_count, 0,
109 "Storage::clear with {} open range(s) — open_range without close_range",
110 self.open_count,
111 );
112 self.data.clear();
113 }
114
115 pub fn push(&mut self, t: T) -> Index<T> {
116 let index = self.data.len();
117 self.data.push(t);
118 Index(index as u32, PhantomData)
119 }
120
121 pub fn reserve(&mut self, count: usize) {
122 self.data.reserve(count);
123 }
124
125 pub fn recycle(&mut self, recycler: &mut Recycler) {
126 #[cfg(debug_assertions)]
127 debug_assert_eq!(
128 self.open_count, 0,
129 "Storage::recycle with {} open range(s) — open_range without close_range",
130 self.open_count,
131 );
132 recycler.recycle_vec(&mut self.data);
133 }
134
135 pub fn extend<II: IntoIterator<Item=T>>(&mut self, iter: II) -> Range<T> {
136 let range = self.open_range();
137 self.data.extend(iter);
138
139 self.close_range(range)
140 }
141
142 pub fn data_mut(&mut self) -> &mut Vec<T> {
149 &mut self.data
150 }
151
152 pub fn open_range(&mut self) -> OpenRange<T> {
153 #[cfg(debug_assertions)]
154 {
155 self.open_count += 1;
156 }
157 OpenRange {
158 start: Index::new(self.data.len())
159 }
160 }
161
162 pub fn close_range(&mut self, range: OpenRange<T>) -> Range<T> {
163 #[cfg(debug_assertions)]
164 {
165 debug_assert!(
166 self.open_count > 0,
167 "Storage::close_range with no matching open_range",
168 );
169 self.open_count -= 1;
170 }
171 Range {
172 start: range.start,
173 end: Index::new(self.data.len()),
174 }
175 }
176}
177
178impl<T> ops::Index<Index<T>> for Storage<T> {
179 type Output = T;
180 fn index(&self, index: Index<T>) -> &Self::Output {
181 &self.data[index.0 as usize]
182 }
183}
184
185impl<T> ops::IndexMut<Index<T>> for Storage<T> {
186 fn index_mut(&mut self, index: Index<T>) -> &mut Self::Output {
187 &mut self.data[index.0 as usize]
188 }
189}
190
191impl<T> ops::Index<Range<T>> for Storage<T> {
192 type Output = [T];
193 fn index(&self, index: Range<T>) -> &Self::Output {
194 let start = index.start.0 as _;
195 let end = index.end.0 as _;
196 &self.data[start..end]
197 }
198}
199
200impl<T> ops::IndexMut<Range<T>> for Storage<T> {
201 fn index_mut(&mut self, index: Range<T>) -> &mut Self::Output {
202 let start = index.start.0 as _;
203 let end = index.end.0 as _;
204 &mut self.data[start..end]
205 }
206}