toy ecs for fun and profit! (aka flecs if it was terrible)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114use alloc::vec::Vec;
#[derive(Copy, Clone)]#[repr(C, align(8))]pub struct Mask(u32, u32);
impl Mask { pub fn from_idx(idx: u32) -> Mask { Mask(idx / u32::BITS, idx % u32::BITS) }}
pub struct MaskSet { masks: Vec<Mask>,}
impl MaskSet { pub fn new() -> Self { Self { masks: Vec::new() } }
pub fn contains(&self, Mask(target, test): Mask) -> bool { for Mask(idx, truth) in &self.masks { if *idx == target && ((truth & test) == 1) { return true; } } false }
pub fn insert(&mut self, Mask(target, value): Mask) { for Mask(idx, truth) in &mut self.masks { if *idx == target { *truth |= value; return; } } self.masks.push(Mask(target, value)); self.masks.sort_by_key(|m| m.0); }
pub fn remove(&mut self, Mask(target, test): Mask) { for (i, Mask(idx, truth)) in self.masks.iter_mut().enumerate() { if *idx == target && ((*truth & test) == 1) { *truth ^= test; if *truth == 0 { self.masks.remove(i); } return; } } }
pub fn superset(&self, other: &Self) -> bool { for mask in &other.masks { if !self.contains(*mask) { return false; } } true }
#[inline] pub fn subset(&self, other: &Self) -> bool { Self::superset(other, self) }
pub fn disjoint(&self, other: &Self) -> bool { let mut tests = other.masks.iter(); for truth in &self.masks { 'testing: while let Some(test) = tests.next() { if test.0 == truth.0 { if (test.1 & truth.1) != 0 { return false; } break 'testing; } } if tests.len() == 0 { break; } } true }
pub fn union(&mut self, other: &Self) { for mask in &other.masks { self.insert(*mask); } }
pub fn intersect(&self, other: &Self) -> Self { let mut new = Vec::new(); let mut tests = other.masks.iter(); for truth in &self.masks { 'testing: while let Some(test) = tests.next() { if test.0 == truth.0 { let new_mask = test.1 & truth.1; if new_mask == 0 { break 'testing; } new.push(Mask(test.0, new_mask)); } } if tests.len() == 0 { break; } }
assert!(new.is_sorted_by_key(|m| m.0)); MaskSet { masks: new } }}