use std::collections::HashMap;
use naia_shared::{
BitReader, ChannelKind, ChannelKinds, ChannelMode, LocalEntityAndGlobalEntityConverter,
MessageContainer, MessageKinds, Serde, SerdeErr, Tick,
};
use crate::connection::tick_buffer_receiver_channel::TickBufferReceiverChannel;
pub struct TickBufferReceiver {
channel_receivers: HashMap<ChannelKind, TickBufferReceiverChannel>,
}
impl TickBufferReceiver {
pub fn new(channel_kinds: &ChannelKinds) -> Self {
let mut channel_receivers = HashMap::new();
for (channel_kind, channel_settings) in channel_kinds.channels() {
if let ChannelMode::TickBuffered(settings) = channel_settings.mode {
channel_receivers.insert(
channel_kind,
TickBufferReceiverChannel::new(settings.clone()),
);
}
}
Self { channel_receivers }
}
pub fn read_messages(
&mut self,
channel_kinds: &ChannelKinds,
message_kinds: &MessageKinds,
host_tick: &Tick,
remote_tick: &Tick,
converter: &dyn LocalEntityAndGlobalEntityConverter,
reader: &mut BitReader,
) -> Result<(), SerdeErr> {
loop {
let channel_continue = bool::de(reader)?;
if !channel_continue {
break;
}
let channel_kind = ChannelKind::de(channel_kinds, reader)?;
let channel = self.channel_receivers.get_mut(&channel_kind).unwrap();
channel.read_messages(converter, message_kinds, host_tick, remote_tick, reader)?;
}
Ok(())
}
#[cfg(feature = "test_utils")]
pub fn inject_message(
&mut self,
channel_kind: &ChannelKind,
host_tick: &Tick,
message_tick: &Tick,
message: MessageContainer,
) -> bool {
if let Some(channel) = self.channel_receivers.get_mut(channel_kind) {
channel.inject_message(host_tick, message_tick, message)
} else {
false
}
}
pub fn receive_messages(
&mut self,
host_tick: &Tick,
) -> Vec<(ChannelKind, Vec<MessageContainer>)> {
let mut output = Vec::new();
for (channel_kind, channel) in &mut self.channel_receivers {
let messages = channel.receive_messages(host_tick);
output.push((*channel_kind, messages));
}
output
}
}