From ba7737671edf7fd6f8072800442279cadbd83043 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Sun, 25 May 2025 17:12:05 -0400 Subject: [PATCH] Use `Vec`s for sending data between threads --- .vscode/launch.json | 2 +- src/game/seed.rs | 33 ++++++++++++++++++++++++++++----- src/game/setup.rs | 2 +- src/lib.rs | 2 +- src/net.rs | 24 ++++++++++++++++-------- 5 files changed, 47 insertions(+), 16 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c35f2ae..323b2e1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -30,7 +30,7 @@ "cargo": { "args": ["build"] }, - "args": ["--connect=[::1]:25565"], + "args": ["--port=25566", "--connect=[::1]:25565"], "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", diff --git a/src/game/seed.rs b/src/game/seed.rs index 5fabafa..2b1ff6b 100644 --- a/src/game/seed.rs +++ b/src/game/seed.rs @@ -1,10 +1,13 @@ -use std::hash::{DefaultHasher, Hash, Hasher}; +use std::{ + array::TryFromSliceError, + hash::{DefaultHasher, Hash, Hasher}, +}; use bevy::prelude::*; use rand::random; /// Value with which to initialize the PRNG -#[derive(Clone, Resource)] +#[derive(Resource, Clone, Copy)] pub struct Seed(u64); impl Seed { @@ -26,20 +29,40 @@ impl From for Seed { } impl From for [u8; 8] { - /// Convert to a u8 array for ingestion by random number generator fn from(value: Seed) -> Self { value.0.to_le_bytes() } } +impl From<[u8; 8]> for Seed { + fn from(value: [u8; 8]) -> Self { + u64::from_le_bytes(value).into() + } +} + +impl From for u64 { + fn from(value: Seed) -> Self { + value.0 + } +} + impl From for Seed { fn from(value: u64) -> Self { Seed(value) } } -impl From for u64 { +impl From for Vec { fn from(value: Seed) -> Self { - value.0 + value.0.to_le_bytes().to_vec() + } +} + +impl TryFrom> for Seed { + type Error = TryFromSliceError; + + fn try_from(value: Vec) -> Result { + let bytes: [u8; 8] = value.as_slice().try_into()?; + Ok(bytes.into()) } } diff --git a/src/game/setup.rs b/src/game/setup.rs index 01b987c..14c2d44 100644 --- a/src/game/setup.rs +++ b/src/game/setup.rs @@ -35,7 +35,7 @@ pub struct PlayableArea(f32, f32); /// Initialize deterministic values pub fn setup_from_seed(mut commands: Commands, seed: Res) { - let mut rng = WyRand::from_seed(seed.clone().into()); + let mut rng = WyRand::from_seed((*seed).into()); commands.insert_resource(PlayableArea( rng.random_range(DIMENSION_SIZES), rng.random_range(DIMENSION_SIZES), diff --git a/src/lib.rs b/src/lib.rs index cb4d69c..b6783f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,7 +90,7 @@ impl Plugin for AppSettings { ); if let Some(ref seed) = self.source.seed { - app.insert_resource(seed.clone()); + app.insert_resource(*seed); } else if let Some(ref peer) = self.source.connect { info!("Will retrieve seed from peer => {peer}"); } else { diff --git a/src/net.rs b/src/net.rs index 3b1b227..71a48a5 100644 --- a/src/net.rs +++ b/src/net.rs @@ -14,7 +14,7 @@ fn configure_socket(socket: &UdpSocket) -> io::Result<()> { Ok(()) } -type NetworkMessage = (u64, SocketAddr); +type NetworkMessage = (Vec, SocketAddr); fn start_network_thread( network_loop: fn(M, UdpSocket) -> Result, @@ -34,16 +34,24 @@ fn start_network_thread( fn network_send_loop(messages: Receiver, socket: UdpSocket) -> Result { loop { let (message, address) = messages.recv()?; - socket.send_to(&message.to_le_bytes(), address)?; + debug!("Sending {} bytes to {}", message.len(), address); + let sent = socket.send_to(message.as_slice(), address)?; + if message.len() != sent { + error!( + "Network thread: Tried to send {} bytes but only sent {}", + message.len(), + sent + ); + } } } fn network_receive_loop(messages: Sender, socket: UdpSocket) -> Result { loop { - let mut message = [0u8; 8]; + let mut message = [0u8; 1024]; // 1 KiB seems like it would be enough, TBD though let (len, address) = socket.recv_from(&mut message)?; - info!("Network thread: Received {len} bytes"); - messages.try_send((u64::from_le_bytes(message), address))?; + debug!("Network thread: Received {len} bytes from {address}"); + messages.try_send((message[..len].into(), address))?; } } @@ -73,9 +81,9 @@ fn handle_network_io( return Ok(()); }; if let Some(value) = seed { - send.0.try_send((value.clone().into(), address))?; + send.0.try_send(((*value).into(), address))?; } else { - commands.insert_resource::(message.into()); + commands.insert_resource::(message.try_into()?); } Ok(()) } @@ -108,7 +116,7 @@ impl Plugin for NetIOPlugin { match setup_socket(self.listen) { Ok((send, receive)) => { if let Some(socket) = self.peer { - if let Err(err) = send.try_send((0, socket)) { + if let Err(err) = send.try_send((Vec::new(), socket)) { warn!("Failed to send to peer: {err}"); return; }