mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-23 22:41:30 +11:00
740778ec41
Previously, the chunk data cache was regenerated at the end of each tick every time a block or biome was modified in a chunk. This causes performance problems in situations where chunks are being modified every tick, like the conway example or redstone machines. This changes things so that the chunk data packet is regenerated only when a client actually needs to load the chunk. This isn't perfect because the regeneration cannot happen in parallel, but the benefits outweigh the costs. (The chunk data packet _is_ generated in parallel when the chunk is first created. There is also some parallelism when clients are loading different chunks. The packet cache is guarded by a `Mutex`.) This has revealed that compression is surprisingly slow. This should be investigated later.
58 lines
1.5 KiB
Rust
58 lines
1.5 KiB
Rust
use std::io::Write;
|
|
|
|
use valence_protocol::{write_packet, write_packet_compressed, Encode, Packet};
|
|
|
|
pub trait WritePacket {
|
|
fn write_packet<P>(&mut self, packet: &P) -> anyhow::Result<()>
|
|
where
|
|
P: Encode + Packet + ?Sized;
|
|
|
|
fn write_bytes(&mut self, bytes: &[u8]) -> anyhow::Result<()>;
|
|
}
|
|
|
|
impl<W: WritePacket> WritePacket for &mut W {
|
|
fn write_packet<P>(&mut self, packet: &P) -> anyhow::Result<()>
|
|
where
|
|
P: Encode + Packet + ?Sized,
|
|
{
|
|
(*self).write_packet(packet)
|
|
}
|
|
|
|
fn write_bytes(&mut self, bytes: &[u8]) -> anyhow::Result<()> {
|
|
(*self).write_bytes(bytes)
|
|
}
|
|
}
|
|
|
|
pub struct PacketWriter<'a, W> {
|
|
writer: W,
|
|
threshold: Option<u32>,
|
|
scratch: &'a mut Vec<u8>,
|
|
}
|
|
|
|
impl<'a, W: Write> PacketWriter<'a, W> {
|
|
pub fn new(writer: W, threshold: Option<u32>, scratch: &'a mut Vec<u8>) -> PacketWriter<W> {
|
|
Self {
|
|
writer,
|
|
threshold,
|
|
scratch,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<W: Write> WritePacket for PacketWriter<'_, W> {
|
|
fn write_packet<P>(&mut self, packet: &P) -> anyhow::Result<()>
|
|
where
|
|
P: Encode + Packet + ?Sized,
|
|
{
|
|
if let Some(threshold) = self.threshold {
|
|
write_packet_compressed(&mut self.writer, threshold, self.scratch, packet)
|
|
} else {
|
|
write_packet(&mut self.writer, packet)
|
|
}
|
|
}
|
|
|
|
fn write_bytes(&mut self, bytes: &[u8]) -> anyhow::Result<()> {
|
|
Ok(self.writer.write_all(bytes)?)
|
|
}
|
|
}
|