Skip to main content

bevy_ecs/message/
mod.rs

1//! [`Message`] functionality.
2
3mod iterators;
4mod message_cursor;
5mod message_mutator;
6mod message_reader;
7mod message_registry;
8mod message_writer;
9mod messages;
10mod mut_iterators;
11mod update;
12
13pub use iterators::*;
14pub use message_cursor::*;
15pub use message_mutator::*;
16pub use message_reader::*;
17pub use message_registry::*;
18pub use message_writer::*;
19pub use messages::*;
20pub use mut_iterators::*;
21pub use update::*;
22
23pub use bevy_ecs_macros::Message;
24
25use crate::change_detection::MaybeLocation;
26#[cfg(feature = "bevy_reflect")]
27use bevy_reflect::Reflect;
28use core::{
29    cmp::Ordering,
30    fmt,
31    hash::{Hash, Hasher},
32    marker::PhantomData,
33};
34
35/// A buffered message for pull-based event handling.
36///
37/// Messages can be written with [`MessageWriter`] and read using the [`MessageReader`] system parameter.
38/// Messages are stored in the [`Messages<M>`] resource, and require periodically polling the world for new messages,
39/// typically in a system that runs as part of a schedule.
40///
41/// A [`MessageReader`] system parameter tracks the consumption of these events on a per-system basis using a [`Local<MessageCursor>`],
42/// which will guarantee each system an opportunity to read the event once.
43///
44/// While the polling imposes a small overhead, messages are useful for efficiently batch processing
45/// a large number of messages at once. For cases like these, messages can be more efficient than [`Event`]s (which are handled via [`Observer`]s).
46///
47/// Unlike [`Event`]s triggered for observers, messages are evaluated at fixed points in the schedule
48/// rather than immediately when they are sent. This allows for more predictable scheduling, and deferring
49/// message processing to a later point in time.
50///
51/// Messages must be thread-safe.
52///
53/// # Usage
54///
55/// The [`Message`] trait can be derived:
56///
57/// ```
58/// # use bevy_ecs::prelude::*;
59/// #
60/// #[derive(Message)]
61/// struct Greeting(String);
62/// ```
63///
64/// The message can then be written to the message buffer using a [`MessageWriter`]:
65///
66/// ```
67/// # use bevy_ecs::prelude::*;
68/// #
69/// # #[derive(Message)]
70/// # struct Greeting(String);
71/// #
72/// fn write_hello(mut writer: MessageWriter<Greeting>) {
73///     writer.write(Greeting("Hello!".to_string()));
74/// }
75/// ```
76///
77/// Messages can be efficiently read using a [`MessageReader`]:
78///
79/// ```
80/// # use bevy_ecs::prelude::*;
81/// #
82/// # #[derive(Message)]
83/// # struct Greeting(String);
84/// #
85/// fn read_messages(mut reader: MessageReader<Greeting>) {
86///     // Process all messages of type `Greeting`.
87///     for Greeting(greeting) in reader.read() {
88///         println!("{greeting}");
89///     }
90/// }
91/// ```
92/// [`Event`]: crate::event::Event
93/// [`Observer`]: crate::observer::Observer
94/// [`Local<MessageCursor>`]: crate::system::Local
95#[diagnostic::on_unimplemented(
96    message = "`{Self}` is not an `Message`",
97    label = "invalid `Message`",
98    note = "consider annotating `{Self}` with `#[derive(Message)]`"
99)]
100pub trait Message: Send + Sync + 'static {}
101
102#[derive(#[automatically_derived]
impl<M: ::core::fmt::Debug + Message> ::core::fmt::Debug for
    MessageInstance<M> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "MessageInstance", "message_id", &self.message_id, "message",
            &&self.message)
    }
}Debug)]
103#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl<M: Message> bevy_reflect::GetTypeRegistration for
            MessageInstance<M> where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <MessageId<M> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <M as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<M: Message> bevy_reflect::Typed for MessageInstance<M> where
            MessageInstance<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<MessageId<M>>("message_id"),
                                                    bevy_reflect::NamedField::new::<M>("message")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<M>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("M")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<M: Message> bevy_reflect::TypePath for MessageInstance<M> where
            MessageInstance<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_ecs::message::MessageInstance<"),
                                    <M as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("MessageInstance<"),
                                    <M as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MessageInstance")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::message".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::message")
            }
        }
        impl<M: Message> bevy_reflect::Reflect for MessageInstance<M> where
            MessageInstance<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<M: Message> bevy_reflect::func::args::GetOwnership for
            MessageInstance<M> where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl<M: Message> bevy_reflect::func::args::FromArg for
            MessageInstance<M> where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            type This<'from_arg> = MessageInstance<M>;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl<M: Message> bevy_reflect::func::IntoReturn for MessageInstance<M>
            where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl<M: Message> bevy_reflect::structs::Struct for MessageInstance<M>
            where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "message_id" =>
                        ::core::option::Option::Some(&self.message_id),
                    "message" => ::core::option::Option::Some(&self.message),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "message_id" =>
                        ::core::option::Option::Some(&mut self.message_id),
                    "message" =>
                        ::core::option::Option::Some(&mut self.message),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.message_id),
                    1usize => ::core::option::Option::Some(&self.message),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize =>
                        ::core::option::Option::Some(&mut self.message_id),
                    1usize => ::core::option::Option::Some(&mut self.message),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("message_id"),
                    1usize => ::core::option::Option::Some("message"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "message_id" => ::core::option::Option::Some(0usize),
                    "message" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("message_id",
                    bevy_reflect::PartialReflect::to_dynamic(&self.message_id));
                dynamic.insert_boxed("message",
                    bevy_reflect::PartialReflect::to_dynamic(&self.message));
                dynamic
            }
        }
        impl<M: Message> bevy_reflect::PartialReflect for MessageInstance<M>
            where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            message_id: <MessageId<M> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.message_id)?,
                            message: <M as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.message)?,
                        }))
            }
        }
        impl<M: Message> bevy_reflect::FromReflect for MessageInstance<M>
            where MessageInstance<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath,
            MessageId<M>: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection,
            M: bevy_reflect::FromReflect + bevy_reflect::TypePath +
            bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            message_id: <MessageId<M> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "message_id")?)?,
                            message: <M as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "message")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
