moonshine_kind/
instance.rs

1use std::{
2    cmp::Ordering,
3    fmt,
4    hash::{Hash, Hasher},
5    marker::PhantomData,
6    ops::{Deref, DerefMut},
7};
8
9use bevy_ecs::change_detection::MaybeLocation;
10use bevy_ecs::component::Mutable;
11use bevy_ecs::relationship::RelationshipSourceCollection;
12use bevy_ecs::{
13    archetype::Archetype,
14    component::{ComponentId, Components, Tick},
15    entity::{EntityMapper, MapEntities},
16    prelude::*,
17    query::{FilteredAccess, QueryData, ReadOnlyQueryData, WorldQuery},
18    storage::{Table, TableRow},
19    system::EntityCommands,
20    world::unsafe_world_cell::UnsafeWorldCell,
21};
22use bevy_reflect::Reflect;
23
24use crate::{Any, CastInto, Kind};
25
26/// Represents an [`Entity`] of [`Kind`] `T`.
27///
28/// `Instance<Any>` is functionally equivalent to an entity.
29///
30/// # Usage
31/// An `Instance<T>` can be used to access entities in a "kind-safe" manner to improve safety and readability.
32///
33/// This type is designed to behave exactly like an [`Entity`].
34///
35/// This means you may use it as a [`Query`] parameter, pass it to [`Commands`] to access [`InstanceCommands<T>`],
36/// or store it as a type-safe reference to an [`Entity`].
37///
38/// Note that an `Instance<T>` has `'static` lifetime and does not contain any [`Component`] data.
39/// It *only* contains type information.
40///
41/// # Example
42/// ```
43/// # use bevy::prelude::*;
44/// # use moonshine_kind::prelude::*;
45///
46/// #[derive(Component)]
47/// struct Apple;
48///
49/// #[derive(Component)]
50/// struct Orange;
51///
52/// struct Fruit;
53///
54/// impl Kind for Fruit {
55///     type Filter = Or<(With<Apple>, With<Orange>)>;
56/// }
57///
58/// #[derive(Resource, Deref, DerefMut)]
59/// struct FruitBasket(Vec<Instance<Fruit>>);
60///
61/// fn collect_fruits(mut basket: ResMut<FruitBasket>, fruits: Query<Instance<Fruit>>) {
62///     for fruit in fruits.iter() {
63///         println!("{fruit:?}");
64///         basket.push(fruit);
65///     }
66/// }
67///
68/// # bevy_ecs::system::assert_is_system(collect_fruits);
69/// ```
70#[derive(Reflect)]
71pub struct Instance<T: Kind>(Entity, #[reflect(ignore)] PhantomData<T>);
72
73impl<T: Kind> Instance<T> {
74    /// Same as [`Entity::PLACEHOLDER`], but for an [`Instance<T>`].
75    pub const PLACEHOLDER: Self = Self(Entity::PLACEHOLDER, PhantomData);
76
77    /// Creates a new instance of kind `T` from some [`Entity`].
78    ///
79    /// # Usage
80    /// This function is useful when you **know** an `Entity` is of a specific kind and you
81    /// need an `Instance<T>` with no way to validate it.
82    ///
83    /// See [`Instance::from_entity`] for a safer alternative.
84    ///
85    /// # Safety
86    /// Assumes `entity` is a valid instance of kind `T`.
87    ///
88    /// # Example
89    /// ```
90    /// # use bevy::prelude::*;
91    /// # use moonshine_kind::prelude::*;
92    ///
93    /// #[derive(Component)]
94    /// struct Apple;
95    ///
96    /// fn init_apple(entity: Entity, commands: &mut Commands) -> Instance<Apple> {
97    ///     commands.entity(entity).insert(Apple);
98    ///     // SAFE: `entity` will be a valid instance of `Apple`.
99    ///     unsafe { Instance::from_entity_unchecked(entity) }
100    /// }
101    /// ```
102    pub unsafe fn from_entity_unchecked(entity: Entity) -> Self {
103        Self(entity, PhantomData)
104    }
105
106    /// Returns the [`Entity`] of this instance.
107    pub fn entity(&self) -> Entity {
108        self.0
109    }
110
111    /// Converts this instance into an instance of another kind [`Kind`] `U`.
112    ///
113    /// # Usage
114    /// A kind `T` is safety convertible to another kind `U` if `T` implements [`CastInto<U>`].
115    ///
116    /// See [`kind`] macro for usage examples.
117    pub fn cast_into<U: Kind>(self) -> Instance<U>
118    where
119        T: CastInto<U>,
120    {
121        T::cast_into(self)
122    }
123
124    /// Converts this instance into an instance of [`Kind`] [`Any`].
125    ///
126    /// # Usage
127    ///
128    /// Any [`Instance<T>`] can be safely cast into an [`Instance<Any>`] using this function.
129    pub fn cast_into_any(self) -> Instance<Any> {
130        // SAFE: All instances are of kind `Any`.
131        unsafe { self.cast_into_unchecked() }
132    }
133
134    /// Converts this instance into an instance of another kind [`Kind`] `U` without any validation.
135    ///
136    /// # Usage
137    /// This function is useful when you **know** an `Instance<T>` is convertible to a specific type and you
138    /// need an `Instance<U>` with no way to validate it.
139    ///
140    /// Always prefer to explicitly declare safe casts using [`kind`] macro and use [`Instance::cast_into`] instead of this.
141    ///
142    /// # Safety
143    /// Assumes this instance is also a valid `Instance<U>`.
144    pub unsafe fn cast_into_unchecked<U: Kind>(self) -> Instance<U> {
145        Instance::from_entity_unchecked(self.entity())
146    }
147}
148
149impl<T: Component> Instance<T> {
150    /// Creates a new instance of kind `T` from some [`EntityRef`] if the entity has a [`Component`] of type `T`.
151    pub fn from_entity(entity: EntityRef) -> Option<Self> {
152        if entity.contains::<T>() {
153            // SAFE: `entity` must be of kind `T`.
154            Some(unsafe { Self::from_entity_unchecked(entity.id()) })
155        } else {
156            None
157        }
158    }
159}
160
161impl<T: Kind> Clone for Instance<T> {
162    fn clone(&self) -> Self {
163        *self
164    }
165}
166
167impl<T: Kind> Copy for Instance<T> {}
168
169impl<T: Kind> fmt::Debug for Instance<T> {
170    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171        write!(f, "{}({:?})", T::debug_name(), self.0)
172    }
173}
174
175impl<T: Kind> fmt::Display for Instance<T> {
176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177        write!(
178            f,
179            "{}({}v{})",
180            T::debug_name(),
181            self.0.index(),
182            self.0.generation()
183        )
184    }
185}
186
187impl<T: Kind> Hash for Instance<T> {
188    fn hash<H: Hasher>(&self, state: &mut H) {
189        self.0.hash(state);
190    }
191}
192
193impl<T: Kind> PartialEq for Instance<T> {
194    fn eq(&self, other: &Self) -> bool {
195        self.0 == other.0
196    }
197}
198
199impl<T: Kind> PartialEq<Entity> for Instance<T> {
200    fn eq(&self, other: &Entity) -> bool {
201        self.0 == *other
202    }
203}
204
205impl<T: Kind> PartialEq<Instance<T>> for Entity {
206    fn eq(&self, other: &Instance<T>) -> bool {
207        other == self
208    }
209}
210
211impl<T: Kind> Eq for Instance<T> {}
212
213impl<T: Kind> PartialOrd for Instance<T> {
214    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
215        Some(self.cmp(other))
216    }
217}
218
219impl<T: Kind> Ord for Instance<T> {
220    fn cmp(&self, other: &Self) -> Ordering {
221        self.0.cmp(&other.0)
222    }
223}
224
225impl<T: Kind> Deref for Instance<T> {
226    type Target = Entity;
227
228    fn deref(&self) -> &Self::Target {
229        &self.0
230    }
231}
232
233unsafe impl<T: Kind> WorldQuery for Instance<T> {
234    type Fetch<'a> = <T::Filter as WorldQuery>::Fetch<'a>;
235
236    type State = <T::Filter as WorldQuery>::State;
237
238    fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
239        <T::Filter as WorldQuery>::shrink_fetch(fetch)
240    }
241
242    unsafe fn init_fetch<'w>(
243        world: UnsafeWorldCell<'w>,
244        state: &Self::State,
245        last_change_tick: Tick,
246        change_tick: Tick,
247    ) -> Self::Fetch<'w> {
248        <T::Filter as WorldQuery>::init_fetch(world, state, last_change_tick, change_tick)
249    }
250
251    const IS_DENSE: bool = <T::Filter as WorldQuery>::IS_DENSE;
252
253    unsafe fn set_archetype<'w>(
254        fetch: &mut Self::Fetch<'w>,
255        state: &Self::State,
256        archetype: &'w Archetype,
257        table: &'w Table,
258    ) {
259        <T::Filter as WorldQuery>::set_archetype(fetch, state, archetype, table)
260    }
261
262    unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
263        <T::Filter as WorldQuery>::set_table(fetch, state, table)
264    }
265
266    fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
267        <T::Filter as WorldQuery>::update_component_access(state, access)
268    }
269
270    fn get_state(components: &Components) -> Option<Self::State> {
271        <T::Filter as WorldQuery>::get_state(components)
272    }
273
274    fn init_state(world: &mut World) -> Self::State {
275        <T::Filter as WorldQuery>::init_state(world)
276    }
277
278    fn matches_component_set(
279        state: &Self::State,
280        set_contains_id: &impl Fn(ComponentId) -> bool,
281    ) -> bool {
282        <T::Filter as WorldQuery>::matches_component_set(state, set_contains_id)
283    }
284}
285
286unsafe impl<T: Kind> ReadOnlyQueryData for Instance<T> {}
287
288unsafe impl<T: Kind> QueryData for Instance<T> {
289    type ReadOnly = Self;
290
291    const IS_READ_ONLY: bool = true;
292
293    type Item<'a> = Self;
294
295    fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
296        item
297    }
298
299    unsafe fn fetch<'w>(
300        _fetch: &mut Self::Fetch<'w>,
301        entity: Entity,
302        _table_row: TableRow,
303    ) -> Self::Item<'w> {
304        Instance::from_entity_unchecked(entity)
305    }
306}
307
308impl<T: Kind> MapEntities for Instance<T> {
309    fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
310        self.0 = entity_mapper.get_mapped(self.0);
311    }
312}
313
314impl<T: Kind> From<Instance<T>> for Entity {
315    fn from(instance: Instance<T>) -> Self {
316        instance.entity()
317    }
318}
319
320impl<T: Kind> RelationshipSourceCollection for Instance<T> {
321    type SourceIter<'a> = <Entity as RelationshipSourceCollection>::SourceIter<'a>;
322
323    fn new() -> Self {
324        Self::PLACEHOLDER
325    }
326
327    fn with_capacity(_capacity: usize) -> Self {
328        Self::new()
329    }
330
331    fn reserve(&mut self, additional: usize) {
332        self.0.reserve(additional);
333    }
334
335    fn add(&mut self, entity: Entity) -> bool {
336        self.0.add(entity)
337    }
338
339    fn remove(&mut self, entity: Entity) -> bool {
340        self.0.remove(entity)
341    }
342
343    fn iter(&self) -> Self::SourceIter<'_> {
344        self.0.iter()
345    }
346
347    fn len(&self) -> usize {
348        self.0.len()
349    }
350
351    fn clear(&mut self) {
352        self.0.clear();
353    }
354
355    fn shrink_to_fit(&mut self) {
356        self.0.shrink_to_fit();
357    }
358}
359
360impl From<Entity> for Instance<Any> {
361    fn from(entity: Entity) -> Self {
362        Self(entity, PhantomData)
363    }
364}
365
366/// Similar to [`ContainsEntity`], but for [`Instance<T>`].
367pub trait ContainsInstance<T: Kind> {
368    /// Returns the associated [`Instance<T>`].
369    fn instance(&self) -> Instance<T>;
370
371    /// Returns the [`Entity`] of the associated [`Instance<T>`].
372    fn entity(&self) -> Entity {
373        self.instance().entity()
374    }
375}
376
377/// A [`QueryData`] item which represents a reference to an [`Instance<T>`] and its associated [`Component`].
378///
379/// This is analogous to a `(Instance<T>, &T)` query.
380///
381/// # Usage
382/// If a [`Kind`] is also a component, it is often convenient to access the instance and component data together.
383/// This type is designed to make these queries more ergonomic.
384///
385/// You may use this type as either a [`Query`] parameter, or access it from an [`EntityRef`].
386///
387/// # Example
388/// ```
389/// # use bevy::prelude::*;
390/// # use moonshine_kind::prelude::*;
391///
392/// #[derive(Component)]
393/// struct Apple {
394///     freshness: f32,
395/// }
396///
397/// impl Apple {
398///     fn is_fresh(&self) -> bool {
399///         self.freshness >= 0.5
400///     }
401/// }
402///
403/// // Query Access:
404/// fn fresh_apples(query: Query<InstanceRef<Apple>>) -> Vec<Instance<Apple>> {
405///     query.iter()
406///         .filter_map(|apple| apple.is_fresh().then_some(apple.instance()))
407///         .collect()
408/// }
409///
410/// // Entity Access:
411/// fn fresh_apples_world<'a>(world: &'a World) -> Vec<InstanceRef<'a, Apple>> {
412///    world.iter_entities()
413///         .filter_map(|entity| InstanceRef::from_entity(entity))
414///         .collect()
415/// }
416///
417/// # bevy_ecs::system::assert_is_system(fresh_apples);
418/// ```
419pub struct InstanceRef<'a, T: Component>(Instance<T>, &'a T);
420
421unsafe impl<T: Component> WorldQuery for InstanceRef<'_, T> {
422    type Fetch<'w> = <(Instance<T>, &'static T) as WorldQuery>::Fetch<'w>;
423
424    type State = <(Instance<T>, &'static T) as WorldQuery>::State;
425
426    fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
427        <(Instance<T>, &T) as WorldQuery>::shrink_fetch(fetch)
428    }
429
430    unsafe fn init_fetch<'w>(
431        world: UnsafeWorldCell<'w>,
432        state: &Self::State,
433        last_run: Tick,
434        this_run: Tick,
435    ) -> Self::Fetch<'w> {
436        <(Instance<T>, &T) as WorldQuery>::init_fetch(world, state, last_run, this_run)
437    }
438
439    const IS_DENSE: bool = <(Instance<T>, &T) as WorldQuery>::IS_DENSE;
440
441    unsafe fn set_archetype<'w>(
442        fetch: &mut Self::Fetch<'w>,
443        state: &Self::State,
444        archetype: &'w Archetype,
445        table: &'w Table,
446    ) {
447        <(Instance<T>, &T) as WorldQuery>::set_archetype(fetch, state, archetype, table)
448    }
449
450    unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
451        <(Instance<T>, &T) as WorldQuery>::set_table(fetch, state, table)
452    }
453
454    fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
455        <(Instance<T>, &T) as WorldQuery>::update_component_access(state, access)
456    }
457
458    fn init_state(world: &mut World) -> Self::State {
459        <(Instance<T>, &T) as WorldQuery>::init_state(world)
460    }
461
462    fn get_state(components: &Components) -> Option<Self::State> {
463        <(Instance<T>, &T) as WorldQuery>::get_state(components)
464    }
465
466    fn matches_component_set(
467        state: &Self::State,
468        set_contains_id: &impl Fn(ComponentId) -> bool,
469    ) -> bool {
470        <(Instance<T>, &T) as WorldQuery>::matches_component_set(state, set_contains_id)
471    }
472}
473
474unsafe impl<T: Component> QueryData for InstanceRef<'_, T> {
475    type ReadOnly = Self;
476
477    const IS_READ_ONLY: bool = true;
478
479    type Item<'a> = InstanceRef<'a, T>;
480
481    fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
482        InstanceRef(item.0, item.1)
483    }
484
485    unsafe fn fetch<'w>(
486        fetch: &mut Self::Fetch<'w>,
487        entity: Entity,
488        table_row: TableRow,
489    ) -> Self::Item<'w> {
490        let (instance, data) = <(Instance<T>, &T) as QueryData>::fetch(fetch, entity, table_row);
491        InstanceRef(instance, data)
492    }
493}
494
495unsafe impl<T: Component> ReadOnlyQueryData for InstanceRef<'_, T> {}
496
497impl<'a, T: Component> InstanceRef<'a, T> {
498    /// Creates a new [`InstanceRef<T>`] from an [`EntityRef`] if it contains a given [`Component`] of type `T`.
499    pub fn from_entity(entity: EntityRef<'a>) -> Option<Self> {
500        Some(Self(
501            // SAFE: Kind is validated by `entity.get()` above.
502            unsafe { Instance::from_entity_unchecked(entity.id()) },
503            entity.get()?,
504        ))
505    }
506}
507
508impl<T: Component> Clone for InstanceRef<'_, T> {
509    fn clone(&self) -> Self {
510        *self
511    }
512}
513
514impl<T: Component> Copy for InstanceRef<'_, T> {}
515
516impl<T: Component> From<InstanceRef<'_, T>> for Instance<T> {
517    fn from(item: InstanceRef<T>) -> Self {
518        item.instance()
519    }
520}
521
522impl<T: Component> From<&InstanceRef<'_, T>> for Instance<T> {
523    fn from(item: &InstanceRef<T>) -> Self {
524        item.instance()
525    }
526}
527
528impl<T: Component> PartialEq for InstanceRef<'_, T> {
529    fn eq(&self, other: &Self) -> bool {
530        self.0 == other.0
531    }
532}
533
534impl<T: Component> Eq for InstanceRef<'_, T> {}
535
536impl<T: Component> Deref for InstanceRef<'_, T> {
537    type Target = T;
538
539    fn deref(&self) -> &Self::Target {
540        self.1
541    }
542}
543
544impl<T: Component> AsRef<Instance<T>> for InstanceRef<'_, T> {
545    fn as_ref(&self) -> &Instance<T> {
546        &self.0
547    }
548}
549
550impl<T: Component> AsRef<T> for InstanceRef<'_, T> {
551    fn as_ref(&self) -> &T {
552        self.1
553    }
554}
555
556impl<T: Component> ContainsInstance<T> for InstanceRef<'_, T> {
557    fn instance(&self) -> Instance<T> {
558        self.0
559    }
560}
561
562/// A [`QueryData`] item which represents a mutable reference to an [`Instance<T>`] and its associated [`Component`].
563///
564/// This is analogous to a `(Instance<T>, &mut T)` query.
565///
566/// # Usage
567/// This type behaves similar like [`InstanceRef<T>`] but allows mutable access to its associated [`Component`].
568///
569/// The main difference is that you cannot create an [`InstanceMut<T>`] from an [`EntityMut`].
570/// See [`InstanceMut::from_entity`] for more details.
571///
572/// See [`InstanceRef<T>`] for more information and examples.
573pub struct InstanceMut<'a, T: Component>(Instance<T>, Mut<'a, T>);
574
575unsafe impl<T: Component> WorldQuery for InstanceMut<'_, T> {
576    type Fetch<'w> = <(Instance<T>, &'static mut T) as WorldQuery>::Fetch<'w>;
577
578    type State = <(Instance<T>, &'static mut T) as WorldQuery>::State;
579
580    fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
581        <(Instance<T>, &mut T) as WorldQuery>::shrink_fetch(fetch)
582    }
583
584    unsafe fn init_fetch<'w>(
585        world: UnsafeWorldCell<'w>,
586        state: &Self::State,
587        last_run: Tick,
588        this_run: Tick,
589    ) -> Self::Fetch<'w> {
590        <(Instance<T>, &mut T) as WorldQuery>::init_fetch(world, state, last_run, this_run)
591    }
592
593    const IS_DENSE: bool = <(Instance<T>, &T) as WorldQuery>::IS_DENSE;
594
595    unsafe fn set_archetype<'w>(
596        fetch: &mut Self::Fetch<'w>,
597        state: &Self::State,
598        archetype: &'w Archetype,
599        table: &'w Table,
600    ) {
601        <(Instance<T>, &mut T) as WorldQuery>::set_archetype(fetch, state, archetype, table)
602    }
603
604    unsafe fn set_table<'w>(fetch: &mut Self::Fetch<'w>, state: &Self::State, table: &'w Table) {
605        <(Instance<T>, &mut T) as WorldQuery>::set_table(fetch, state, table)
606    }
607
608    fn update_component_access(state: &Self::State, access: &mut FilteredAccess<ComponentId>) {
609        <(Instance<T>, &T) as WorldQuery>::update_component_access(state, access)
610    }
611
612    fn init_state(world: &mut World) -> Self::State {
613        <(Instance<T>, &T) as WorldQuery>::init_state(world)
614    }
615
616    fn get_state(components: &Components) -> Option<Self::State> {
617        <(Instance<T>, &T) as WorldQuery>::get_state(components)
618    }
619
620    fn matches_component_set(
621        state: &Self::State,
622        set_contains_id: &impl Fn(ComponentId) -> bool,
623    ) -> bool {
624        <(Instance<T>, &T) as WorldQuery>::matches_component_set(state, set_contains_id)
625    }
626}
627
628unsafe impl<'b, T: Component<Mutability = Mutable>> QueryData for InstanceMut<'b, T> {
629    type ReadOnly = InstanceRef<'b, T>;
630
631    const IS_READ_ONLY: bool = false;
632
633    type Item<'a> = InstanceMut<'a, T>;
634
635    fn shrink<'wlong: 'wshort, 'wshort>(item: Self::Item<'wlong>) -> Self::Item<'wshort> {
636        InstanceMut(item.0, item.1)
637    }
638
639    unsafe fn fetch<'w>(
640        fetch: &mut Self::Fetch<'w>,
641        entity: Entity,
642        table_row: TableRow,
643    ) -> Self::Item<'w> {
644        let (instance, data) =
645            <(Instance<T>, &mut T) as QueryData>::fetch(fetch, entity, table_row);
646        InstanceMut(instance, data)
647    }
648}
649
650impl<'a, T: Component> InstanceMut<'a, T> {
651    /// Creates a new [`InstanceMut<T>`] from an [`EntityWorldMut`] if it contains a given [`Component`] of type `T`.
652    pub fn from_entity(entity: &'a mut EntityWorldMut) -> Option<Self>
653    where
654        T: Component<Mutability = Mutable>,
655    {
656        let id = entity.id();
657        let data = entity.get_mut::<T>()?;
658        Some(Self(
659            // SAFE: Kind is validated by `entity.get_mut()` above.
660            unsafe { Instance::from_entity_unchecked(id) },
661            data,
662        ))
663    }
664}
665
666impl<T: Component> From<InstanceMut<'_, T>> for Instance<T> {
667    fn from(item: InstanceMut<T>) -> Self {
668        item.instance()
669    }
670}
671
672impl<T: Component> From<&InstanceMut<'_, T>> for Instance<T> {
673    fn from(item: &InstanceMut<T>) -> Self {
674        item.instance()
675    }
676}
677
678impl<T: Component> PartialEq for InstanceMut<'_, T> {
679    fn eq(&self, other: &Self) -> bool {
680        self.0 == other.0
681    }
682}
683
684impl<T: Component> Eq for InstanceMut<'_, T> {}
685
686impl<T: Component> Deref for InstanceMut<'_, T> {
687    type Target = T;
688
689    fn deref(&self) -> &Self::Target {
690        self.1.as_ref()
691    }
692}
693
694impl<T: Component> DerefMut for InstanceMut<'_, T> {
695    fn deref_mut(&mut self) -> &mut Self::Target {
696        self.1.as_mut()
697    }
698}
699
700impl<T: Component> AsRef<Instance<T>> for InstanceMut<'_, T> {
701    fn as_ref(&self) -> &Instance<T> {
702        &self.0
703    }
704}
705
706impl<T: Component> AsRef<T> for InstanceMut<'_, T> {
707    fn as_ref(&self) -> &T {
708        self.1.as_ref()
709    }
710}
711
712impl<T: Component> AsMut<T> for InstanceMut<'_, T> {
713    fn as_mut(&mut self) -> &mut T {
714        self.1.as_mut()
715    }
716}
717
718impl<T: Component> DetectChanges for InstanceMut<'_, T> {
719    fn is_added(&self) -> bool {
720        self.1.is_added()
721    }
722
723    fn is_changed(&self) -> bool {
724        self.1.is_changed()
725    }
726
727    fn last_changed(&self) -> Tick {
728        self.1.last_changed()
729    }
730
731    fn added(&self) -> Tick {
732        self.1.added()
733    }
734
735    fn changed_by(&self) -> MaybeLocation {
736        self.1.changed_by()
737    }
738}
739
740impl<T: Component> DetectChangesMut for InstanceMut<'_, T> {
741    type Inner = T;
742
743    fn set_changed(&mut self) {
744        self.1.set_changed();
745    }
746
747    fn set_last_changed(&mut self, last_changed: Tick) {
748        self.1.set_last_changed(last_changed);
749    }
750
751    fn bypass_change_detection(&mut self) -> &mut Self::Inner {
752        self.1.bypass_change_detection()
753    }
754
755    fn set_added(&mut self) {
756        self.1.set_added();
757    }
758
759    fn set_last_added(&mut self, last_added: Tick) {
760        self.1.set_last_added(last_added);
761    }
762}
763
764impl<T: Component> ContainsInstance<T> for InstanceMut<'_, T> {
765    fn instance(&self) -> Instance<T> {
766        self.0
767    }
768}
769
770/// Similar to [`EntityWorldMut`], but with kind semantics.
771pub struct InstanceWorldMut<'w, T: Kind>(EntityWorldMut<'w>, PhantomData<T>);
772
773impl<'w, T: Kind> InstanceWorldMut<'w, T> {
774    /// Creates a new [`InstanceWorldMut<T>`] from [`EntityWorldMut`] without any validation.
775    ///
776    /// # Safety
777    /// Assumes `entity` is a valid instance of kind `T`.
778    pub unsafe fn from_entity_unchecked(entity: EntityWorldMut<'w>) -> Self {
779        Self(entity, PhantomData)
780    }
781}
782
783impl<'w, T: Component> InstanceWorldMut<'w, T> {
784    /// Creates a new [`InstanceWorldMut<T>`] from [`EntityWorldMut`] if it contains a [`Component`] of type `T`.
785    pub fn from_entity(entity: EntityWorldMut<'w>) -> Option<Self> {
786        if entity.contains::<T>() {
787            Some(Self(entity, PhantomData))
788        } else {
789            None
790        }
791    }
792}
793
794impl<T: Kind> ContainsInstance<T> for InstanceWorldMut<'_, T> {
795    fn instance(&self) -> Instance<T> {
796        // SAFE: `self.entity()` must be a valid instance of kind `T`.
797        unsafe { Instance::from_entity_unchecked(self.0.id()) }
798    }
799}
800
801impl<'w, T: Kind> Deref for InstanceWorldMut<'w, T> {
802    type Target = EntityWorldMut<'w>;
803
804    fn deref(&self) -> &Self::Target {
805        &self.0
806    }
807}
808
809impl<'w, T: Kind> DerefMut for InstanceWorldMut<'w, T> {
810    fn deref_mut(&mut self) -> &mut Self::Target {
811        &mut self.0
812    }
813}
814
815/// Extension trait to access [`InstanceCommands<T>`] from [`Commands`].
816///
817/// See [`InstanceCommands`] for more information.
818pub trait GetInstanceCommands<T: Kind> {
819    /// Returns the [`InstanceCommands<T>`] for an [`Instance<T>`].
820    fn instance(&mut self, instance: Instance<T>) -> InstanceCommands<'_, T>;
821}
822
823impl<T: Kind> GetInstanceCommands<T> for Commands<'_, '_> {
824    fn instance(&mut self, instance: Instance<T>) -> InstanceCommands<'_, T> {
825        InstanceCommands(self.entity(instance.entity()), PhantomData)
826    }
827}
828
829/// [`EntityCommands`] with kind semantics.
830///
831/// # Usage
832/// On its own, this type is not very useful. Instead, it is designed to be extended using traits.
833/// This allows you to design commands for a specific kind of an entity in a type-safe manner.
834///
835/// # Example
836/// ```
837/// # use bevy::prelude::*;
838/// # use moonshine_kind::prelude::*;
839///
840/// #[derive(Component)]
841/// struct Apple;
842///
843/// #[derive(Component)]
844/// struct Eat;
845///
846/// trait EatApple {
847///     fn eat(&mut self);
848/// }
849///
850/// impl EatApple for InstanceCommands<'_, Apple> {
851///     fn eat(&mut self) {
852///         info!("Crunch!");
853///         self.despawn();
854///     }
855/// }
856///
857/// fn eat_apples(apples: Query<Instance<Apple>, With<Eat>>, mut commands: Commands) {
858///     for apple in apples.iter() {
859///         commands.instance(apple).eat();
860///     }
861/// }
862///
863/// # bevy_ecs::system::assert_is_system(eat_apples);
864pub struct InstanceCommands<'a, T: Kind>(EntityCommands<'a>, PhantomData<T>);
865
866impl<'a, T: Kind> InstanceCommands<'a, T> {
867    /// Creates a new [`InstanceCommands<T>`] from [`EntityCommands`] without any validation.
868    ///
869    /// # Safety
870    /// Assumes `entity` is a valid instance of kind `T`.
871    pub unsafe fn from_entity_unchecked(entity: EntityCommands<'a>) -> Self {
872        Self(entity, PhantomData)
873    }
874
875    /// Creates a new [`InstanceCommands<T>`] from [`EntityRef`] if it contains a [`Component`] of type `T`.
876    pub fn from_entity(entity: EntityRef, commands: &'a mut Commands) -> Option<Self>
877    where
878        T: Component,
879    {
880        if entity.contains::<T>() {
881            Some(Self(commands.entity(entity.id()), PhantomData))
882        } else {
883            None
884        }
885    }
886
887    /// Returns the associated [`Instance<T>`].
888    pub fn instance(&self) -> Instance<T> {
889        // SAFE: `self.entity()` must be a valid instance of kind `T`.
890        unsafe { Instance::from_entity_unchecked(self.id()) }
891    }
892
893    /// Returns the associated [`EntityCommands`].
894    pub fn as_entity(&mut self) -> &mut EntityCommands<'a> {
895        &mut self.0
896    }
897
898    /// Equivalent to [`EntityCommands::insert`], but it returns `self` to maintain kind semantics.
899    pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {
900        self.0.insert(bundle);
901        self
902    }
903
904    /// Equivalent to [`EntityCommands::insert`], but it returns `self` to maintain kind semantics.
905    pub fn remove<U: Component>(&mut self) -> &mut Self {
906        self.0.remove::<U>();
907        self
908    }
909
910    /// Returns an [`InstanceCommands`] with a smaller lifetime.
911    ///
912    /// This is useful if you have `&mut InstanceCommands` but you need `InstanceCommands`.
913    pub fn reborrow(&mut self) -> InstanceCommands<'_, T> {
914        InstanceCommands(self.0.reborrow(), PhantomData)
915    }
916
917    /// Converts this [`InstanceCommands<T>`] into an [`InstanceCommands<U>`], given that `T` implements [`CastInto<U>`].
918    ///
919    /// See [`CastInto`] and [`kind`][crate::kind]  macro for more information on casting.
920    pub fn cast_into<U: Kind>(self) -> InstanceCommands<'a, U>
921    where
922        T: CastInto<U>,
923    {
924        // SAFE: `CastInto<U>` is implemented for `T`.
925        unsafe { InstanceCommands::from_entity_unchecked(self.0) }
926    }
927}
928
929impl<'a, T: Kind> From<InstanceCommands<'a, T>> for Instance<T> {
930    fn from(commands: InstanceCommands<'a, T>) -> Self {
931        commands.instance()
932    }
933}
934
935impl<'a, T: Kind> From<&InstanceCommands<'a, T>> for Instance<T> {
936    fn from(commands: &InstanceCommands<'a, T>) -> Self {
937        commands.instance()
938    }
939}
940
941impl<'a, T: Kind> Deref for InstanceCommands<'a, T> {
942    type Target = EntityCommands<'a>;
943
944    fn deref(&self) -> &Self::Target {
945        &self.0
946    }
947}
948
949impl<T: Kind> DerefMut for InstanceCommands<'_, T> {
950    fn deref_mut(&mut self) -> &mut Self::Target {
951        &mut self.0
952    }
953}
954
955impl<T: Kind> ContainsInstance<T> for InstanceCommands<'_, T> {
956    fn instance(&self) -> Instance<T> {
957        self.instance()
958    }
959}