use std::collections::BTreeSet; use bevy::prelude::{Added, Changed, Commands, MessageWriter, Query}; use crate::prelude::{debug, Entity, ParamSet, Transform}; use crate::shared::ecs::{Part, Temperature}; use crate::shared::net::part::{PartUpdatePacket, PartDto}; use crate::shared::net::staged_transform::LastStagedTransform; use crate::shared::net::{SendTargets, ToClients}; pub fn send_updated_parts( mut set: ParamSet<( // If you need to send more data, don't add it here... Query<(Entity, &Transform), Added>, Query<(Entity, &Transform, &LastStagedTransform), Changed>, Query>, // add it here. Query<(&Part, &Transform, &Temperature, &mut LastStagedTransform)>, )>, mut update_packets_out: MessageWriter>, mut commands: Commands ) { let start = bevy::platform::time::Instant::now(); let mut parts_to_send: BTreeSet = BTreeSet::new(); // Updating the part behavior triggers sprite loading on the client. We don't want to send it every time the Transform changes let mut parts_with_part_change: BTreeSet = BTreeSet::new(); for (new_part, transform) in set.p0().iter() { parts_to_send.insert(new_part); // Always send newly created parts... // ...and add LastStagedTransform... commands.entity(new_part).insert(LastStagedTransform(*transform)); // and put a marker, we need to copy part data across parts_with_part_change.insert(new_part); } for (moved_part, current_transform, maybe_staged_transform) in set.p1().iter() { // have we had a significant transform change? if !maybe_staged_transform.should_update(current_transform) { continue; } // we have, resend parts_to_send.insert(moved_part); } for changed_part in set.p2().iter() { // if part changed, always resend parts_to_send.insert(changed_part); // and put a marker, we need to copy part data across parts_with_part_change.insert(changed_part); } // process all parts to send let mut packet = PartUpdatePacket { updated_parts: vec![] }; for part_to_send in parts_to_send.iter() { let mut q = set.p3(); let Ok(mut part_info) = q.get_mut(*part_to_send) else { continue }; *part_info.3 = LastStagedTransform(*part_info.1); packet.updated_parts.push(PartDto { server_entity: *part_to_send, part: part_info.0.clone(), part_data_changed: parts_with_part_change.contains(part_to_send), transform: *part_info.1, temperature: *part_info.2 }); } update_packets_out.write(ToClients { message: packet, targets: SendTargets::All, }); }