Async Entity Component System based on the ideas of specs (https://github.com/amethyst/specs)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.1 KiB

  1. use hibitset::BitSetLike;
  2. #[derive(Debug, Clone)]
  3. pub struct BitIter<T> {
  4. pub(crate) set: T,
  5. pub(crate) masks: [usize; LAYERS],
  6. pub(crate) prefix: [u32; LAYERS - 1],
  7. }
  8. impl<T> BitIter<T> {
  9. pub fn new(set: T, masks: [usize; LAYERS], prefix: [u32; LAYERS - 1]) -> Self {
  10. Self { set, masks, prefix }
  11. }
  12. }
  13. impl<T: BitSetLike> BitIter<T> {
  14. pub fn contains(&self, i: u32) -> bool {
  15. self.set.contains(i)
  16. }
  17. }
  18. #[derive(PartialEq)]
  19. pub(crate) enum State {
  20. Empty,
  21. Continue,
  22. Value(u32),
  23. }
  24. impl<T> Iterator for BitIter<T>
  25. where
  26. T: BitSetLike,
  27. {
  28. type Item = u32;
  29. fn next(&mut self) -> Option<Self::Item> {
  30. use self::State::*;
  31. 'find: loop {
  32. for level in 0..LAYERS {
  33. match self.handle_level(level) {
  34. Value(v) => return Some(v),
  35. Continue => continue 'find,
  36. Empty => {}
  37. }
  38. }
  39. return None;
  40. }
  41. }
  42. }
  43. impl<T: BitSetLike> BitIter<T> {
  44. pub(crate) fn handle_level(&mut self, level: usize) -> State {
  45. use self::State::*;
  46. if self.masks[level] == 0 {
  47. Empty
  48. } else {
  49. let first_bit = self.masks[level].trailing_zeros();
  50. self.masks[level] &= !(1 << first_bit);
  51. let idx = self.prefix.get(level).cloned().unwrap_or(0) | first_bit;
  52. if level == 0 {
  53. Value(idx)
  54. } else {
  55. self.masks[level - 1] = self.set.get_from_layer(level - 1, idx as usize);
  56. self.prefix[level - 1] = idx << BITS;
  57. Continue
  58. }
  59. }
  60. }
  61. }
  62. const LAYERS: usize = 4;
  63. #[cfg(target_pointer_width = "64")]
  64. pub const BITS: usize = 6;
  65. #[cfg(target_pointer_width = "32")]
  66. pub const BITS: usize = 5;
  67. #[cfg(test)]
  68. mod tests {
  69. use hibitset::{BitSet, BitSetLike};
  70. #[test]
  71. fn iterator_clone() {
  72. let mut set = BitSet::new();
  73. set.add(1);
  74. set.add(3);
  75. let iter = set.iter().skip(1);
  76. for (a, b) in iter.clone().zip(iter) {
  77. assert_eq!(a, b);
  78. }
  79. }
  80. }