From d4d169d130913348b5adaf519e18ca1c543fcdaa Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 9 Aug 2022 17:24:21 -0700 Subject: [PATCH] Use chunk state instead of HashSet --- examples/terrain.rs | 26 ++++++++++++++++---------- src/chunk.rs | 4 ++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/examples/terrain.rs b/examples/terrain.rs index 309ef55..6bb987e 100644 --- a/examples/terrain.rs +++ b/examples/terrain.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::net::SocketAddr; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -53,7 +52,8 @@ const MAX_PLAYERS: usize = 10; #[async_trait] impl Config for Game { - type ChunkState = (); + /// If the chunk should stay loaded at the end of the tick. + type ChunkState = bool; type ClientState = EntityId; type EntityState = (); type PlayerListState = (); @@ -91,8 +91,6 @@ impl Config for Game { fn update(&self, server: &mut Server) { let (world_id, world) = server.worlds.iter_mut().next().unwrap(); - let mut chunks_to_unload = HashSet::<_>::from_iter(world.chunks.iter().map(|t| t.0)); - server.clients.retain(|_, client| { if client.created_this_tick() { if self @@ -155,19 +153,27 @@ impl Config for Game { let p = client.position(); for pos in chunks_in_view_distance(ChunkPos::at(p.x, p.z), dist) { - chunks_to_unload.remove(&pos); - if world.chunks.get(pos).is_none() { - world.chunks.insert(pos, ()); + if let Some(chunk) = world.chunks.get_mut(pos) { + chunk.state = true; + } else { + world.chunks.insert(pos, true); } } true }); - for pos in chunks_to_unload { - world.chunks.remove(pos); - } + // Remove chunks outside the view distance of players. + world.chunks.retain(|_, chunk| { + if chunk.state { + chunk.state = false; + true + } else { + false + } + }); + // Generate chunk data for chunks created this tick. world.chunks.par_iter_mut().for_each(|(pos, chunk)| { if chunk.created_tick() != server.shared.current_tick() { return; diff --git a/src/chunk.rs b/src/chunk.rs index a6f4903..a710367 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -90,6 +90,10 @@ impl Chunks { self.chunks.get_mut(&pos.into()) } + pub fn retain(&mut self, mut f: impl FnMut(ChunkPos, &mut Chunk) -> bool) { + self.chunks.retain(|&pos, chunk| f(pos, chunk)) + } + /// Deletes all chunks. pub fn clear(&mut self) { self.chunks.clear();