use super::receiver::SceneReceiver;
use crate::network::SceneMessage;
use crate::plugin_manager::systems::LogicSystem;
use crate::plugin_manager::{runner::RunnerState, Plugin};
use crate::plugin_manager::{EventSystem, GuiSystem, InitSystem};
use crate::scene::Scene;
use gloss_hecs::CommandBuffer;
use log::error;
#[allow(clippy::empty_line_after_doc_comments)]
extern "C" fn network_receiver_system(scene: &mut Scene, _runner: &mut RunnerState) {
let mut command_buffer = CommandBuffer::new();
let frames = if let Ok(mut receiver) = scene.get_resource::<&mut SceneReceiver>() {
if !receiver.is_connected() {
match receiver.connect_to_sender() {
Ok(()) => {
log::info!("Successfully reconnected to sender");
}
Err(super::transport::TransportError::NotConnected) => {
}
Err(e) => {
log::debug!("Failed to connect to sender: {e}");
}
}
}
if receiver.is_connected() {
match receiver.receive_pending_frames() {
Ok(frames) => frames,
Err(super::transport::TransportError::ConnectionClosed) => {
log::info!("Connection lost, will attempt to reconnect");
Vec::new()
}
Err(e) => {
error!("Error receiving network frames: {e}");
Vec::new()
}
}
} else {
Vec::new()
}
} else {
Vec::new()
};
for frame in frames {
let individual_frames = frame.to_individual_messages();
for individual_frame in individual_frames {
if let Ok(mut receiver) = scene.get_resource::<&mut SceneReceiver>() {
receiver.process_frame(scene, &mut command_buffer, &individual_frame);
}
scene.world_mut().run_command_buffer(&mut command_buffer);
if let SceneMessage::EntitySpawn { entity_name, .. } = &individual_frame.message {
scene.update_name2entity(entity_name);
}
}
}
}
#[derive(Clone)]
pub struct SceneReceiverPlugin {
pub autorun: bool,
}
impl SceneReceiverPlugin {
pub fn new(autorun: bool) -> Self {
Self { autorun }
}
}
impl Plugin for SceneReceiverPlugin {
fn autorun(&self) -> bool {
self.autorun
}
fn init_system(&self) -> Option<InitSystem> {
None
}
#[allow(clippy::vec_init_then_push)]
fn event_systems(&self) -> Vec<EventSystem> {
Vec::new()
}
fn logic_systems(&self) -> Vec<LogicSystem> {
vec![
LogicSystem::new(network_receiver_system).with_name("network_receive"), ]
}
#[allow(clippy::vec_init_then_push)]
fn gui_systems(&self) -> Vec<GuiSystem> {
Vec::new()
}
}