Factor out ExistenceBitset, remove unneeded resize of region data vector

This commit is contained in:
crumblingstatue 2023-04-14 12:41:03 +02:00
parent 4457dae8c9
commit ff44ee6959
2 changed files with 55 additions and 23 deletions

View file

@ -1,6 +1,9 @@
mod reg_chunk_existence;
use std::{ use std::{
fmt::Debug,
fs::{File, OpenOptions}, fs::{File, OpenOptions},
io::{Read, Seek, SeekFrom, Write}, io::{Seek, SeekFrom, Write},
path::Path, path::Path,
}; };
@ -8,7 +11,9 @@ use egui_inspect::derive::Inspect;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{math::WorldPos, player::Player, worldgen::Worldgen}; use crate::{
math::WorldPos, player::Player, world::reg_chunk_existence::ExistenceBitset, worldgen::Worldgen,
};
pub type ChkPosSc = u16; pub type ChkPosSc = u16;
@ -89,9 +94,9 @@ impl World {
.open(&reg_file_name) .open(&reg_file_name)
.unwrap(); .unwrap();
let mut existence_bitset = if reg_file_exists { let mut existence_bitset = if reg_file_exists {
read_existence_bitset_file(&mut f) ExistenceBitset::read_from_file(&mut f)
} else { } else {
0 ExistenceBitset::EMPTY
}; };
dbg!(existence_bitset); dbg!(existence_bitset);
let _ = dbg!(f.stream_position()); let _ = dbg!(f.stream_position());
@ -105,14 +110,11 @@ impl World {
let (loc_x, loc_y) = pos.local(); let (loc_x, loc_y) = pos.local();
dbg!(loc_x, loc_y); dbg!(loc_x, loc_y);
let loc_idx = loc_idx(loc_y, loc_x); let loc_idx = loc_idx(loc_y, loc_x);
crate::bitmanip::set_nth_bit(&mut existence_bitset, loc_idx as usize, true); crate::bitmanip::set_nth_bit(&mut existence_bitset.0, loc_idx as usize, true);
let byte_idx = loc_byte_idx(loc_idx); let byte_idx = loc_byte_idx(loc_idx);
dbg!(byte_idx); dbg!(byte_idx);
let end_idx = byte_idx + CHUNK_BYTES; let end_idx = byte_idx + CHUNK_BYTES;
dbg!(end_idx); dbg!(end_idx);
if region_tile_data.len() < end_idx + 1 {
region_tile_data.resize(end_idx + 1, 0);
}
for (i, tile) in chk.tiles.iter().enumerate() { for (i, tile) in chk.tiles.iter().enumerate() {
let off = byte_idx + (i * TILE_BYTES); let off = byte_idx + (i * TILE_BYTES);
region_tile_data[off..off + 2].copy_from_slice(&tile.bg.to_le_bytes()); region_tile_data[off..off + 2].copy_from_slice(&tile.bg.to_le_bytes());
@ -120,7 +122,7 @@ impl World {
region_tile_data[off + 4..off + 6].copy_from_slice(&tile.fg.to_le_bytes()); region_tile_data[off + 4..off + 6].copy_from_slice(&tile.fg.to_le_bytes());
} }
f.seek(SeekFrom::Start(0)).unwrap(); f.seek(SeekFrom::Start(0)).unwrap();
f.write_all(&u64::to_le_bytes(existence_bitset)[..]) f.write_all(&u64::to_le_bytes(existence_bitset.0)[..])
.unwrap(); .unwrap();
log::info!( log::info!(
"{:?}", "{:?}",
@ -130,12 +132,6 @@ impl World {
} }
} }
fn read_existence_bitset_file(f: &mut File) -> u64 {
let mut buf = [0; 8];
f.read_exact(&mut buf).unwrap();
u64::from_le_bytes(buf)
}
fn loc_byte_idx_xy(x: u8, y: u8) -> usize { fn loc_byte_idx_xy(x: u8, y: u8) -> usize {
loc_byte_idx(loc_idx(y, x)) loc_byte_idx(loc_idx(y, x))
} }
@ -291,8 +287,12 @@ impl Chunk {
let chunk = if chunk_exists(&reg_filename, chk) { let chunk = if chunk_exists(&reg_filename, chk) {
log::info!("Chunk exists, loading"); log::info!("Chunk exists, loading");
let mut f = File::open(&reg_filename).unwrap(); let mut f = File::open(&reg_filename).unwrap();
log::info!("Existence bitset: {:b}", read_existence_bitset_file(&mut f)); log::info!(
"Existence bitset: {:?}",
ExistenceBitset::read_from_file(&mut f)
);
let decomp_data = zstd::decode_all(f).unwrap(); let decomp_data = zstd::decode_all(f).unwrap();
assert_eq!(decomp_data.len(), REGION_BYTES);
let local_pos = chk.local(); let local_pos = chk.local();
Chunk::load_from_region(&decomp_data, local_pos.0, local_pos.1) Chunk::load_from_region(&decomp_data, local_pos.0, local_pos.1)
} else { } else {
@ -320,19 +320,14 @@ impl Chunk {
} }
} }
fn read_existence_bitset(reg_filename: &str) -> u64 {
let mut f = File::open(reg_filename).unwrap();
read_existence_bitset_file(&mut f)
}
fn chunk_exists(reg_filename: &str, pos: ChunkPos) -> bool { fn chunk_exists(reg_filename: &str, pos: ChunkPos) -> bool {
if !Path::new(&reg_filename).exists() { if !Path::new(&reg_filename).exists() {
return false; return false;
} }
let bitset = read_existence_bitset(reg_filename); let bitset = ExistenceBitset::read_from_fs(reg_filename);
let local = pos.local(); let local = pos.local();
let idx = loc_idx(local.1, local.0); let idx = loc_idx(local.1, local.0);
crate::bitmanip::nth_bit_set(bitset, idx as usize) crate::bitmanip::nth_bit_set(bitset.0, idx as usize)
} }
pub type TileId = u16; pub type TileId = u16;

View file

@ -0,0 +1,37 @@
use std::{fs::File, io::Read};
#[derive(Clone, Copy)]
pub struct ExistenceBitset(pub u64);
impl ExistenceBitset {
pub const EMPTY: Self = Self(0);
pub fn read_from_file(f: &mut File) -> ExistenceBitset {
let mut buf = [0; 8];
f.read_exact(&mut buf).unwrap();
ExistenceBitset(u64::from_le_bytes(buf))
}
pub fn read_from_fs(reg_filename: &str) -> ExistenceBitset {
let mut f = File::open(reg_filename).unwrap();
Self::read_from_file(&mut f)
}
}
impl std::fmt::Debug for ExistenceBitset {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f)?;
for i in 0..64 {
let chr = if crate::bitmanip::nth_bit_set(self.0, i) {
'X'
} else {
'_'
};
write!(f, "{chr}")?;
if (i + 1) % 8 == 0 {
writeln!(f)?;
}
}
Ok(())
}
}