use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
use crate::prelude::*;
pub trait CommunicatorSocket {
fn bind<A: ToSocketAddrs>(addr: A) -> Self;
fn with_reliable_unordered_resend_interval(self, interval: Duration) -> Self;
fn with_reliable_ordered_resend_interval(self, interval: Duration) -> Self;
}
pub(crate) trait SocketSendAddr {
fn send(
&self,
socket: &mut UdpCommunicatorSocket,
slice_index: impl std::slice::SliceIndex<[u8], Output = [u8]>,
) -> Result<usize, std::io::Error>;
}
pub(crate) struct UdpCommunicatorSocket {
pub socket: UdpSocket,
pub data_buffer: [u8; MAX_PACKET_LEN],
pub reliable_unordered_resend_interval: Duration,
pub reliable_ordered_resend_interval: Duration,
#[cfg(feature = "debug")]
pub drop_probability: Option<f64>,
#[cfg(feature = "debug")]
pub corruption_probability: Option<f64>,
#[cfg(feature = "debug")]
pub fake_delay: std::ops::Range<u64>,
#[cfg(feature = "debug")]
pub debug_logs: bool,
#[cfg(feature = "debug")]
pub fake_delayed_buffer: Vec<(
Option<SocketAddr>,
[u8; MAX_PACKET_LEN],
usize,
std::time::Instant,
)>,
}
impl CommunicatorSocket for UdpCommunicatorSocket {
fn bind<A: ToSocketAddrs>(addr: A) -> Self {
let socket = UdpSocket::bind(addr).expect("Failed to bind to udp socket");
socket
.set_nonblocking(true)
.expect("Failed to set udp socket to nonblocking mode");
Self {
socket,
data_buffer: [0; MAX_PACKET_LEN],
reliable_unordered_resend_interval: Duration::from_millis(100),
reliable_ordered_resend_interval: Duration::from_millis(100),
#[cfg(feature = "debug")]
drop_probability: None,
#[cfg(feature = "debug")]
corruption_probability: None,
#[cfg(feature = "debug")]
fake_delay: 0..0,
#[cfg(feature = "debug")]
debug_logs: false,
#[cfg(feature = "debug")]
fake_delayed_buffer: vec![],
}
}
fn with_reliable_unordered_resend_interval(mut self, interval: Duration) -> Self {
self.reliable_ordered_resend_interval = interval;
self
}
fn with_reliable_ordered_resend_interval(mut self, interval: Duration) -> Self {
self.reliable_ordered_resend_interval = interval;
self
}
}
impl SocketSendAddr for () {
fn send(
&self,
socket: &mut UdpCommunicatorSocket,
slice_index: impl std::slice::SliceIndex<[u8], Output = [u8]>,
) -> Result<usize, std::io::Error> {
socket.socket.send(&socket.data_buffer[slice_index])
}
}
impl SocketSendAddr for SocketAddr {
fn send(
&self,
socket: &mut UdpCommunicatorSocket,
slice_index: impl std::slice::SliceIndex<[u8], Output = [u8]>,
) -> Result<usize, std::io::Error> {
socket
.socket
.send_to(&socket.data_buffer[slice_index], self)
}
}