Path: blob/main/crates/bevy_ecs/src/message/message_writer.rs
6849 views
use crate::{1message::{Message, MessageId, Messages, WriteBatchIds},2system::{ResMut, SystemParam},3};45/// Writes [`Message`]s of type `T`.6///7/// # Usage8///9/// `MessageWriter`s are usually declared as a [`SystemParam`].10/// ```11/// # use bevy_ecs::prelude::*;12///13/// #[derive(Message)]14/// pub struct MyMessage; // Custom message type.15/// fn my_system(mut writer: MessageWriter<MyMessage>) {16/// writer.write(MyMessage);17/// }18///19/// # bevy_ecs::system::assert_is_system(my_system);20/// ```21///22/// # Concurrency23///24/// `MessageWriter` param has [`ResMut<Messages<T>>`](Messages) inside. So two systems declaring `MessageWriter<T>` params25/// for the same message type won't be executed concurrently.26///27/// # Untyped messages28///29/// `MessageWriter` can only write messages of one specific type, which must be known at compile-time.30/// This is not a problem most of the time, but you may find a situation where you cannot know31/// ahead of time every kind of message you'll need to write. In this case, you can use the "type-erased message" pattern.32///33/// ```34/// # use bevy_ecs::{prelude::*, message::Messages};35/// # #[derive(Message)]36/// # pub struct MyMessage;37/// fn write_untyped(mut commands: Commands) {38/// // Write a message of a specific type without having to declare that39/// // type as a SystemParam.40/// //41/// // Effectively, we're just moving the type parameter from the /type/ to the /method/,42/// // which allows one to do all kinds of clever things with type erasure, such as sending43/// // custom messages to unknown 3rd party plugins (modding API).44/// //45/// // NOTE: the message won't actually be sent until commands get applied during46/// // apply_deferred.47/// commands.queue(|w: &mut World| {48/// w.write_message(MyMessage);49/// });50/// }51/// ```52/// Note that this is considered *non-idiomatic*, and should only be used when `MessageWriter` will not work.53///54/// [`Observer`]: crate::observer::Observer55#[derive(SystemParam)]56pub struct MessageWriter<'w, E: Message> {57#[system_param(validation_message = "Message not initialized")]58messages: ResMut<'w, Messages<E>>,59}6061impl<'w, E: Message> MessageWriter<'w, E> {62/// Writes an `message`, which can later be read by [`MessageReader`](super::MessageReader)s.63/// This method returns the [ID](`MessageId`) of the written `message`.64///65/// See [`Messages`] for details.66#[doc(alias = "send")]67#[track_caller]68pub fn write(&mut self, message: E) -> MessageId<E> {69self.messages.write(message)70}7172/// Writes a list of `messages` all at once, which can later be read by [`MessageReader`](super::MessageReader)s.73/// This is more efficient than writing each message individually.74/// This method returns the [IDs](`MessageId`) of the written `messages`.75///76/// See [`Messages`] for details.77#[doc(alias = "send_batch")]78#[track_caller]79pub fn write_batch(&mut self, messages: impl IntoIterator<Item = E>) -> WriteBatchIds<E> {80self.messages.write_batch(messages)81}8283/// Writes the default value of the message. Useful when the message is an empty struct.84/// This method returns the [ID](`MessageId`) of the written `message`.85///86/// See [`Messages`] for details.87#[doc(alias = "send_default")]88#[track_caller]89pub fn write_default(&mut self) -> MessageId<E>90where91E: Default,92{93self.messages.write_default()94}95}969798