1#![deny(missing_docs)]
2
3pub struct MaskStorage {
47 pub masks: Vec<(u64, u64)>,
49 pub offsets: Vec<usize>,
51}
52
53impl MaskStorage {
54 pub fn new() -> MaskStorage {
56 MaskStorage {masks: vec![], offsets: vec![]}
57 }
58
59 pub fn optimize(&mut self, n: usize) -> Vec<usize> {
62 if n == 0 {return vec![]};
63
64 let mut ids: Vec<usize> = (0..n).collect();
65 let masks: Vec<(u64, u64)> = ids.iter().map(|&id| self.both_masks_of(id)).collect();
66 ids.sort_by(|a, b| {
67 let (am, ai) = masks[*a];
68 let (bm, bi) = masks[*b];
69 ai.cmp(&bi).then(bm.cmp(&am))
70 });
71
72 self.masks.clear();
73 self.offsets.clear();
74 let mut prev = masks[ids[0]];
75 self.masks.push(prev);
76 self.offsets.push(0);
77 for (i, &id) in ids.iter().enumerate().skip(1) {
78 if masks[id] != prev {
79 self.masks.push(masks[id]);
80 self.offsets.push(i);
81 }
82 prev = masks[id];
83 }
84
85 ids
86 }
87
88 pub fn next(&self, mask_pat: u64, i: &mut usize, n: usize) -> Option<(usize, usize)> {
90 loop {
91 if *i >= self.masks.len() {return None};
92 if self.masks[*i].0 & mask_pat == mask_pat {
93 if let Some(&next) = self.offsets.get(*i + 1) {
94 return Some((self.offsets[*i], next));
95 } else {
96 return Some((self.offsets[*i], n));
97 }
98 }
99 *i += 1;
100 }
101 }
102
103 pub fn mask_of(&self, cid: usize) -> u64 {
105 match self.offsets.binary_search(&cid) {
106 Ok(ind) => self.masks[ind].0,
107 Err(ind) if ind > 0 => self.masks[ind - 1].0,
108 Err(_) => panic!("Mask storage offset not including `0`")
109 }
110 }
111
112 pub fn init_mask_of(&self, id: usize) -> u64 {
114 match self.offsets.binary_search(&id) {
115 Ok(ind) => self.masks[ind].1,
116 Err(ind) if ind > 0 => self.masks[ind - 1].1,
117 Err(_) => panic!("Mask storage offset not including `0`")
118 }
119 }
120
121 pub fn both_masks_of(&self, id: usize) -> (u64, u64) {
123 match self.offsets.binary_search(&id) {
124 Ok(ind) => self.masks[ind],
125 Err(ind) if ind > 0 => self.masks[ind - 1],
126 Err(_) => panic!("Mask storage offset not including `0`")
127 }
128 }
129
130 pub fn push(&mut self, mask: u64, id: usize) {
132 if let Some(&(active, last)) = self.masks.last() {
133 if mask == last && active == last {return};
134 }
135 self.masks.push((mask, mask));
136 self.offsets.push(id);
137 }
138
139 pub fn update(&mut self, mask: u64, id: usize, n: usize) {
141 let ind = match self.offsets.binary_search(&id) {
142 Ok(ind) => ind,
143 Err(ind) if ind > 0 => {ind - 1},
144 Err(_) => panic!("Mask storage offset not including `0`")
145 };
146
147 if self.masks[ind].0 == mask {return};
148
149 let offset = self.offsets[ind];
150 let init_mask = self.masks[ind].1;
151 let next_offset = self.offsets.get(ind + 1);
152 let prev_offset = if ind == 0 {None} else {self.offsets.get(ind - 1)};
153 let next_range_same_masks = next_offset.is_some() &&
154 self.masks[ind + 1] == (mask, init_mask);
155 let prev_range_same_masks = prev_offset.is_some() &&
156 self.masks[ind - 1] == (mask, init_mask);
157
158 let last_range = next_offset.is_none();
159 let next_offset = next_offset.map(|x| *x).unwrap_or(n);
160 let at_beginning_in_old_range = offset == id;
161 let at_end_in_old_range = next_offset == id + 1;
162 let last = last_range && at_end_in_old_range;
163
164 let only_in_old_range = at_beginning_in_old_range && at_end_in_old_range;
165 let mut remove_old_range = false;
166 let mut remove_next_range = false;
167 let mut insert_range = false;
168 match (prev_range_same_masks, next_range_same_masks, only_in_old_range) {
169 (true, false, _) => {
170 remove_old_range = only_in_old_range;
172 if at_beginning_in_old_range {self.offsets[ind] += 1} else {insert_range = true}
173 }
174 (false, true, _) | (_, true, false) => {
175 remove_old_range = only_in_old_range;
177 if at_end_in_old_range {self.offsets[ind + 1] -= 1} else {insert_range = true}
178 }
179 (true, true, true) => {
180 remove_old_range = true;
182 remove_next_range = true;
183 }
184 (false, false, true) => {
185 self.masks[ind].0 = mask;
187 }
188 (false, false, false) => {
189 insert_range = true;
191 }
192 }
193 if insert_range {
194 if last {
195 self.offsets.push(id);
196 self.masks.push((mask, init_mask));
197 } else {
198 self.offsets.insert(ind + 1, id + 1);
199 let old_masks = self.masks[ind];
200 self.masks.insert(ind + 1, old_masks);
201 self.offsets.insert(ind + 1, id);
202 self.masks.insert(ind + 1, (mask, init_mask));
203 }
204 }
205 if remove_next_range {
206 self.offsets.remove(ind + 1);
207 self.masks.remove(ind + 1);
208 }
209 if remove_old_range {
210 self.offsets.remove(ind);
211 self.masks.remove(ind);
212 }
213 }
214}
215
216#[macro_export]
224macro_rules! ecs{
225 ($max_components:tt : $($x:ident),* $(,)?) => {
226 #[allow(missing_docs)]
228 pub enum Component {
229 $($x($x)),*
230 }
231
232 pub struct World {
234 pub components: Vec<Component>,
236 pub entities: Vec<(usize, u8)>,
238 pub masks: MaskStorage,
240 }
241
242 impl World {
243 pub fn new() -> World {
245 World {
246 components: vec![],
247 entities: vec![],
248 masks: MaskStorage::new(),
249 }
250 }
251
252 pub fn with_capacity(entities: usize, components: usize) -> World {
254 World {
255 components: Vec::with_capacity(components),
256 entities: Vec::with_capacity(entities),
257 masks: MaskStorage::new(),
258 }
259 }
260
261 pub fn optimize(&mut self) -> Vec<usize> {
267 let n = self.entities.len();
268 let mut ids = self.masks.optimize(n);
269
270 let n = self.components.len();
271 let mut gen: Vec<usize> = vec![0; n];
272 let mut k = 0;
273 for (i, &id) in ids.iter().enumerate() {
274 let off = self.entities[id].0;
275 let m = self.entities[id].1 as usize;
276 for j in 0..m {
277 gen[off + j] = k;
278 k += 1;
279 }
280 }
281
282 for i in 0..n {
283 while gen[i] != i {
284 let j = gen[i];
285 self.components.swap(i, j);
286 gen.swap(i, j);
287 }
288 }
289
290 let n = self.entities.len();
291 let mut k = 0;
292 let old = self.entities.clone();
293 for i in 0..n {
294 let m = old[ids[i]].1;
295 self.entities[i] = (k, m);
296 k += m as usize;
297 }
298
299 ids
300 }
301
302 #[inline(always)]
304 pub fn all(&self) -> impl Iterator<Item = usize> {0..self.entities.len()}
305
306 #[inline(always)]
308 pub fn entity_slice(&mut self, id: usize) -> &mut [Component] {
309 let (at, len) = self.entities[id];
310 &mut self.components[at..at + len as usize]
311 }
312
313 #[inline(always)]
315 pub fn has_component_index(&self, id: usize, ind: u8) -> bool {
316 (self.masks.mask_of(id) >> ind) & 1 == 1
317 }
318
319 #[inline(always)]
321 pub fn has_component<T>(&self, id: usize) -> bool
322 where Component: Ind<T>
323 {
324 self.has_component_index(id, self.component_index::<T>())
325 }
326
327 #[inline(always)]
329 pub fn has_mask(&self, id: usize, mask: u64) -> bool {
330 self.masks.mask_of(id) & mask == mask
331 }
332
333 #[inline(always)]
335 pub fn has_any_component<T>(&self) -> bool
336 where Component: Ind<T>
337 {
338 self.has_any_component_index(self.component_index::<T>())
339 }
340
341 #[inline]
343 pub fn has_any_component_index(&self, ind: u8) -> bool {
344 self.masks.masks.iter().any(|&(m, _)| (m >> ind) & 1 == 1)
345 }
346
347 #[inline(always)]
349 pub fn component_index<T>(&self) -> u8
350 where Component: Ind<T>
351 {
352 <Component as Ind<T>>::ind()
353 }
354
355 #[inline(always)]
357 pub fn mask_of(&self, id: usize) -> u64 {self.masks.mask_of(id)}
358
359 #[inline(always)]
361 pub fn init_mask_of(&self, id: usize) -> u64 {self.masks.init_mask_of(id)}
362
363 pub fn enable_component<T>(&mut self, id: usize) -> bool
368 where Component: Ind<T>
369 {
370 self.enable_component_index(id, <Component as Ind<T>>::ind())
371 }
372
373 pub fn enable_component_index(&mut self, id: usize, ind: u8) -> bool {
378 let (mut mask, init_mask) = self.masks.both_masks_of(id);
379 if init_mask >> ind & 1 == 1 {
380 mask |= 1 << ind;
381 self.masks.update(mask, id, self.entities.len());
382 true
383 } else {
384 false
385 }
386 }
387
388 #[inline(always)]
390 pub fn disable_component<T>(&mut self, id: usize)
391 where Component: Ind<T>
392 {
393 self.disable_component_index(id, <Component as Ind<T>>::ind())
394 }
395
396 #[inline(always)]
398 pub fn disable_component_index(&mut self, id: usize, ind: u8) {
399 let mut mask = self.masks.mask_of(id);
400 mask &= !(1 << ind);
401 self.masks.update(mask, id, self.entities.len());
402 }
403
404 #[inline(always)]
406 pub fn disable(&mut self, id: usize) {
407 self.masks.update(0, id, self.entities.len());
408 }
409 }
410
411 pub trait Ind<T> {
415 fn ind() -> u8;
417 }
418 pub trait Get<T> {
422 unsafe fn get(self) -> Option<T>;
426 }
427 pub trait Push<T> {
429 fn push(&mut self, val: T) -> usize;
431 }
432
433 push_impl!{$max_components}
434
435 ind!{Component, 0, $($x),*}
436
437 $(
438 impl<'a> Get<&'a mut $x> for *mut Component {
439 unsafe fn get(self) -> Option<&'a mut $x> {
440 if let Component::$x(x) = (&mut *self) {Some(x)} else {None}
441 }
442 }
443
444 impl<'a> Get<&'a $x> for *mut Component {
445 unsafe fn get(self) -> Option<&'a $x> {
446 if let Component::$x(x) = (&*self) {Some(x)} else {None}
447 }
448 }
449
450 impl From<$x> for Component {
451 fn from(x: $x) -> Component {Component::$x(x)}
452 }
453 )*
454 }
455}
456
457#[macro_export]
461macro_rules! tup_count(
462 () => {0};
463 ($x0:ident $(, $y:ident)* $(,)?) => {1 + tup_count!($($y),*)};
464);
465
466#[macro_export]
468macro_rules! mask_pat(
469 ($($x:ident),* $(,)?) => {($(1 << <Component as Ind<$x>>::ind())|*)}
470);
471
472#[macro_export]
476macro_rules! mask_pre(
477 ($mask:ident, |$($n:ident: $x:ty),*|) => {
478 let $mask: u64 = ($(1 << <Component as Ind<$x>>::ind())|*);
479 let __component_len = $mask.count_ones() as isize;
480 assert_eq!(__component_len, tup_count!($($n),*), "Component used twice");
481 }
482);
483
484#[macro_export]
494macro_rules! system(
495 ($world:ident, $(?|$filter_id:ident| $filter:expr ;)*
496 |$($n:ident: $x:ty),* $(,)?| $e:expr) => {
497 mask_pre!(__mask, |$($n: $x),*|);
498
499 let __n = $world.entities.len();
500 let mut __i = 0;
501 while let Some((__start, __end)) = $world.masks.next(__mask, &mut __i, __n) {
502 let __init_mask = $world.masks.masks[__i].1;
503 let __components = __init_mask.count_ones() as usize;
504 let mut __ptr = $world.entity_slice(__start).as_mut_ptr();
505 for __i in __start..__end {
506 entity_unchecked_access!($world, __i, __init_mask, __ptr,
507 $(?|$filter_id| $filter ;)* |$($n : $x,)*| $e);
508 __ptr = unsafe {__ptr.add(__components)};
509 }
510 __i += 1;
511 }
512 };
513);
514
515#[macro_export]
519macro_rules! system_ids(
520 ($world:ident,
521 $(?|$filter_id:ident| $filter:expr ;)*
522 $id:ident,
523 |$($n:ident: $x:ty),* $(,)?| $e:expr) => {
524 mask_pre!(__mask, |$($n: $x),*|);
525
526 let __n = $world.entities.len();
527 let mut __i = 0;
528 while let Some((__start, __end)) = $world.masks.next(__mask, &mut __i, __n) {
529 let __init_mask = $world.masks.masks[__i].1;
530 let __components = __init_mask.count_ones() as usize;
531 let mut __ptr = $world.entity_slice(__start).as_mut_ptr();
532 for __i in __start..__end {
533 let $id = __i;
534 entity_unchecked_access!($world, $id, __init_mask, __ptr,
535 $(?|$filter_id| $filter ;)* |$($n : $x,)*| $e);
536 __ptr = unsafe {__ptr.add(__components)};
537 }
538 __i += 1;
539 }
540 };
541);
542
543#[macro_export]
545macro_rules! entity_ids(
546 ($world:ident, $id:ident, |$($x:ty),* $(,)?| $e:expr) => {
547 mask_pre!(__mask, |$(_n: $x),*|);
548
549 let __n = $world.entities.len();
550 let mut __i = 0;
551 while let Some((__start, __end)) = $world.masks.next(__mask, &mut __i, __n) {
552 for __i in __start..__end {
553 let $id = __i;
554 $e
555 }
556 __i += 1;
557 }
558 };
559);
560
561#[macro_export]
565macro_rules! entity(
566 ($world:ident, $ind:expr, |$($n:ident: $x:ty),* $(,)?| $e:expr) => {
567 mask_pre!(__mask, |$($n: $x),*|);
568
569 let __i = $ind;
570 entity_access!($world, __i, __mask, |$($n : $x,)*| $e);
571 }
572);
573
574#[macro_export]
578macro_rules! entity_access(
579 ($world:ident, $i:ident, $__mask:ident,
580 $(?|$filter_id:ident| $filter:expr ;)*
581 |$($n:ident : $x:ty,)*| $e:expr) => {
582 let __init_mask = $world.init_mask_of($i);
583 let __entity_mask = $world.mask_of($i);
584 if __init_mask & __entity_mask & $__mask == $__mask {
585 $(
586 let $filter_id = $i;
587 if !$filter {continue};
588 )*
589 let __ptr = $world.entity_slice($i).as_mut_ptr();
590 $(
591 let $n: $x = unsafe {__ptr.offset(
592 (((1_u64 << <Component as Ind<$x>>::ind()) - 1) & __init_mask).count_ones() as isize
593 ).get()}.unwrap();
594 )*
595 $e
596 }
597 }
598);
599
600#[macro_export]
604macro_rules! entity_unchecked_access(
605 ($world:ident, $i:ident, $__init_mask:ident, $__ptr:ident,
606 $(?|$filter_id:ident| $filter:expr ;)*
607 |$($n:ident : $x:ty,)*| $e:expr) => {
608 $(
609 let $filter_id = $i;
610 if !$filter {continue};
611 )*
612 $(
613 let $n: $x = unsafe {$__ptr.offset(
614 (((1_u64 << <Component as Ind<$x>>::ind()) - 1) & $__init_mask).count_ones() as isize
615 ).get()}.unwrap();
616 )*
617 $e
618 }
619);
620
621#[macro_export]
623macro_rules! push_impl {
624 (4) => {
625 push_impl!{
626 x0: T0, x1: T1, x2: T2, x3: T3
627 }
628 };
629 (8) => {
630 push_impl!{
631 x0: T0, x1: T1, x2: T2, x3: T3, x4: T4, x5: T5,x6: T6, x7: T7
632 }
633 };
634 (16) => {
635 push_impl!{
636 x0: T0, x1: T1, x2: T2, x3: T3, x4: T4, x5: T5,x6: T6, x7: T7,
637 x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15
638 }
639 };
640 (32) => {
641 push_impl!{
642 x0: T0, x1: T1, x2: T2, x3: T3, x4: T4, x5: T5,x6: T6, x7: T7,
643 x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15,
644 x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22, x23: T23,
645 x24: T24, x25: T25, x26: T26, x27: T27, x28: T28, x29: T29, x30: T30, x31: T31
646 }
647 };
648 (64) => {
649 push_impl!{
650 x0: T0, x1: T1, x2: T2, x3: T3, x4: T4, x5: T5,x6: T6, x7: T7,
651 x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15,
652 x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22, x23: T23,
653 x24: T24, x25: T25, x26: T26, x27: T27, x28: T28, x29: T29, x30: T30, x31: T31,
654 x32: T32, x33: T33, x34: T34, x35: T35, x36: T36, x37: T37, x38: T38, x39: T39,
655 x40: T40, x41: T41, x42: T42, x43: T43, x44: T44, x45: T45, x46: T46, x47: T47,
656 x48: T48, x49: T49, x50: T50, x51: T51, x52: T52, x53: T53, x54: T54, x55: T55,
657 x56: T56, x57: T57, x58: T58, x59: T59, x60: T60, x61: T61, x62: T62, x63: T63
658 }
659 };
660 ($n:ident : $x:ident) => {
661 push!{$n : $x}
662 };
663 ($n:ident : $x:ident, $($n2:ident : $x2:ident),*) => {
664 push!{$n : $x, $($n2 : $x2),*}
665 push_impl!{$($n2 : $x2),*}
666 };
667}
668
669#[macro_export]
671macro_rules! push{
672 ($($n:ident : $x:ident),+) => {
673 #[allow(unused_parens)]
674 impl<$($x),*> Push<($($x),*)> for World
675 where $(Component: From<$x> + Ind<$x>,)*
676 $($x: Clone),*
677 {
678 fn push(&mut self, ($($n),*): ($($x),*)) -> usize {
679 let id = self.entities.len();
680 let comp = self.components.len();
681 let mask: u64 = $(1 << <Component as Ind<$x>>::ind())|+;
682 self.masks.push(mask, id);
683 let count = tup_count!($($n),*);
684 assert_eq!(mask.count_ones(), count, "Component declared twice");
685 let mut i = 0;
686 let mut bit = 0;
687 while i < count {
688 let mut set = false;
689 $(
690 if <Component as Ind<$x>>::ind() == bit {
691 self.components.push($n.clone().into());
692 set = true;
693 }
694 )*
695 if set {i += 1}
696 bit += 1;
697 }
698 self.entities.push((comp, count as u8));
699 id
700 }
701 }
702 }
703}
704
705#[macro_export]
707macro_rules! ind{
708 ($c:ident, $id:expr, $x:ident) => {
709 impl Ind<&mut $x> for $c {#[inline(always)] fn ind() -> u8 {$id}}
710 impl Ind<&$x> for $c {#[inline(always)] fn ind() -> u8 {$id}}
711 impl Ind<$x> for $c {#[inline(always)] fn ind() -> u8 {$id}}
712 };
713 ($c:ident, $id:expr, $x:ident, $($y:ident),+) => {
714 impl Ind<&mut $x> for $c {#[inline(always)] fn ind() -> u8 {$id}}
715 impl Ind<&$x> for $c {#[inline(always)] fn ind() -> u8 {$id}}
716 impl Ind<$x> for $c {#[inline(always)] fn ind() -> u8 {$id}}
717 ind!{$c, $id + 1, $($y),+}
718 };
719}