83 let mut data: Box<[u8; BLOCK_SIZE]> = |
83 let mut data: Box<[u8; BLOCK_SIZE]> = |
84 Box::new(unsafe { MaybeUninit::uninit().assume_init() }); |
84 Box::new(unsafe { MaybeUninit::uninit().assume_init() }); |
85 let mut blocks = [None; 64]; |
85 let mut blocks = [None; 64]; |
86 let mut offset = 0; |
86 let mut offset = 0; |
87 |
87 |
88 for i in 0..64 { |
88 for i in 0..element_sizes.len() { |
89 if mask & (1 << i) != 0 { |
89 if mask & (1 << i as u64) != 0 { |
90 blocks[i] = Some(NonNull::new(data[offset..].as_mut_ptr()).unwrap()); |
90 blocks[i] = Some(NonNull::new(data[offset..].as_mut_ptr()).unwrap()); |
91 offset += element_sizes[i] as usize * max_elements as usize; |
91 offset += element_sizes[i] as usize * max_elements as usize; |
92 } |
92 } |
93 } |
93 } |
94 Self { |
94 Self { |
133 fn get_type_index<T: 'static>(&self) -> Option<usize> { |
133 fn get_type_index<T: 'static>(&self) -> Option<usize> { |
134 let type_id = TypeId::of::<T>(); |
134 let type_id = TypeId::of::<T>(); |
135 self.types.iter().position(|id| *id == type_id) |
135 self.types.iter().position(|id| *id == type_id) |
136 } |
136 } |
137 |
137 |
138 fn move_between_blocks(&mut self, from_block_index: u16, from_index: u16, to_block_index: u16) { |
138 fn move_between_blocks( |
|
139 &mut self, |
|
140 from_block_index: u16, |
|
141 from_index: u16, |
|
142 to_block_index: u16, |
|
143 ) -> u16 { |
139 debug_assert!(from_block_index != to_block_index); |
144 debug_assert!(from_block_index != to_block_index); |
140 let source_mask = self.block_masks[from_block_index as usize]; |
145 let source_mask = self.block_masks[from_block_index as usize]; |
141 let destination_mask = self.block_masks[to_block_index as usize]; |
146 let destination_mask = self.block_masks[to_block_index as usize]; |
142 debug_assert!(source_mask & destination_mask == source_mask); |
147 debug_assert!(source_mask & destination_mask == source_mask); |
143 |
148 |
144 let source = &self.blocks[from_block_index as usize]; |
149 let source = &self.blocks[from_block_index as usize]; |
145 let destination = &self.blocks[to_block_index as usize]; |
150 let destination = &self.blocks[to_block_index as usize]; |
146 debug_assert!(from_index < source.elements_count); |
151 debug_assert!(from_index < source.elements_count); |
147 debug_assert!(!destination.is_full()); |
152 debug_assert!(!destination.is_full()); |
148 |
153 |
149 for i in 0..64 { |
154 let to_index = destination.elements_count; |
150 if source_mask & 1 << i != 0 { |
155 for i in 0..self.types.len() { |
|
156 if source_mask & 1 << i as u64 != 0 { |
151 unsafe { |
157 unsafe { |
152 copy_nonoverlapping( |
158 copy_nonoverlapping( |
153 source.component_blocks[i].unwrap().as_ptr(), |
159 source.component_blocks[i] |
154 destination.component_blocks[i].unwrap().as_ptr(), |
160 .unwrap() |
|
161 .as_ptr() |
|
162 .add((from_index * self.element_sizes[i]) as usize), |
|
163 destination.component_blocks[i] |
|
164 .unwrap() |
|
165 .as_ptr() |
|
166 .add((to_index * self.element_sizes[i]) as usize), |
155 self.element_sizes[i] as usize, |
167 self.element_sizes[i] as usize, |
156 ); |
168 ); |
157 } |
169 } |
158 } |
170 } |
159 } |
171 } |
160 self.blocks[from_block_index as usize].elements_count -= 1; |
172 self.blocks[from_block_index as usize].elements_count -= 1; |
161 self.blocks[to_block_index as usize].elements_count += 1; |
173 let destination = &mut self.blocks[to_block_index as usize]; |
162 } |
174 destination.elements_count += 1; |
163 |
175 destination.elements_count - 1 |
164 fn add_to_block<T: Clone>(&mut self, block_index: u16, value: &T) { |
176 } |
|
177 |
|
178 fn add_to_block<T: Clone>(&mut self, block_index: u16, value: &T) -> u16 { |
165 debug_assert!(self.block_masks[block_index as usize].count_ones() == 1); |
179 debug_assert!(self.block_masks[block_index as usize].count_ones() == 1); |
166 |
180 |
167 let block = &mut self.blocks[block_index as usize]; |
181 let block = &mut self.blocks[block_index as usize]; |
168 debug_assert!(block.elements_count < block.max_elements); |
182 debug_assert!(block.elements_count < block.max_elements); |
169 |
183 |
173 block.max_elements as usize, |
187 block.max_elements as usize, |
174 ); |
188 ); |
175 *slice.get_unchecked_mut(block.elements_count as usize) = value.clone(); |
189 *slice.get_unchecked_mut(block.elements_count as usize) = value.clone(); |
176 }; |
190 }; |
177 block.elements_count += 1; |
191 block.elements_count += 1; |
|
192 block.elements_count - 1 |
178 } |
193 } |
179 |
194 |
180 fn remove_from_block(&mut self, block_index: u16, index: u16) { |
195 fn remove_from_block(&mut self, block_index: u16, index: u16) { |
181 let block = &mut self.blocks[block_index as usize]; |
196 let block = &mut self.blocks[block_index as usize]; |
182 debug_assert!(index < block.elements_count); |
197 debug_assert!(index < block.elements_count); |
223 let mask = self.block_masks[entry.block_index as usize]; |
238 let mask = self.block_masks[entry.block_index as usize]; |
224 let new_mask = mask | type_bit; |
239 let new_mask = mask | type_bit; |
225 |
240 |
226 if new_mask != mask { |
241 if new_mask != mask { |
227 let dest_block_index = self.ensure_block(new_mask); |
242 let dest_block_index = self.ensure_block(new_mask); |
228 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
243 let dest_index = self.move_between_blocks( |
|
244 entry.block_index, |
|
245 index.get() - 1, |
|
246 dest_block_index, |
|
247 ); |
|
248 self.lookup[gear_id.get() as usize - 1] = LookupEntry { |
|
249 index: unsafe { |
|
250 Some(NonZeroU16::new_unchecked(dest_index.saturating_add(1))) |
|
251 }, |
|
252 block_index: dest_block_index, |
|
253 } |
229 } |
254 } |
230 } else { |
255 } else { |
231 let dest_block_index = self.ensure_block(type_bit); |
256 let dest_block_index = self.ensure_block(type_bit); |
232 self.add_to_block(dest_block_index, value); |
257 let index = self.add_to_block(dest_block_index, value); |
|
258 self.lookup[gear_id.get() as usize - 1] = LookupEntry { |
|
259 index: unsafe { Some(NonZeroU16::new_unchecked(index.saturating_add(1))) }, |
|
260 block_index: dest_block_index, |
|
261 } |
233 } |
262 } |
234 } else { |
263 } else { |
235 panic!("Unregistered type") |
264 panic!("Unregistered type") |
236 } |
265 } |
237 } |
266 } |
262 pub fn remove_all(&mut self, gear_id: GearId) { |
291 pub fn remove_all(&mut self, gear_id: GearId) { |
263 let entry = self.lookup[gear_id.get() as usize - 1]; |
292 let entry = self.lookup[gear_id.get() as usize - 1]; |
264 if let Some(index) = entry.index { |
293 if let Some(index) = entry.index { |
265 self.remove_from_block(entry.block_index, index.get() - 1); |
294 self.remove_from_block(entry.block_index, index.get() - 1); |
266 } |
295 } |
|
296 self.lookup[gear_id.get() as usize - 1] = LookupEntry { |
|
297 index: None, |
|
298 block_index: 0, |
|
299 } |
267 } |
300 } |
268 |
301 |
269 pub fn register<T: 'static>(&mut self) { |
302 pub fn register<T: 'static>(&mut self) { |
270 debug_assert!(!std::mem::needs_drop::<T>()); |
303 debug_assert!(!std::mem::needs_drop::<T>()); |
271 debug_assert!(self.types.len() <= 64); |
304 debug_assert!(self.types.len() <= 64); |
288 for (arg_index, type_id) in arg_types.iter().enumerate() { |
321 for (arg_index, type_id) in arg_types.iter().enumerate() { |
289 match self.types.iter().position(|t| t == type_id) { |
322 match self.types.iter().position(|t| t == type_id) { |
290 Some(i) if selector & 1 << i as u64 != 0 => panic!("Duplicate type"), |
323 Some(i) if selector & 1 << i as u64 != 0 => panic!("Duplicate type"), |
291 Some(i) => { |
324 Some(i) => { |
292 type_indices[arg_index] = i as i8; |
325 type_indices[arg_index] = i as i8; |
293 selector &= 1 << i as u64; |
326 selector |= 1 << i as u64; |
294 } |
327 } |
295 None => panic!("Unregistered type"), |
328 None => panic!("Unregistered type"), |
296 } |
329 } |
297 } |
330 } |
298 |
|
299 let mut slices = vec![null_mut(); arg_types.len()]; |
331 let mut slices = vec![null_mut(); arg_types.len()]; |
300 |
332 |
301 for (block_index, mask) in self.block_masks.iter().enumerate() { |
333 for (block_index, mask) in self.block_masks.iter().enumerate() { |
302 if mask & selector == selector { |
334 if mask & selector == selector { |
303 let block = &self.blocks[block_index]; |
335 let block = &self.blocks[block_index]; |
304 |
336 block.elements_count; |
305 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
337 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
306 slices[arg_index as usize] = block.component_blocks[type_index as usize] |
338 slices[arg_index as usize] = block.component_blocks[type_index as usize] |
307 .unwrap() |
339 .unwrap() |
308 .as_ptr() |
340 .as_ptr() |
309 } |
341 } |