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<Part>>,
Query<(Entity, &Transform, &LastStagedTransform), Changed<Transform>>,
Query<Entity, Changed<Part>>,
// add it here.
Query<(&Part, &Transform, &Temperature, &mut LastStagedTransform)>,
)>,
mut update_packets_out: MessageWriter<ToClients<PartUpdatePacket>>,
mut commands: Commands
) {
let start = bevy::platform::time::Instant::now();
let mut parts_to_send: BTreeSet<Entity> = 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<Entity> = 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,
});
}