//! [`Message`] functionality.12mod iterators;3mod message_cursor;4mod message_mutator;5mod message_reader;6mod message_registry;7mod message_writer;8mod messages;9mod mut_iterators;10mod update;1112pub use iterators::*;13pub use message_cursor::*;14pub use message_mutator::*;15pub use message_reader::*;16pub use message_registry::*;17pub use message_writer::*;18pub use messages::*;19pub use mut_iterators::*;20pub use update::*;2122pub use bevy_ecs_macros::Message;2324use crate::change_detection::MaybeLocation;25#[cfg(feature = "bevy_reflect")]26use bevy_reflect::Reflect;27use core::{28cmp::Ordering,29fmt,30hash::{Hash, Hasher},31marker::PhantomData,32};3334/// A buffered message for pull-based event handling.35///36/// Messages can be written with [`MessageWriter`] and read using the [`MessageReader`] system parameter.37/// Messages are stored in the [`Messages<M>`] resource, and require periodically polling the world for new messages,38/// typically in a system that runs as part of a schedule.39///40/// While the polling imposes a small overhead, messages are useful for efficiently batch processing41/// 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).42///43/// Unlike [`Event`]s triggered for observers, messages are evaluated at fixed points in the schedule44/// rather than immediately when they are sent. This allows for more predictable scheduling, and deferring45/// message processing to a later point in time.46///47/// Messages must be thread-safe.48///49/// # Usage50///51/// The [`Message`] trait can be derived:52///53/// ```54/// # use bevy_ecs::prelude::*;55/// #56/// #[derive(Message)]57/// struct Greeting(String);58/// ```59///60/// The message can then be written to the message buffer using a [`MessageWriter`]:61///62/// ```63/// # use bevy_ecs::prelude::*;64/// #65/// # #[derive(Message)]66/// # struct Greeting(String);67/// #68/// fn write_hello(mut writer: MessageWriter<Greeting>) {69/// writer.write(Greeting("Hello!".to_string()));70/// }71/// ```72///73/// Messages can be efficiently read using a [`MessageReader`]:74///75/// ```76/// # use bevy_ecs::prelude::*;77/// #78/// # #[derive(Message)]79/// # struct Greeting(String);80/// #81/// fn read_messages(mut reader: MessageReader<Greeting>) {82/// // Process all messages of type `Greeting`.83/// for Greeting(greeting) in reader.read() {84/// println!("{greeting}");85/// }86/// }87/// ```88/// [`Event`]: crate::event::Event89/// [`Observer`]: crate::observer::Observer90#[diagnostic::on_unimplemented(91message = "`{Self}` is not an `Message`",92label = "invalid `Message`",93note = "consider annotating `{Self}` with `#[derive(Message)]`"94)]95pub trait Message: Send + Sync + 'static {}9697#[derive(Debug)]98#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]99pub(crate) struct MessageInstance<M: Message> {100pub message_id: MessageId<M>,101pub message: M,102}103104/// A [`MessageId`] uniquely identifies a message stored in a specific [`World`].105///106/// A [`MessageId`] can, among other things, be used to trace the flow of a [`Message`] from the point it was107/// sent to the point it was processed. [`MessageId`]s increase monotonically by write order.108///109/// [`World`]: crate::world::World110#[cfg_attr(111feature = "bevy_reflect",112derive(Reflect),113reflect(Clone, Debug, PartialEq, Hash)114)]115pub struct MessageId<M: Message> {116/// Uniquely identifies the message associated with this ID.117// This value corresponds to the order in which each message was written to the world.118pub id: usize,119/// The source code location that triggered this message.120pub caller: MaybeLocation,121#[cfg_attr(feature = "bevy_reflect", reflect(ignore, clone))]122pub(super) _marker: PhantomData<M>,123}124125impl<M: Message> Copy for MessageId<M> {}126127impl<M: Message> Clone for MessageId<M> {128fn clone(&self) -> Self {129*self130}131}132133impl<M: Message> fmt::Display for MessageId<M> {134fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {135<Self as fmt::Debug>::fmt(self, f)136}137}138139impl<M: Message> fmt::Debug for MessageId<M> {140fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {141write!(142f,143"message<{}>#{}",144core::any::type_name::<M>().split("::").last().unwrap(),145self.id,146)147}148}149150impl<M: Message> PartialEq for MessageId<M> {151fn eq(&self, other: &Self) -> bool {152self.id == other.id153}154}155156impl<M: Message> Eq for MessageId<M> {}157158impl<M: Message> PartialOrd for MessageId<M> {159fn partial_cmp(&self, other: &Self) -> Option<Ordering> {160Some(self.cmp(other))161}162}163164impl<M: Message> Ord for MessageId<M> {165fn cmp(&self, other: &Self) -> Ordering {166self.id.cmp(&other.id)167}168}169170impl<M: Message> Hash for MessageId<M> {171fn hash<H: Hasher>(&self, state: &mut H) {172Hash::hash(&self.id, state);173}174}175176177