use std::{collections::HashMap, hash::Hash};
use naia_shared::{
BitReader, ChannelKind, ChannelKinds, ChannelMode, EntityAndGlobalEntityConverter,
EntityAndLocalEntityConverter, EntityConverter, MessageContainer, Protocol, 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<E: Copy + Eq + Hash + Send + Sync>(
&mut self,
protocol: &Protocol,
host_tick: &Tick,
remote_tick: &Tick,
global_world_manager: &dyn EntityAndGlobalEntityConverter<E>,
local_world_manager: &dyn EntityAndLocalEntityConverter<E>,
reader: &mut BitReader,
) -> Result<(), SerdeErr> {
let converter = EntityConverter::new(global_world_manager, local_world_manager);
loop {
let channel_continue = bool::de(reader)?;
if !channel_continue {
break;
}
let channel_kind = ChannelKind::de(&protocol.channel_kinds, reader)?;
let channel = self.channel_receivers.get_mut(&channel_kind).unwrap();
channel.read_messages(
&converter,
&protocol.message_kinds,
host_tick,
remote_tick,
reader,
)?;
}
Ok(())
}
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
}
}