Skip to main content

nano_ecs/
lib.rs

1#![deny(missing_docs)]
2
3//! # Nano-ECS
4//! A bare-bones macro-based Entity-Component-System
5//!
6//! - Maximum 64 components per entity
7//! - Stores components sequentially in same array
8//! - Masks for enabled/disabled components
9//!
10//! ```rust
11//! use nano_ecs::*;
12//!
13//! #[derive(Clone)]
14//! pub struct Position(pub f32);
15//! #[derive(Clone)]
16//! pub struct Velocity(pub f32);
17//!
18//! ecs!{4: Position, Velocity}
19//!
20//! fn main() {
21//!     let mut world = World::new();
22//!     world.push(Position(0.0));
23//!     world.push((Position(0.0), Velocity(0.0)));
24//!     let dt = 1.0;
25//!     system!(world, |pos: &mut Position, vel: &Velocity| {
26//!         pos.0 = pos.0 + vel.0 * dt;
27//!     });
28//! }
29//! ```
30//!
31//! ### Design
32//!
33//! The `ecs!` macro generates a `World` and `Component` object.
34//!
35//! Can be used with any Rust data structure that implements `Clone`.
36//!
37//!
38//! The order of declared components is used to assign every component an index.
39//! This index is used in the mask per entity and to handle slice memory correctly.
40//!
41//! - All components are stored in one array inside `World`.
42//! - All entities have a slice refering to components
43//! - All entities have a mask that enable/disable components
44
45/// Stores masks efficiently and allows fast iteration.
46pub struct MaskStorage {
47    /// Stores `(active, initial)` masks.
48    pub masks: Vec<(u64, u64)>,
49    /// Stores the offsets of the mask.
50    pub offsets: Vec<usize>,
51}
52
53impl MaskStorage {
54    /// Creates a new mask storage.
55    pub fn new() -> MaskStorage {
56        MaskStorage {masks: vec![], offsets: vec![]}
57    }
58
59    /// Sorts optimally and returns a sort to update
60    /// entity slices and components.
61    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    /// Gets the next range of entities with active mask pattern.
89    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    /// Returns the active mask of component id.
104    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    /// Returns the initial mask of entity id.
113    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    /// Returns both active and initial mask of entity id.
122    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    /// Pushes a new mask.
131    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    /// Updates a mask for an entity.
140    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                // Join previous range.
171                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                // Join next range.
176                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                // Join previous and next range.
181                remove_old_range = true;
182                remove_next_range = true;
183            }
184            (false, false, true) => {
185                // Change mask on old range.
186                self.masks[ind].0 = mask;
187            }
188            (false, false, false) => {
189                // Insert range.
190                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/// Creates an Entity-Component-System.
217///
218/// The first number is how many components are allowed per entity.
219/// A lower number reduces compile time.
220/// This can be `4, 8, 16, 32, 64`.
221///
222/// Example: `ecs!{4; Position, Velocity}`
223#[macro_export]
224macro_rules! ecs{
225    ($max_components:tt : $($x:ident),* $(,)?) => {
226        /// Stores a single component.
227        #[allow(missing_docs)]
228        pub enum Component {
229            $($x($x)),*
230        }
231
232        /// World storing components and entities.
233        pub struct World {
234            /// A list of all components.
235            pub components: Vec<Component>,
236            /// Entities with indices into components.
237            pub entities: Vec<(usize, u8)>,
238            /// Masks for ranges of components.
239            pub masks: MaskStorage,
240        }
241
242        impl World {
243            /// Creates a new empty world.
244            pub fn new() -> World {
245                World {
246                    components: vec![],
247                    entities: vec![],
248                    masks: MaskStorage::new(),
249                }
250            }
251
252            /// Creates a new empty world with pre-allocated capacity.
253            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            /// Optimizes storage of components for cache friendliness.
262            ///
263            /// This does not preserve the entity ids.
264            ///
265            /// Returns a list of indices for new entities.
266            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            /// An iterator for all entities.
303            #[inline(always)]
304            pub fn all(&self) -> impl Iterator<Item = usize> {0..self.entities.len()}
305
306            /// Gets entity slice of components from id.
307            #[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            /// Returns `true` if entity has a component by index.
314            #[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            /// Returns `true` if entity has a component.
320            #[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            /// Returns `true` if entity has a specified mask (a set of components).
328            #[inline(always)]
329            pub fn has_mask(&self, id: usize, mask: u64) -> bool {
330                self.masks.mask_of(id) & mask == mask
331            }
332
333            /// Returns `true` if any entity has a component.
334            #[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            /// Returns `true` if any entity has a component by index.
342            #[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            /// Returns the component index of a component.
348            #[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            /// Returns the mask of an entity.
356            #[inline(always)]
357            pub fn mask_of(&self, id: usize) -> u64 {self.masks.mask_of(id)}
358
359            /// Returns the initial mask of an entity.
360            #[inline(always)]
361            pub fn init_mask_of(&self, id: usize) -> u64 {self.masks.init_mask_of(id)}
362
363            /// Enables component for entity.
364            ///
365            /// The entity must be pushed with the component active to enable it again.
366            /// Returns `true` if successful.
367            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            /// Enables component for entity by index.
374            ///
375            /// The entity must be pushed with the component active to enable it again.
376            /// Returns `true` if successful.
377            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            /// Disables component for entity.
389            #[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            /// Disables component for entity by index.
397            #[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            /// Disables all components for entity.
405            #[inline(always)]
406            pub fn disable(&mut self, id: usize) {
407                self.masks.update(0, id, self.entities.len());
408            }
409        }
410
411        /// The index of a component type `T` from `Component`.
412        ///
413        /// This is used to store the components in the declared order.
414        pub trait Ind<T> {
415            /// Returns the component index.
416            fn ind() -> u8;
417        }
418        /// Gets a component type `T` from a raw pointer of `Component`.
419        ///
420        /// Implemented for `&mut T` and `&T`.
421        pub trait Get<T> {
422            /// Gets component type.
423            ///
424            /// This is an unsafe method because the lifetime of the return value is only valid for the scope.
425            unsafe fn get(self) -> Option<T>;
426        }
427        /// Creates a new entity from a set of components.
428        pub trait Push<T> {
429            /// Pushes/spawns a new entity.
430            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/// Helper macro for counting size of a tuple.
458///
459/// This is used to check that every component in a system is uniquely accessed.
460#[macro_export]
461macro_rules! tup_count(
462    () => {0};
463    ($x0:ident $(, $y:ident)* $(,)?) => {1 + tup_count!($($y),*)};
464);
465
466/// Generates mask pattern based on a set of components.
467#[macro_export]
468macro_rules! mask_pat(
469    ($($x:ident),* $(,)?) => {($(1 << <Component as Ind<$x>>::ind())|*)}
470);
471
472/// Used internally by other macros.
473///
474/// Checks that same component is not used twice.
475#[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/// Declares and executes a system.
485///
486/// Example: `system!(world, |pos: &mut Position| {...});`
487///
488/// One or more filters can be added using the `world` object:
489///
490/// `system!(world, ?|n| world.has_component::<Velocity>(); |pos: &mut Position| {...})`
491///
492/// *Warning! This is unsafe to call nested when accessing same entities more than one.*
493#[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/// Same as `system!`, but with entity ids.
516///
517/// Example: `system_ids!(world, ?|n| ...; id, |&Position| {...});`
518#[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/// Enumerates indices of entities only.
544#[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/// Accesses a single entity.
562///
563/// *Warning! This is unsafe to call nested when accessing same entities more than one.*
564#[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/// Accesses an entity.
575///
576/// This macro is used internally.
577#[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/// Accesses an entity, but without checking active mask.
601///
602/// This macro is used internally.
603#[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/// Calls `push` macro with smaller arguments.
622#[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/// Generates `Push` impl for `World`.
670#[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/// Generates `Ind` impl for `Component`.
706#[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}