mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
fix(chunk): resend replaced chunk data at same position (#1544)
* fix(chunk): resend replaced chunk data at same position * fix(clippy): simplify chunk resend dedupe check * fix(chunk): dedupe by weak chunk identity
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
use core::f32;
|
||||
use std::collections::{BinaryHeap, HashSet, VecDeque};
|
||||
use std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};
|
||||
use std::f64::consts::TAU;
|
||||
use std::mem;
|
||||
use std::num::NonZeroU8;
|
||||
use std::ops::AddAssign;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, AtomicI32, AtomicI64, AtomicU8, AtomicU32, Ordering};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use arc_swap::ArcSwap;
|
||||
@@ -136,7 +136,7 @@ pub struct ChunkManager {
|
||||
center: Vector2<i32>,
|
||||
view_distance: u8,
|
||||
chunk_listener: Receiver<(Vector2<i32>, SyncChunk)>,
|
||||
chunk_sent: HashSet<Vector2<i32>>,
|
||||
chunk_sent: HashMap<Vector2<i32>, Weak<ChunkData>>,
|
||||
chunk_queue: BinaryHeap<HeapNode>,
|
||||
entity_chunk_queue: VecDeque<(Vector2<i32>, SyncEntityChunk)>,
|
||||
batches_sent_since_ack: BatchState,
|
||||
@@ -158,7 +158,7 @@ impl ChunkManager {
|
||||
center: Vector2::<i32>::new(0, 0),
|
||||
view_distance: 0,
|
||||
chunk_listener,
|
||||
chunk_sent: HashSet::new(),
|
||||
chunk_sent: HashMap::new(),
|
||||
chunk_queue: BinaryHeap::new(),
|
||||
entity_chunk_queue: VecDeque::new(),
|
||||
batches_sent_since_ack: BatchState::Initial,
|
||||
@@ -172,6 +172,13 @@ impl ChunkManager {
|
||||
&self.world
|
||||
}
|
||||
|
||||
fn should_enqueue_chunk(&mut self, position: Vector2<i32>, chunk: &SyncChunk) -> bool {
|
||||
self.chunk_sent
|
||||
.insert(position, Arc::downgrade(chunk))
|
||||
.and_then(|old_chunk| old_chunk.upgrade())
|
||||
.is_none_or(|old_chunk| !Arc::ptr_eq(&old_chunk, chunk))
|
||||
}
|
||||
|
||||
pub fn pull_new_chunks(&mut self) {
|
||||
// log::debug!("pull new chunks");
|
||||
while let Ok((pos, chunk)) = self.chunk_listener.try_recv() {
|
||||
@@ -181,7 +188,7 @@ impl ChunkManager {
|
||||
if dst > i32::from(self.view_distance) {
|
||||
continue;
|
||||
}
|
||||
if self.chunk_sent.insert(pos) {
|
||||
if self.should_enqueue_chunk(pos, &chunk) {
|
||||
// log::debug!("receive new chunk {pos:?}");
|
||||
self.chunk_queue.push(HeapNode(dst, pos, chunk));
|
||||
}
|
||||
@@ -222,7 +229,7 @@ impl ChunkManager {
|
||||
let view_distance_i32 = i32::from(view_distance);
|
||||
let unloading_chunks: HashSet<Vector2<i32>> = unloading_chunks.iter().copied().collect();
|
||||
|
||||
self.chunk_sent.retain(|pos| {
|
||||
self.chunk_sent.retain(|pos, _| {
|
||||
(pos.x - center.x).abs().max((pos.y - center.y).abs()) <= view_distance_i32
|
||||
&& !unloading_chunks.contains(pos)
|
||||
});
|
||||
@@ -237,7 +244,7 @@ impl ChunkManager {
|
||||
self.chunk_queue = new_queue;
|
||||
|
||||
for pos in loading_chunks {
|
||||
if !self.chunk_sent.contains(pos)
|
||||
if !self.chunk_sent.contains_key(pos)
|
||||
&& let Some(chunk) = level.loaded_chunks.get(pos)
|
||||
{
|
||||
self.push_chunk(*pos, chunk.value().clone());
|
||||
@@ -283,11 +290,12 @@ impl ChunkManager {
|
||||
}
|
||||
|
||||
pub fn push_chunk(&mut self, position: Vector2<i32>, chunk: SyncChunk) {
|
||||
self.chunk_sent.insert(position);
|
||||
let dst = (position.x - self.center.x)
|
||||
.abs()
|
||||
.max((position.y - self.center.y).abs());
|
||||
self.chunk_queue.push(HeapNode(dst, position, chunk));
|
||||
if self.should_enqueue_chunk(position, &chunk) {
|
||||
let dst = (position.x - self.center.x)
|
||||
.abs()
|
||||
.max((position.y - self.center.y).abs());
|
||||
self.chunk_queue.push(HeapNode(dst, position, chunk));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_entity(&mut self, position: Vector2<i32>, chunk: SyncEntityChunk) {
|
||||
|
||||
Reference in New Issue
Block a user