my_ecs/lib.rs
1#![doc = include_str!("../README.md")]
2
3// Clients may use `ds` module directly. It's optional.
4pub(crate) mod default;
5pub mod ds;
6pub(crate) mod ecs;
7pub(crate) mod util;
8
9pub(crate) type DefaultRandomState = std::hash::RandomState;
10pub(crate) const MAX_GROUP: usize = 4;
11
12/// Imports all you need at once.
13pub mod prelude {
14 pub use super::global;
15 pub use super::my_ecs_macro_with_doc::*;
16 pub use super::{default::prelude::*, ds::prelude::*, ecs::prelude::*, util::prelude::*};
17 pub use super::{log, tinfo};
18 pub use rayon::prelude::*;
19}
20
21pub mod test_util {
22 pub use super::util::call_timeout;
23}
24
25/// Global functions.
26pub mod global {
27 pub use super::ecs::stat;
28 #[cfg(target_arch = "wasm32")]
29 pub use super::ecs::web::{set_panic_hook_once, web_panic_hook};
30}
31
32/// Imports `my_ecs_macro` with testable doc.
33mod my_ecs_macro_with_doc {
34 /// Implements [`Component`](crate::ecs::ent::component::Component) for the
35 /// type.
36 ///
37 /// # Examples
38 ///
39 /// ```
40 /// use my_ecs::prelude::*;
41 ///
42 /// // Zero-sized marker component.
43 /// #[derive(Component)]
44 /// struct Ca;
45 ///
46 /// #[derive(Component)]
47 /// struct Cb(u8);
48 ///
49 /// #[derive(Component)]
50 /// struct Cc {
51 /// vel: (f32, f32, f32),
52 /// acc: (f32, f32, f32),
53 /// }
54 /// ```
55 pub use my_ecs_macros::Component;
56
57 /// Impelments [`Entity`](crate::ecs::ent::entity::Entity) for the type.
58 ///
59 /// Actually, you don't have to define entity type explicitly, but by doing
60 /// so, the crate becomes to be able to provide easy-to-use functions for
61 /// you.
62 ///
63 /// You can designate which container type you use as well by attributes
64 /// `container` and `random_state`.
65 ///
66 /// `container` means which container type you use for the entity. You can
67 /// use your own types or choose one of built-in types shown below.
68 /// * [`SparseSet`](crate::default::ent_cont::SparseSet) - Default
69 /// * [`ChunkSparseSet`](crate::default::ent_cont::ChunkSparseSet)
70 ///
71 /// `random_state` means a state to make a hasher.
72 /// [`std::hash::RandomState`] is default.
73 ///
74 /// # Examples
75 ///
76 /// ```
77 /// use my_ecs::prelude::*;
78 ///
79 /// #[derive(Component)]
80 /// struct Ca;
81 ///
82 /// #[derive(Entity)]
83 /// struct Ea {
84 /// a: Ca,
85 /// }
86 ///
87 /// // Or, you can customize entity container.
88 /// #[derive(Entity)]
89 /// #[container(ChunkSparseSet)]
90 /// #[random_state(std::hash::RandomState)]
91 /// struct Eb {
92 /// a: Ca,
93 /// }
94 /// ```
95 pub use my_ecs_macros::Entity;
96
97 /// Implements [`Resource`](crate::ecs::resource::Resource) for the type.
98 ///
99 /// # Examples
100 ///
101 /// ```
102 /// use my_ecs::prelude::*;
103 ///
104 /// #[derive(Resource)]
105 /// struct R(i32);
106 /// ```
107 pub use my_ecs_macros::Resource;
108
109 /// Implements [`Filter`] for the type, and implements [`Select`] optionally
110 /// if `Target` is defined.
111 ///
112 /// Types implementing `Filter` only can be used in [`EntWrite`] only. Types
113 /// implementing both `Filter` and `Select`, on the other hand, also can be
114 /// used in [`Read`] and [`Write`] as well. Because `Read` and `Write`
115 /// mean requesting read or write access to a specific *target* component.
116 ///
117 /// See [`Filter`] and [`Select`] for more details.
118 ///
119 /// # Examples
120 ///
121 /// ```
122 /// use my_ecs::prelude::*;
123 ///
124 /// #[derive(Component)] struct Ca;
125 /// #[derive(Component)] struct Cb;
126 /// #[derive(Component)] struct Cc;
127 /// #[derive(Component)] struct Cd;
128 /// #[derive(Component)] struct Ce;
129 ///
130 /// // Declares `Fa` with an implemenation of `Filter`.
131 /// filter!(Fa, All = Ca);
132 ///
133 /// // Declares `Fb` with an implemenation of `Filter`.
134 /// filter!(Fb, All = Ca, Any = Cb, None = Cc);
135 ///
136 /// // Declares `Fc` with an implementation of `Filter` and `Select`.
137 /// filter!(Fc, Target = Ca);
138 ///
139 /// // Declares `Fd` with an implementation of `Filter` and `Select`.
140 /// filter!(Fd, Target = Ca, All = Cb, Any = Cc, None = (Cd, Ce));
141 ///
142 /// // All types implement `Filter` which means they can be used in
143 /// // `EntWrite`.
144 /// fn system_a(ew: EntWrite<(Fa, Fb, Fc, Fd)>) { /* ... */ }
145 ///
146 /// // On the other hand, `Fc` and `Fd` can be used in `Read` and `Write`
147 /// // because they implement `Select` too.
148 /// fn system_b(r: Read<Fc>, w: Write<Fd>) { /* ... */ }
149 /// ```
150 ///
151 /// [`Filter`]: crate::ecs::sys::select::Filter
152 /// [`Select`]: crate::ecs::sys::select::Select
153 /// [`EntWrite`]: crate::ecs::sys::query::EntWrite
154 /// [`Read`]: crate::ecs::sys::query::Read
155 /// [`Write`]: crate::ecs::sys::query::Write
156 pub use my_ecs_macros::filter;
157
158 /// Implements [`Request`] for the type.
159 ///
160 /// Functions implement the `Request` by the crate internally, but others
161 /// such as struct or enum don't. You must implement the `Request` yourself
162 /// if you want it to act as a system. This macro helps you write just a
163 /// little bit of code for that.
164 ///
165 /// # Examples
166 ///
167 /// ```
168 /// use my_ecs::prelude::*;
169 ///
170 /// #[derive(Component)] struct Ca;
171 /// #[derive(Component)] struct Cb;
172 /// #[derive(Resource)] struct Ra(i32);
173 /// #[derive(Resource)] struct Rb(i32);
174 ///
175 /// filter!(Fa, Target = Ca);
176 /// filter!(Fb, Target = Cb);
177 /// filter!(Fc, All = (Ca, Cb));
178 ///
179 /// // Declares `Req` with an implementation of `Request`.
180 /// // You can omit Read, Write, ResRead, ResWrite, or EntWrite.
181 /// request!(Req, Read = Fa, Write = Fb, ResRead = Ra, ResWrite = Rb, EntWrite = Fc);
182 ///
183 /// struct Sys {
184 /// data: String,
185 /// }
186 ///
187 /// impl System for Sys {
188 /// type Request = Req;
189 /// fn run(&mut self, resp: Response<'_, Self::Request>) { /* ... */ }
190 /// }
191 /// ```
192 ///
193 /// [`Request`]: crate::ecs::sys::request::Request
194 pub use my_ecs_macros::request;
195}