use crate::world::sync::ordered_ids::OrderedIds;
use crate::{
world::{
host::host_world_manager::SubCommandId, sync::remote_entity_channel::EntityChannelState,
},
EntityMessage, MessageIndex,
};
pub(crate) struct AuthChannelReceiver {
next_subcommand_id: SubCommandId,
buffered_messages: OrderedIds<EntityMessage<()>>,
incoming_messages: Vec<EntityMessage<()>>,
}
impl AuthChannelReceiver {
pub(crate) fn new() -> Self {
Self {
next_subcommand_id: 0,
buffered_messages: OrderedIds::new(),
incoming_messages: Vec::new(),
}
}
pub(crate) fn set_next_subcommand_id(&mut self, id: SubCommandId) {
self.next_subcommand_id = id;
}
pub(crate) fn drain_messages_into(&mut self, outgoing_messages: &mut Vec<EntityMessage<()>>) {
outgoing_messages.append(&mut self.incoming_messages);
}
pub(crate) fn buffer_pop_front_until_and_including(&mut self, id: MessageIndex) {
self.buffered_messages.pop_front_until_and_including(id);
}
pub(crate) fn receive_message(
&mut self,
entity_state_opt: Option<EntityChannelState>,
id: MessageIndex,
msg: EntityMessage<()>,
) {
self.buffered_messages.push_back(id, msg);
self.process_messages(entity_state_opt);
}
pub(crate) fn process_messages(&mut self, entity_state_opt: Option<EntityChannelState>) {
if let Some(entity_state) = entity_state_opt {
if entity_state != EntityChannelState::Spawned {
return;
}
}
loop {
let Some((_, msg)) = self.buffered_messages.peek_front() else {
break;
};
let Some(subcommand_id) = msg.subcommand_id() else {
panic!("Expected a subcommand ID in the message: {:?}", msg);
};
if subcommand_id != self.next_subcommand_id {
break;
}
self.next_subcommand_id = self.next_subcommand_id.wrapping_add(1);
let (_, msg) = self.buffered_messages.pop_front().unwrap();
self.incoming_messages.push(msg);
}
}
#[cfg(feature = "e2e_debug")]
pub(crate) fn debug_diagnostic(&self) -> (SubCommandId, usize, Option<SubCommandId>, usize) {
let head_sub_id = self
.buffered_messages
.peek_front()
.and_then(|(_, msg)| msg.subcommand_id());
let buffer_len = self.buffered_messages.len();
let incoming_len = self.incoming_messages.len();
(
self.next_subcommand_id,
buffer_len,
head_sub_id,
incoming_len,
)
}
}