bones_ecs/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(doc, allow(unknown_lints))]
3#![deny(rustdoc::all)]
4#![warn(missing_docs)]
5
6pub mod atomic {
7    //! Atomic Refcell implmentation.
8    //!
9    //! Atomic Refcells are from the [`atomic_refcell`] crate.
10    //!
11    //! [`atomic_refcell`]: https://docs.rs/atomic_refcell
12    pub use atomicell::*;
13}
14pub mod bitset;
15pub mod components;
16pub mod entities;
17pub mod resources;
18pub mod stage;
19pub mod system;
20
21pub use bones_schema as schema;
22pub use bones_utils as utils;
23
24mod world;
25pub use world::{FromWorld, World};
26
27/// The prelude.
28pub mod prelude {
29    pub use atomicell::*;
30    pub use bitset_core::BitSet;
31    pub use bones_schema::prelude::*;
32    pub use bones_utils::prelude::*;
33    pub use branches::{likely, unlikely};
34
35    pub use crate::{
36        bitset::*,
37        components::*,
38        entities::*,
39        resources::*,
40        stage::{CoreStage::*, *},
41        system::*,
42        FromWorld, UnwrapMany, World,
43    };
44
45    #[cfg(feature = "derive")]
46    pub use bones_ecs_macros::*;
47
48    // Make bones_schema available for derive macros
49    pub use bones_schema;
50}
51
52/// Helper trait for unwraping each item in an array.
53///
54/// # Example
55///
56/// ```
57/// # use bones_ecs::UnwrapMany;
58/// let data = [Some(1), Some(2)];
59/// let [data1, data2] = data.unwrap_many();
60/// ```
61pub trait UnwrapMany<const N: usize, T> {
62    /// Unwrap all the items in an array.
63    fn unwrap_many(self) -> [T; N];
64}
65
66impl<const N: usize, T> UnwrapMany<N, T> for [Option<T>; N] {
67    fn unwrap_many(self) -> [T; N] {
68        let mut iter = self.into_iter();
69        std::array::from_fn(|_| iter.next().unwrap().unwrap())
70    }
71}
72impl<const N: usize, T, E: std::fmt::Debug> UnwrapMany<N, T> for [Result<T, E>; N] {
73    fn unwrap_many(self) -> [T; N] {
74        let mut iter = self.into_iter();
75        std::array::from_fn(|_| iter.next().unwrap().unwrap())
76    }
77}
78
79#[cfg(test)]
80mod test {
81    use crate::prelude::*;
82
83    #[test]
84    fn insert_comp_with_gap() {
85        let w = World::new();
86
87        #[derive(HasSchema, Default, Clone)]
88        #[repr(C)]
89        struct MyComp(u32, u32, u32);
90
91        w.run_system(
92            |mut entities: ResMut<Entities>, mut comps: CompMut<MyComp>| {
93                for _ in 0..3 {
94                    entities.create();
95                }
96
97                let e = entities.create();
98                comps.insert(e, default());
99            },
100            (),
101        )
102    }
103}