Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

94 行
2.5 KiB

  1. use hibitset::BitSetLike;
  2. use parallel_iterator::{Folder, Producer};
  3. use crate::misc::bit_average;
  4. use super::BitIter;
  5. pub struct BitProducer<'a, T> {
  6. pub(crate) iter: BitIter<&'a T>,
  7. pub(crate) splits: u8,
  8. }
  9. impl<'a, T> BitProducer<'a, T>
  10. where
  11. T: BitSetLike,
  12. {
  13. pub fn new(iter: BitIter<&'a T>, splits: u8) -> Self {
  14. Self { iter, splits }
  15. }
  16. fn handle_level(&mut self, level: usize) -> Option<Self> {
  17. if self.iter.masks[level] == 0 {
  18. None
  19. } else {
  20. let level_prefix = self.iter.prefix.get(level).cloned().unwrap_or(0);
  21. let first_bit = self.iter.masks[level].trailing_zeros();
  22. bit_average(self.iter.masks[level])
  23. .map(|average_bit| {
  24. let mask = (1 << average_bit) - 1;
  25. let mut other = BitProducer::new(
  26. BitIter::new(self.iter.set, [0; LAYERS], [0; LAYERS - 1]),
  27. self.splits,
  28. );
  29. other.iter.masks[level] = self.iter.masks[level] & !mask;
  30. other.iter.prefix[level - 1] = (level_prefix | average_bit as u32) << BITS;
  31. other.iter.prefix[level..].copy_from_slice(&self.iter.prefix[level..]);
  32. self.iter.masks[level] &= mask;
  33. self.iter.prefix[level - 1] = (level_prefix | first_bit) << BITS;
  34. other
  35. })
  36. .or_else(|| {
  37. let idx = level_prefix as usize | first_bit as usize;
  38. self.iter.prefix[level - 1] = (idx as u32) << BITS;
  39. self.iter.masks[level] = 0;
  40. self.iter.masks[level - 1] = self.iter.set.get_from_layer(level - 1, idx);
  41. None
  42. })
  43. }
  44. }
  45. }
  46. impl<'a, T> Producer for BitProducer<'a, T>
  47. where
  48. T: BitSetLike + Send + Sync,
  49. {
  50. type Item = u32;
  51. fn split(mut self) -> (Self, Option<Self>) {
  52. let other = {
  53. let top_layer = LAYERS - 1;
  54. let mut h = self.handle_level(top_layer);
  55. for i in 1..self.splits {
  56. h = h.or_else(|| self.handle_level(top_layer - i as usize));
  57. }
  58. h
  59. };
  60. (self, other)
  61. }
  62. fn fold_with<F>(self, folder: F) -> F
  63. where
  64. F: Folder<Self::Item>,
  65. {
  66. folder.consume_iter(self.iter)
  67. }
  68. }
  69. const LAYERS: usize = 4;
  70. #[cfg(target_pointer_width = "64")]
  71. pub const BITS: usize = 6;
  72. #[cfg(target_pointer_width = "32")]
  73. pub const BITS: usize = 5;