1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3
4pub mod prelude {
6 pub use crate::{CastInto, Kind};
7 pub use crate::{
8 ComponentInstance, InsertInstance, InsertInstanceWorld, SpawnInstance, SpawnInstanceWorld,
9 };
10 pub use crate::{ContainsInstance, Instance, InstanceMut, InstanceRef};
11 pub use crate::{GetInstanceCommands, InstanceCommands};
12}
13
14mod instance;
15
16use bevy_ecs::world::DeferredWorld;
17use bevy_reflect::Reflect;
18pub use instance::*;
19
20use bevy_ecs::component::Mutable;
21use bevy_ecs::{prelude::*, query::QueryFilter};
22
23pub trait Kind: 'static + Send + Sized + Sync {
55 type Filter: QueryFilter;
57
58 fn debug_name() -> String {
63 disqualified::ShortName::of::<Self>().to_string()
64 }
65}
66
67impl<T: Component> Kind for T {
68 type Filter = With<T>;
69}
70
71#[derive(Debug, Reflect)]
75pub struct Any;
76
77impl Kind for Any {
78 type Filter = ();
79}
80
81pub trait CastInto<T: Kind>: Kind {
83 #[doc(hidden)]
84 unsafe fn cast(instance: Instance<Self>) -> Instance<T> {
85 Instance::from_entity_unchecked(instance.entity())
88 }
89}
90
91impl<T: Kind> CastInto<T> for T {
92 unsafe fn cast(instance: Instance<Self>) -> Instance<T> {
93 Instance::from_entity_unchecked(instance.entity())
94 }
95}
96
97pub trait SpawnInstance {
99 fn spawn_instance<T: Component>(&mut self, instance: T) -> InstanceCommands<'_, T>;
101}
102
103impl SpawnInstance for Commands<'_, '_> {
104 fn spawn_instance<T: Component>(&mut self, instance: T) -> InstanceCommands<'_, T> {
105 let entity = self.spawn(instance).id();
106 unsafe { InstanceCommands::from_entity_unchecked(self.entity(entity)) }
108 }
109}
110
111pub trait SpawnInstanceWorld {
113 fn spawn_instance<T: Component>(&'_ mut self, instance: T) -> InstanceRef<'_, T>;
115
116 fn spawn_instance_mut<T: Component<Mutability = Mutable>>(
118 &'_ mut self,
119 instance: T,
120 ) -> InstanceMut<'_, T>;
121}
122
123impl SpawnInstanceWorld for World {
124 fn spawn_instance<T: Component>(&'_ mut self, instance: T) -> InstanceRef<'_, T> {
125 let mut entity = self.spawn_empty();
126 entity.insert(instance);
127 unsafe { InstanceRef::from_entity_unchecked(entity.into_readonly()) }
129 }
130
131 fn spawn_instance_mut<T: Component<Mutability = Mutable>>(
132 &'_ mut self,
133 instance: T,
134 ) -> InstanceMut<'_, T> {
135 let mut entity = self.spawn_empty();
136 entity.insert(instance);
137 unsafe { InstanceMut::from_entity_unchecked(entity.into_mutable()) }
139 }
140}
141
142pub trait InsertInstance {
144 fn insert_instance<T: Component>(&mut self, instance: T) -> InstanceCommands<'_, T>;
146}
147
148impl InsertInstance for EntityCommands<'_> {
149 fn insert_instance<T: Component>(&mut self, instance: T) -> InstanceCommands<'_, T> {
150 self.insert(instance);
151 unsafe { InstanceCommands::from_entity_unchecked(self.reborrow()) }
153 }
154}
155
156pub trait InsertInstanceWorld {
158 fn insert_instance<T: Component>(&'_ mut self, instance: T) -> InstanceRef<'_, T>;
160
161 fn insert_instance_mut<T: Component<Mutability = Mutable>>(
165 &'_ mut self,
166 instance: T,
167 ) -> InstanceMut<'_, T>;
168}
169
170impl InsertInstanceWorld for EntityWorldMut<'_> {
171 fn insert_instance<T: Component>(&'_ mut self, instance: T) -> InstanceRef<'_, T> {
172 self.insert(instance);
173 InstanceRef::from_entity(self.as_readonly()).unwrap()
174 }
175
176 fn insert_instance_mut<T: Component<Mutability = Mutable>>(
177 &'_ mut self,
178 instance: T,
179 ) -> InstanceMut<'_, T> {
180 self.insert(instance);
181 InstanceMut::from_entity(self.as_mutable()).unwrap()
182 }
183}
184
185pub trait ComponentInstance {
187 fn instance<T: Component>(&'_ self, instance: Instance<T>) -> InstanceRef<'_, T> {
193 self.get_instance(instance.entity()).unwrap()
194 }
195
196 fn get_instance<T: Component>(&'_ self, entity: Entity) -> Option<InstanceRef<'_, T>>;
198
199 fn instance_mut<T: Component<Mutability = Mutable>>(
207 &'_ mut self,
208 instance: Instance<T>,
209 ) -> InstanceMut<'_, T> {
210 self.get_instance_mut(instance.entity()).unwrap()
211 }
212
213 fn get_instance_mut<T: Component<Mutability = Mutable>>(
217 &'_ mut self,
218 entity: Entity,
219 ) -> Option<InstanceMut<'_, T>>;
220}
221
222impl ComponentInstance for World {
223 fn get_instance<T: Component>(&'_ self, entity: Entity) -> Option<InstanceRef<'_, T>> {
224 InstanceRef::from_entity(self.get_entity(entity).ok()?)
225 }
226
227 fn get_instance_mut<T: Component<Mutability = Mutable>>(
228 &'_ mut self,
229 entity: Entity,
230 ) -> Option<InstanceMut<'_, T>> {
231 InstanceMut::from_entity(self.get_entity_mut(entity).ok()?.into_mutable())
232 }
233}
234
235impl ComponentInstance for DeferredWorld<'_> {
236 fn get_instance<T: Component>(&'_ self, entity: Entity) -> Option<InstanceRef<'_, T>> {
237 InstanceRef::from_entity(self.get_entity(entity).ok()?)
238 }
239
240 fn get_instance_mut<T: Component<Mutability = Mutable>>(
241 &'_ mut self,
242 entity: Entity,
243 ) -> Option<InstanceMut<'_, T>> {
244 InstanceMut::from_entity(self.get_entity_mut(entity).ok()?)
245 }
246}
247
248#[cfg(test)]
249mod tests {
250 use super::*;
251 use bevy_ecs::system::RunSystemOnce;
252
253 fn count<T: Kind>(query: Query<Instance<T>>) -> usize {
254 query.iter().count()
255 }
256
257 #[test]
258 fn kind_with() {
259 #[derive(Component)]
260 struct Foo;
261
262 let mut world = World::new();
263 world.spawn(Foo);
264 assert_eq!(world.run_system_once(count::<Foo>).unwrap(), 1);
265 }
266
267 #[test]
268 fn kind_without() {
269 #[derive(Component)]
270 struct Foo;
271
272 struct NotFoo;
273
274 impl Kind for NotFoo {
275 type Filter = Without<Foo>;
276 }
277
278 let mut world = World::new();
279 world.spawn(Foo);
280 assert_eq!(world.run_system_once(count::<NotFoo>).unwrap(), 0);
281 }
282
283 #[test]
284 fn kind_multi() {
285 #[derive(Component)]
286 struct Foo;
287
288 #[derive(Component)]
289 struct Bar;
290
291 let mut world = World::new();
292 world.spawn((Foo, Bar));
293 assert_eq!(world.run_system_once(count::<Foo>).unwrap(), 1);
294 assert_eq!(world.run_system_once(count::<Bar>).unwrap(), 1);
295 }
296
297 #[test]
298 fn kind_cast() {
299 #[derive(Component)]
300 struct Foo;
301
302 #[derive(Component)]
303 struct Bar;
304
305 impl CastInto<Bar> for Foo {}
306
307 let any = Instance::<Any>::PLACEHOLDER;
308 let foo = Instance::<Foo>::PLACEHOLDER;
309 let bar = foo.cast_into::<Bar>();
310 assert!(foo.cast_into_any() == any);
311 assert!(bar.cast_into_any() == any);
312 assert!(bar.entity() == foo.entity());
316 }
317}