104pub(crate) struct MessageInstance<M: Message> {
105    pub message_id: MessageId<M>,
106    pub message: M,
107}
108
109/// A [`MessageId`] uniquely identifies a message stored in a specific [`World`].
110///
111/// A [`MessageId`] can, among other things, be used to trace the flow of a [`Message`] from the point it was
112/// sent to the point it was processed. [`MessageId`]s increase monotonically by write order.
113///
114/// [`World`]: crate::world::World
115#[cfg_attr(
116    feature = "bevy_reflect",
117    derive(const _: () =
    {
        impl<M: Message> bevy_reflect::GetTypeRegistration for MessageId<M>
            where MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <usize as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <MaybeLocation as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<M: Message> bevy_reflect::Typed for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<usize>("id"),
                                                    bevy_reflect::NamedField::new::<MaybeLocation>("caller")]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<M>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("M")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<M: Message> bevy_reflect::TypePath for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_ecs::message::MessageId<"),
                                    <M as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("MessageId<"),
                                    <M as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MessageId")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::message".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::message")
            }
        }
        impl<M: Message> bevy_reflect::Reflect for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<M: Message> bevy_reflect::func::args::GetOwnership for
            MessageId<M> where MessageId<M>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            M: bevy_reflect::TypePath {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl<M: Message> bevy_reflect::func::args::FromArg for MessageId<M>
            where MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            type This<'from_arg> = MessageId<M>;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl<M: Message> bevy_reflect::func::IntoReturn for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl<M: Message> bevy_reflect::structs::Struct for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "id" => ::core::option::Option::Some(&self.id),
                    "caller" => ::core::option::Option::Some(&self.caller),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "id" => ::core::option::Option::Some(&mut self.id),
                    "caller" => ::core::option::Option::Some(&mut self.caller),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.id),
                    1usize => ::core::option::Option::Some(&self.caller),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.id),
                    1usize => ::core::option::Option::Some(&mut self.caller),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("id"),
                    1usize => ::core::option::Option::Some("caller"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "id" => ::core::option::Option::Some(0usize),
                    "caller" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("id",
                    bevy_reflect::PartialReflect::to_dynamic(&self.id));
                dynamic.insert_boxed("caller",
                    bevy_reflect::PartialReflect::to_dynamic(&self.caller));
                dynamic
            }
        }
        impl<M: Message> bevy_reflect::PartialReflect for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_hash(&self) -> ::core::option::Option<u64> {
                use ::core::hash::{Hash, Hasher};
                let mut hasher = bevy_reflect::utility::reflect_hasher();
                Hash::hash(&::core::any::Any::type_id(self), &mut hasher);
                Hash::hash(self, &mut hasher);
                ::core::option::Option::Some(Hasher::finish(&hasher))
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                let value =
                    <dyn bevy_reflect::PartialReflect>::try_downcast_ref::<Self>(value);
                if let ::core::option::Option::Some(value) = value {
                    ::core::option::Option::Some(::core::cmp::PartialEq::eq(self,
                            value))
                } else { ::core::option::Option::Some(false) }
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl<M: Message> bevy_reflect::FromReflect for MessageId<M> where
            MessageId<M>: ::core::any::Any + ::core::marker::Send +
            ::core::marker::Sync, M: bevy_reflect::TypePath {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            id: <usize as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "id")?)?,
                            caller: <MaybeLocation as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "caller")?)?,
                            _marker: ::core::default::Default::default(),
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect),
118    reflect(Clone, Debug, PartialEq, Hash)
119)]
120pub struct MessageId<M: Message> {
121    /// Uniquely identifies the message associated with this ID.
122    // This value corresponds to the order in which each message was written to the world.
123    pub id: usize,
124    /// The source code location that triggered this message.
125    pub caller: MaybeLocation,
126    #[cfg_attr(feature = "bevy_reflect", reflect(ignore, clone))]
127    pub(super) _marker: PhantomData<M>,
128}
129
130impl<M: Message> Copy for MessageId<M> {}
131
132impl<M: Message> Clone for MessageId<M> {
133    fn clone(&self) -> Self {
134        *self
135    }
136}
137
138impl<M: Message> fmt::Display for MessageId<M> {
139    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140        <Self as fmt::Debug>::fmt(self, f)
141    }
142}
143
144impl<M: Message> fmt::Debug for MessageId<M> {
145    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146        f.write_fmt(format_args!("message<{0}>#{1}",
        core::any::type_name::<M>().split("::").last().unwrap(), self.id))write!(
147            f,
148            "message<{}>#{}",
149            core::any::type_name::<M>().split("::").last().unwrap(),
150            self.id,
151        )
152    }
153}
154
155impl<M: Message> PartialEq for MessageId<M> {
156    fn eq(&self, other: &Self) -> bool {
157        self.id == other.id
158    }
159}
160
161impl<M: Message> Eq for MessageId<M> {}
162
163impl<M: Message> PartialOrd for MessageId<M> {
164    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
165        Some(self.cmp(other))
166    }
167}
168
169impl<M: Message> Ord for MessageId<M> {
170    fn cmp(&self, other: &Self) -> Ordering {
171        self.id.cmp(&other.id)
172    }
173}
174
175impl<M: Message> Hash for MessageId<M> {
176    fn hash<H: Hasher>(&self, state: &mut H) {
177        Hash::hash(&self.id, state);
178    }
179}