8 slice, |
8 slice, |
9 }; |
9 }; |
10 |
10 |
11 pub trait TypeTuple: Sized { |
11 pub trait TypeTuple: Sized { |
12 fn get_types(types: &mut Vec<TypeId>); |
12 fn get_types(types: &mut Vec<TypeId>); |
13 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, mut f: F); |
13 unsafe fn iter<F: FnMut(GearId, Self)>(slices: &[*mut u8], count: usize, f: F); |
14 } |
14 } |
15 |
15 |
16 macro_rules! type_tuple_impl { |
16 macro_rules! type_tuple_impl { |
17 ($($n: literal: $t: ident),+) => { |
17 ($($n: literal: $t: ident),+) => { |
18 impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) { |
18 impl<$($t: 'static),+> TypeTuple for ($(&$t),+,) { |
164 block_index, |
164 block_index, |
165 } |
165 } |
166 } |
166 } |
167 } |
167 } |
168 |
168 |
|
169 #[derive(Copy, Clone, Eq, PartialEq, Debug)] |
|
170 struct BlockMask { |
|
171 type_mask: u64, |
|
172 tag_mask: u64, |
|
173 } |
|
174 |
|
175 impl BlockMask { |
|
176 #[inline] |
|
177 fn new(type_mask: u64, tag_mask: u64) -> Self { |
|
178 Self { |
|
179 type_mask, |
|
180 tag_mask, |
|
181 } |
|
182 } |
|
183 |
|
184 #[inline] |
|
185 fn with_type(&self, type_bit: u64) -> Self { |
|
186 Self::new(self.type_mask | type_bit, self.tag_mask) |
|
187 } |
|
188 |
|
189 #[inline] |
|
190 fn with_tag(&self, tag_bit: u64) -> Self { |
|
191 Self::new(self.type_mask, self.tag_mask | tag_bit) |
|
192 } |
|
193 } |
|
194 |
169 pub struct GearDataManager { |
195 pub struct GearDataManager { |
170 types: Vec<TypeId>, |
196 types: Vec<TypeId>, |
|
197 tags: Vec<TypeId>, |
171 blocks: Vec<DataBlock>, |
198 blocks: Vec<DataBlock>, |
172 block_masks: Vec<u64>, |
199 block_masks: Vec<BlockMask>, |
173 element_sizes: Box<[u16; 64]>, |
200 element_sizes: Box<[u16; 64]>, |
174 lookup: Box<[LookupEntry]>, |
201 lookup: Box<[LookupEntry]>, |
175 } |
202 } |
176 |
203 |
177 impl GearDataManager { |
204 impl GearDataManager { |
178 pub fn new() -> Self { |
205 pub fn new() -> Self { |
179 Self { |
206 Self { |
180 types: vec![], |
207 types: Vec::with_capacity(64), |
|
208 tags: Vec::with_capacity(64), |
181 blocks: vec![], |
209 blocks: vec![], |
182 block_masks: vec![], |
210 block_masks: vec![], |
183 element_sizes: Box::new([0; 64]), |
211 element_sizes: Box::new([0; 64]), |
184 lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(), |
212 lookup: vec![LookupEntry::default(); u16::max_value() as usize].into_boxed_slice(), |
185 } |
213 } |
189 fn get_type_index<T: 'static>(&self) -> Option<usize> { |
217 fn get_type_index<T: 'static>(&self) -> Option<usize> { |
190 let type_id = TypeId::of::<T>(); |
218 let type_id = TypeId::of::<T>(); |
191 self.types.iter().position(|id| *id == type_id) |
219 self.types.iter().position(|id| *id == type_id) |
192 } |
220 } |
193 |
221 |
|
222 #[inline] |
|
223 fn get_tag_index<T: 'static>(&self) -> Option<usize> { |
|
224 let type_id = TypeId::of::<T>(); |
|
225 self.tags.iter().position(|id| *id == type_id) |
|
226 } |
|
227 |
194 fn move_between_blocks(&mut self, src_block_index: u16, src_index: u16, dest_block_index: u16) { |
228 fn move_between_blocks(&mut self, src_block_index: u16, src_index: u16, dest_block_index: u16) { |
195 debug_assert!(src_block_index != dest_block_index); |
229 debug_assert!(src_block_index != dest_block_index); |
196 let src_mask = self.block_masks[src_block_index as usize]; |
230 let src_mask = self.block_masks[src_block_index as usize]; |
197 let dest_mask = self.block_masks[dest_block_index as usize]; |
231 let dest_mask = self.block_masks[dest_block_index as usize]; |
198 debug_assert!(src_mask & dest_mask == src_mask); |
232 debug_assert!(src_mask.type_mask & dest_mask.type_mask == src_mask.type_mask); |
199 |
233 |
200 let src_block = &self.blocks[src_block_index as usize]; |
234 let src_block = &self.blocks[src_block_index as usize]; |
201 let dest_block = &self.blocks[dest_block_index as usize]; |
235 let dest_block = &self.blocks[dest_block_index as usize]; |
202 debug_assert!(src_index < src_block.elements_count); |
236 debug_assert!(src_index < src_block.elements_count); |
203 debug_assert!(!dest_block.is_full()); |
237 debug_assert!(!dest_block.is_full()); |
204 |
238 |
205 let dest_index = dest_block.elements_count; |
239 let dest_index = dest_block.elements_count; |
206 for i in 0..self.types.len() { |
240 for i in 0..self.types.len() { |
207 if src_mask & (1 << i as u64) != 0 { |
241 if src_mask.type_mask & (1 << i as u64) != 0 { |
208 let size = self.element_sizes[i]; |
242 let size = self.element_sizes[i]; |
209 let src_ptr = src_block.component_blocks[i].unwrap().as_ptr(); |
243 let src_ptr = src_block.component_blocks[i].unwrap().as_ptr(); |
210 let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr(); |
244 let dest_ptr = dest_block.component_blocks[i].unwrap().as_ptr(); |
211 unsafe { |
245 unsafe { |
212 copy_nonoverlapping( |
246 copy_nonoverlapping( |
246 self.lookup[gear_id.get() as usize - 1] = LookupEntry::new(dest_block_index, dest_index); |
280 self.lookup[gear_id.get() as usize - 1] = LookupEntry::new(dest_block_index, dest_index); |
247 dest_block.elements_count += 1; |
281 dest_block.elements_count += 1; |
248 } |
282 } |
249 |
283 |
250 fn add_to_block<T: Clone>(&mut self, gear_id: GearId, block_index: u16, value: &T) { |
284 fn add_to_block<T: Clone>(&mut self, gear_id: GearId, block_index: u16, value: &T) { |
251 debug_assert!(self.block_masks[block_index as usize].count_ones() == 1); |
285 debug_assert!( |
|
286 self.block_masks[block_index as usize] |
|
287 .type_mask |
|
288 .count_ones() |
|
289 == 1 |
|
290 ); |
252 |
291 |
253 let block = &mut self.blocks[block_index as usize]; |
292 let block = &mut self.blocks[block_index as usize]; |
254 debug_assert!(block.elements_count < block.max_elements); |
293 debug_assert!(block.elements_count < block.max_elements); |
255 |
294 |
256 unsafe { |
295 unsafe { |
297 } |
336 } |
298 block.elements_count -= 1; |
337 block.elements_count -= 1; |
299 } |
338 } |
300 |
339 |
301 #[inline] |
340 #[inline] |
302 fn ensure_block(&mut self, mask: u64) -> u16 { |
341 fn ensure_block(&mut self, mask: BlockMask) -> u16 { |
303 if let Some(index) = self |
342 if let Some(index) = self |
304 .block_masks |
343 .block_masks |
305 .iter() |
344 .iter() |
306 .enumerate() |
345 .enumerate() |
307 .position(|(i, m)| *m == mask && !self.blocks[i].is_full()) |
346 .position(|(i, m)| *m == mask && !self.blocks[i].is_full()) |
308 { |
347 { |
309 index as u16 |
348 index as u16 |
310 } else { |
349 } else { |
311 self.blocks.push(DataBlock::new( |
350 self.blocks.push(DataBlock::new( |
312 mask, |
351 mask.type_mask, |
313 &self.element_sizes[0..self.types.len()], |
352 &self.element_sizes[0..self.types.len()], |
314 )); |
353 )); |
315 self.block_masks.push(mask); |
354 self.block_masks.push(mask); |
316 (self.blocks.len() - 1) as u16 |
355 (self.blocks.len() - 1) as u16 |
317 } |
356 } |
322 let type_bit = 1 << type_index as u64; |
361 let type_bit = 1 << type_index as u64; |
323 let entry = self.lookup[gear_id.get() as usize - 1]; |
362 let entry = self.lookup[gear_id.get() as usize - 1]; |
324 |
363 |
325 if let Some(index) = entry.index { |
364 if let Some(index) = entry.index { |
326 let mask = self.block_masks[entry.block_index as usize]; |
365 let mask = self.block_masks[entry.block_index as usize]; |
327 let new_mask = mask | type_bit; |
366 let new_mask = mask.with_type(type_bit); |
328 |
367 |
329 if new_mask != mask { |
368 if new_mask != mask { |
330 let dest_block_index = self.ensure_block(new_mask); |
369 let dest_block_index = self.ensure_block(new_mask); |
331 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
370 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
332 } |
371 } |
333 } else { |
372 } else { |
334 let dest_block_index = self.ensure_block(type_bit); |
373 let dest_block_index = self.ensure_block(BlockMask::new(type_bit, 0)); |
335 self.add_to_block(gear_id, dest_block_index, value); |
374 self.add_to_block(gear_id, dest_block_index, value); |
336 } |
375 } |
337 } else { |
376 } else { |
338 panic!("Unregistered type") |
377 panic!("Unregistered type") |
|
378 } |
|
379 } |
|
380 |
|
381 pub fn add_tag<T: 'static>(&mut self, gear_id: GearId) { |
|
382 if let Some(tag_index) = self.get_tag_index::<T>() { |
|
383 let tag_bit = 1 << tag_index as u64; |
|
384 let entry = self.lookup[gear_id.get() as usize - 1]; |
|
385 |
|
386 if let Some(index) = entry.index { |
|
387 let mask = self.block_masks[entry.block_index as usize]; |
|
388 let new_mask = mask.with_tag(tag_bit); |
|
389 |
|
390 if new_mask != mask { |
|
391 let dest_block_index = self.ensure_block(new_mask); |
|
392 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
|
393 } |
|
394 } else { |
|
395 panic!("Cannot tag a gear with no data") |
|
396 } |
|
397 } else { |
|
398 panic!("Unregistered tag") |
339 } |
399 } |
340 } |
400 } |
341 |
401 |
342 pub fn remove<T: 'static>(&mut self, gear_id: GearId) { |
402 pub fn remove<T: 'static>(&mut self, gear_id: GearId) { |
343 if let Some(type_index) = self.get_type_index::<T>() { |
403 if let Some(type_index) = self.get_type_index::<T>() { |
344 let entry = self.lookup[gear_id.get() as usize - 1]; |
404 let entry = self.lookup[gear_id.get() as usize - 1]; |
345 if let Some(index) = entry.index { |
405 if let Some(index) = entry.index { |
346 let dest_mask = |
406 let mut dest_mask = self.block_masks[entry.block_index as usize]; |
347 self.block_masks[entry.block_index as usize] & !(1 << type_index as u64); |
407 dest_mask.type_mask &= !(1 << type_index as u64); |
348 |
408 |
349 if dest_mask == 0 { |
409 if dest_mask.type_mask == 0 { |
350 self.remove_all(gear_id) |
410 self.remove_from_block(entry.block_index, index.get() - 1); |
351 } else { |
411 } else { |
352 let dest_block_index = self.ensure_block(dest_mask); |
412 let dest_block_index = self.ensure_block(dest_mask); |
353 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
413 self.move_between_blocks(entry.block_index, index.get() - 1, dest_block_index); |
354 } |
414 } |
355 } |
415 } |
365 } |
425 } |
366 } |
426 } |
367 |
427 |
368 pub fn register<T: 'static>(&mut self) { |
428 pub fn register<T: 'static>(&mut self) { |
369 debug_assert!(!std::mem::needs_drop::<T>()); |
429 debug_assert!(!std::mem::needs_drop::<T>()); |
370 debug_assert!(self.types.len() <= 64); |
|
371 debug_assert!(size_of::<T>() <= u16::max_value() as usize); |
430 debug_assert!(size_of::<T>() <= u16::max_value() as usize); |
372 |
431 |
373 let id = TypeId::of::<T>(); |
432 let id = TypeId::of::<T>(); |
374 if !self.types.contains(&id) { |
433 if size_of::<T>() == 0 { |
375 self.element_sizes[self.types.len()] = size_of::<T>() as u16; |
434 if !self.tags.contains(&id) { |
376 self.types.push(id); |
435 debug_assert!(self.tags.len() <= 64); |
377 } |
436 self.tags.push(id) |
378 } |
437 } |
379 |
438 } else { |
|
439 if !self.types.contains(&id) { |
|
440 debug_assert!(self.types.len() <= 64); |
|
441 self.element_sizes[self.types.len()] = size_of::<T>() as u16; |
|
442 self.types.push(id); |
|
443 } |
|
444 } |
|
445 } |
|
446 |
|
447 #[inline] |
380 pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&mut self, mut f: F) { |
448 pub fn iter<T: TypeTuple + 'static, F: FnMut(T)>(&mut self, mut f: F) { |
381 self.iter_id(|_, x| f(x)); |
449 self.iter_id(|_, x| f(x)); |
382 } |
450 } |
383 |
451 |
384 pub fn iter_id<T: TypeTuple + 'static, F: FnMut(GearId, T)>(&mut self, mut f: F) { |
452 pub fn iter_id<T: TypeTuple + 'static, F: FnMut(GearId, T)>(&mut self, mut f: F) { |
399 } |
467 } |
400 } |
468 } |
401 let mut slices = vec![null_mut(); arg_types.len() + 1]; |
469 let mut slices = vec![null_mut(); arg_types.len() + 1]; |
402 |
470 |
403 for (block_index, mask) in self.block_masks.iter().enumerate() { |
471 for (block_index, mask) in self.block_masks.iter().enumerate() { |
404 if mask & selector == selector { |
472 if mask.type_mask & selector == selector { |
405 let block = &mut self.blocks[block_index]; |
473 let block = &mut self.blocks[block_index]; |
406 slices[0] = block.data.as_mut_ptr(); |
474 slices[0] = block.data.as_mut_ptr(); |
407 |
475 |
408 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
476 for (arg_index, type_index) in type_indices.iter().cloned().enumerate() { |
409 slices[arg_index as usize + 1] = block.component_blocks[type_index as usize] |
477 slices[arg_index as usize + 1] = block.component_blocks[type_index as usize] |