use {
crate::{IoSystems, Session},
bevy_app::prelude::*,
bevy_ecs::prelude::*,
bevy_platform::time::Instant,
bevy_reflect::prelude::*,
bytes::Bytes,
core::{num::Saturating, time::Duration},
derive_more::{Add, AddAssign, Deref, Display, Error, Sub, SubAssign},
log::warn,
};
pub(crate) struct PacketPlugin;
impl Plugin for PacketPlugin {
fn build(&self, app: &mut App) {
app.register_type::<PacketRtt>()
.register_type::<PacketStats>()
.add_systems(
PreUpdate,
clear_recv_buffers
.before(IoSystems::Poll)
.run_if(not(resource_exists::<NoClearBuffers>)),
)
.add_systems(
PostUpdate,
clear_send_buffers
.after(IoSystems::Flush)
.run_if(not(resource_exists::<NoClearBuffers>)),
);
}
}
#[derive(Debug, Clone)]
pub struct RecvPacket {
pub recv_at: Instant,
pub payload: Bytes,
}
pub const IP_MTU: usize = 1024;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)]
#[display("packet MTU too small - {mtu} / {min}")]
pub struct MtuTooSmall {
pub mtu: usize,
pub min: usize,
}
#[derive(Debug, Clone, Copy, Default, Reflect)] #[derive(Add, AddAssign, Sub, SubAssign)]
pub struct PacketStats {
pub packets_recv: Saturating<usize>,
pub packets_sent: Saturating<usize>,
pub bytes_recv: Saturating<usize>,
pub bytes_sent: Saturating<usize>,
}
#[derive(Debug, Clone, Copy, Deref, Component, Reflect)]
#[reflect(Component)]
#[doc(alias = "ping", alias = "latency")]
pub struct PacketRtt(pub Duration);
#[derive(Debug, Clone, Copy, Default, Resource, Reflect)]
#[reflect(Resource)]
pub struct NoClearBuffers;
pub fn clear_recv_buffers(mut sessions: Query<(Entity, &mut Session)>) {
for (entity, mut session) in &mut sessions {
let len = session.recv.len();
if len > 0 {
warn!(
"{entity} has {len} received packets which have not been consumed - this \
indicates a bug in code above the IO layer"
);
session.recv.clear();
}
}
}
pub fn clear_send_buffers(mut sessions: Query<(Entity, &mut Session)>) {
for (entity, mut session) in &mut sessions {
let len = session.send.len();
if len > 0 {
warn!(
"{entity} has {len} sent packets which have not been consumed - this indicates a \
bug in the IO layer"
);
session.send.clear();
}
}
}