use std::{collections::HashMap, hash::Hash};
use log::warn;
use crate::{
messages::channels::receivers::indexed_message_reader::IndexedMessageReader,
world::entity::local_entity::RemoteEntity, world::local_world_manager::LocalWorldManager,
BitReader, ComponentKind, ComponentKinds, ComponentUpdate, EntityAction, EntityActionReceiver,
EntityActionType, EntityConverter, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter,
MessageIndex, Protocol, Replicate, Serde, SerdeErr, Tick, UnsignedVariableInteger,
};
pub struct RemoteWorldReader<E: Copy + Eq + Hash + Send + Sync> {
receiver: EntityActionReceiver<RemoteEntity>,
received_components: HashMap<(RemoteEntity, ComponentKind), Box<dyn Replicate>>,
received_updates: Vec<(Tick, E, ComponentUpdate)>,
}
pub struct RemoteWorldEvents<E: Copy + Eq + Hash + Send + Sync> {
pub incoming_actions: Vec<EntityAction<RemoteEntity>>,
pub incoming_components: HashMap<(RemoteEntity, ComponentKind), Box<dyn Replicate>>,
pub incoming_updates: Vec<(Tick, E, ComponentUpdate)>,
}
impl<E: Copy + Eq + Hash + Send + Sync> RemoteWorldReader<E> {
pub fn new() -> Self {
Self {
receiver: EntityActionReceiver::new(),
received_components: HashMap::default(),
received_updates: Vec::new(),
}
}
pub fn take_incoming_events(&mut self) -> RemoteWorldEvents<E> {
RemoteWorldEvents {
incoming_actions: self.receiver.receive_actions(),
incoming_components: std::mem::take(&mut self.received_components),
incoming_updates: std::mem::take(&mut self.received_updates),
}
}
pub fn track_hosts_redundant_remote_entity(
&mut self,
remote_entity: &RemoteEntity,
component_kinds: &Vec<ComponentKind>,
) {
self.receiver
.track_hosts_redundant_remote_entity(remote_entity, component_kinds);
}
pub fn untrack_hosts_redundant_remote_entity(&mut self, remote_entity: &RemoteEntity) {
self.receiver
.untrack_hosts_redundant_remote_entity(remote_entity);
}
fn read_message_index(
reader: &mut BitReader,
last_index_opt: &mut Option<MessageIndex>,
) -> Result<MessageIndex, SerdeErr> {
let current_index = IndexedMessageReader::read_message_index(reader, last_index_opt)?;
*last_index_opt = Some(current_index);
Ok(current_index)
}
pub fn read_world_events(
&mut self,
global_world_manager: &dyn GlobalWorldManagerType<E>,
local_world_manager: &mut LocalWorldManager<E>,
protocol: &Protocol,
tick: &Tick,
reader: &mut BitReader,
) -> Result<(), SerdeErr> {
self.read_updates(local_world_manager, &protocol.component_kinds, tick, reader)?;
self.read_actions(
global_world_manager,
local_world_manager,
&protocol.component_kinds,
reader,
)?;
Ok(())
}
fn read_actions(
&mut self,
global_world_manager: &dyn GlobalWorldManagerType<E>,
local_world_manager: &mut LocalWorldManager<E>,
component_kinds: &ComponentKinds,
reader: &mut BitReader,
) -> Result<(), SerdeErr> {
let mut last_read_id: Option<MessageIndex> = None;
{
let converter = EntityConverter::new(
global_world_manager.to_global_entity_converter(),
local_world_manager,
);
loop {
let action_continue = bool::de(reader)?;
if !action_continue {
break;
}
self.read_action(&converter, component_kinds, reader, &mut last_read_id)?;
}
}
Ok(())
}
fn read_action(
&mut self,
converter: &dyn LocalEntityAndGlobalEntityConverter,
component_kinds: &ComponentKinds,
reader: &mut BitReader,
last_read_id: &mut Option<MessageIndex>,
) -> Result<(), SerdeErr> {
let action_id = Self::read_message_index(reader, last_read_id)?;
let action_type = EntityActionType::de(reader)?;
match action_type {
EntityActionType::SpawnEntity => {
let remote_entity = RemoteEntity::de(reader)?;
let components_num = UnsignedVariableInteger::<3>::de(reader)?.get();
let mut component_kind_list = Vec::new();
for _ in 0..components_num {
let new_component = component_kinds.read(reader, converter)?;
let new_component_kind = new_component.kind();
self.received_components
.insert((remote_entity, new_component_kind), new_component);
component_kind_list.push(new_component_kind);
}
self.receiver.buffer_action(
action_id,
EntityAction::SpawnEntity(remote_entity, component_kind_list),
);
}
EntityActionType::DespawnEntity => {
let remote_entity = RemoteEntity::de(reader)?;
self.receiver
.buffer_action(action_id, EntityAction::DespawnEntity(remote_entity));
}
EntityActionType::InsertComponent => {
let remote_entity = RemoteEntity::de(reader)?;
let new_component = component_kinds.read(reader, converter)?;
let new_component_kind = new_component.kind();
self.receiver.buffer_action(
action_id,
EntityAction::InsertComponent(remote_entity, new_component_kind),
);
self.received_components
.insert((remote_entity, new_component_kind), new_component);
}
EntityActionType::RemoveComponent => {
let remote_entity = RemoteEntity::de(reader)?;
let component_kind = ComponentKind::de(component_kinds, reader)?;
self.receiver.buffer_action(
action_id,
EntityAction::RemoveComponent(remote_entity, component_kind),
);
}
EntityActionType::Noop => {
self.receiver.buffer_action(action_id, EntityAction::Noop);
}
}
Ok(())
}
fn read_updates(
&mut self,
local_world_manager: &LocalWorldManager<E>,
component_kinds: &ComponentKinds,
tick: &Tick,
reader: &mut BitReader,
) -> Result<(), SerdeErr> {
loop {
let update_continue = bool::de(reader)?;
if !update_continue {
break;
}
let remote_entity = RemoteEntity::de(reader)?;
self.read_update(
local_world_manager,
component_kinds,
tick,
reader,
&remote_entity,
)?;
}
Ok(())
}
fn read_update(
&mut self,
local_world_manager: &LocalWorldManager<E>,
component_kinds: &ComponentKinds,
tick: &Tick,
reader: &mut BitReader,
remote_entity: &RemoteEntity,
) -> Result<(), SerdeErr> {
loop {
let component_continue = bool::de(reader)?;
if !component_continue {
break;
}
let component_update = component_kinds.read_create_update(reader)?;
if local_world_manager.has_remote_entity(remote_entity) {
let world_entity = local_world_manager.world_entity_from_remote(remote_entity);
self.received_updates
.push((*tick, world_entity, component_update));
} else {
warn!("read_update(): SKIPPED READ UPDATE!");
}
}
Ok(())
}
}