Path: blob/main/crates/bevy_ecs/src/message/message_cursor.rs
6849 views
use crate::message::{1Message, MessageIterator, MessageIteratorWithId, MessageMutIterator, MessageMutIteratorWithId,2Messages,3};4#[cfg(feature = "multi_threaded")]5use crate::message::{MessageMutParIter, MessageParIter};6use core::marker::PhantomData;78/// Stores the state for a [`MessageReader`] or [`MessageMutator`].9///10/// Access to the [`Messages<E>`] resource is required to read any incoming messages.11///12/// In almost all cases, you should just use a [`MessageReader`] or [`MessageMutator`],13/// which will automatically manage the state for you.14///15/// However, this type can be useful if you need to manually track messages,16/// such as when you're attempting to send and receive messages of the same type in the same system.17///18/// # Example19///20/// ```21/// use bevy_ecs::prelude::*;22/// use bevy_ecs::message::{Message, MessageCursor};23///24/// #[derive(Message, Clone, Debug)]25/// struct MyMessage;26///27/// /// A system that both sends and receives messages using a [`Local`] [`MessageCursor`].28/// fn send_and_receive_messages(29/// // The `Local` `SystemParam` stores state inside the system itself, rather than in the world.30/// // `MessageCursor<T>` is the internal state of `MessageMutator<T>`, which tracks which messages have been seen.31/// mut local_message_reader: Local<MessageCursor<MyMessage>>,32/// // We can access the `Messages` resource mutably, allowing us to both read and write its contents.33/// mut messages: ResMut<Messages<MyMessage>>,34/// ) {35/// // We must collect the messages to resend, because we can't mutate messages while we're iterating over the messages.36/// let mut messages_to_resend = Vec::new();37///38/// for message in local_message_reader.read(&mut messages) {39/// messages_to_resend.push(message.clone());40/// }41///42/// for message in messages_to_resend {43/// messages.write(MyMessage);44/// }45/// }46///47/// # bevy_ecs::system::assert_is_system(send_and_receive_messages);48/// ```49///50/// [`MessageReader`]: super::MessageReader51/// [`MessageMutator`]: super::MessageMutator52#[derive(Debug)]53pub struct MessageCursor<E: Message> {54pub(super) last_message_count: usize,55pub(super) _marker: PhantomData<E>,56}5758impl<E: Message> Default for MessageCursor<E> {59fn default() -> Self {60MessageCursor {61last_message_count: 0,62_marker: Default::default(),63}64}65}6667impl<E: Message> Clone for MessageCursor<E> {68fn clone(&self) -> Self {69MessageCursor {70last_message_count: self.last_message_count,71_marker: PhantomData,72}73}74}7576impl<E: Message> MessageCursor<E> {77/// See [`MessageReader::read`](super::MessageReader::read)78pub fn read<'a>(&'a mut self, messages: &'a Messages<E>) -> MessageIterator<'a, E> {79self.read_with_id(messages).without_id()80}8182/// See [`MessageMutator::read`](super::MessageMutator::read)83pub fn read_mut<'a>(&'a mut self, messages: &'a mut Messages<E>) -> MessageMutIterator<'a, E> {84self.read_mut_with_id(messages).without_id()85}8687/// See [`MessageReader::read_with_id`](super::MessageReader::read_with_id)88pub fn read_with_id<'a>(89&'a mut self,90messages: &'a Messages<E>,91) -> MessageIteratorWithId<'a, E> {92MessageIteratorWithId::new(self, messages)93}9495/// See [`MessageMutator::read_with_id`](super::MessageMutator::read_with_id)96pub fn read_mut_with_id<'a>(97&'a mut self,98messages: &'a mut Messages<E>,99) -> MessageMutIteratorWithId<'a, E> {100MessageMutIteratorWithId::new(self, messages)101}102103/// See [`MessageReader::par_read`](super::MessageReader::par_read)104#[cfg(feature = "multi_threaded")]105pub fn par_read<'a>(&'a mut self, messages: &'a Messages<E>) -> MessageParIter<'a, E> {106MessageParIter::new(self, messages)107}108109/// See [`MessageMutator::par_read`](super::MessageMutator::par_read)110#[cfg(feature = "multi_threaded")]111pub fn par_read_mut<'a>(112&'a mut self,113messages: &'a mut Messages<E>,114) -> MessageMutParIter<'a, E> {115MessageMutParIter::new(self, messages)116}117118/// See [`MessageReader::len`](super::MessageReader::len)119pub fn len(&self, messages: &Messages<E>) -> usize {120// The number of messages in this reader is the difference between the most recent message121// and the last message seen by it. This will be at most the number of messages contained122// with the messages (any others have already been dropped)123// TODO: Warn when there are dropped messages, or return e.g. a `Result<usize, (usize, usize)>`124messages125.message_count126.saturating_sub(self.last_message_count)127.min(messages.len())128}129130/// Amount of messages we missed.131pub fn missed_messages(&self, messages: &Messages<E>) -> usize {132messages133.oldest_message_count()134.saturating_sub(self.last_message_count)135}136137/// See [`MessageReader::is_empty()`](super::MessageReader::is_empty)138pub fn is_empty(&self, messages: &Messages<E>) -> bool {139self.len(messages) == 0140}141142/// See [`MessageReader::clear()`](super::MessageReader::clear)143pub fn clear(&mut self, messages: &Messages<E>) {144self.last_message_count = messages.message_count;145}146}147148149