This commit is contained in:
griffi-gh 2023-11-19 18:27:20 +01:00
parent 5494dc61ed
commit 63f27cbb71
5 changed files with 111 additions and 3 deletions

15
Cargo.lock generated
View file

@ -120,6 +120,15 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -170,9 +179,9 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.13.1" version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
@ -826,6 +835,7 @@ checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
dependencies = [ dependencies = [
"ahash 0.8.3", "ahash 0.8.3",
"allocator-api2", "allocator-api2",
"serde",
] ]
[[package]] [[package]]
@ -1015,6 +1025,7 @@ name = "kubi-shared"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bincode",
"bracket-noise", "bracket-noise",
"glam", "glam",
"hashbrown 0.14.0", "hashbrown 0.14.0",

View file

@ -10,13 +10,17 @@ shipyard = { git = "https://github.com/leudz/shipyard", rev = "0934b426eb9a8", d
strum = { version = "0.25", features = ["derive"] } strum = { version = "0.25", features = ["derive"] }
postcard = { version = "1.0", features = ["alloc"] } postcard = { version = "1.0", features = ["alloc"] }
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
bincode = "1.3"
anyhow = "1.0" anyhow = "1.0"
bracket-noise = "0.8" bracket-noise = "0.8"
rand = { version = "0.8", default_features = false, features = ["std", "min_const_gen"] } rand = { version = "0.8", default_features = false, features = ["std", "min_const_gen"] }
rand_xoshiro = "0.6" rand_xoshiro = "0.6"
hashbrown = "0.14" hashbrown = { version = "0.14", features = ["serde"] }
nohash-hasher = "0.2" nohash-hasher = "0.2"
#bytemuck = { version = "1.14", features = ["derive"] }
#static_assertions = "1.1"
[features] [features]
default = [] default = []
nightly = ["hashbrown/nightly", "rand/nightly", "rand/simd_support", "glam/core-simd"] nightly = ["hashbrown/nightly", "rand/nightly", "rand/simd_support", "glam/core-simd"]

View file

@ -2,3 +2,4 @@ use crate::block::Block;
pub const CHUNK_SIZE: usize = 32; pub const CHUNK_SIZE: usize = 32;
pub type BlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>; pub type BlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>;
pub type BlockDataRef = [[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE];

91
kubi-shared/src/data.rs Normal file
View file

@ -0,0 +1,91 @@
use std::{
fs::File,
mem::size_of,
io::{Read, Seek, SeekFrom, Write},
borrow::Cow
};
use serde::{Serialize, Deserialize};
use glam::IVec2;
use hashbrown::HashMap;
use anyhow::Result;
use crate::{block::Block, chunk::{CHUNK_SIZE, BlockDataRef}};
const SECTOR_SIZE: usize = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * size_of::<Block>();
const RESERVED_SIZE: usize = 524288; //512kb (16 sectors assuming 32x32x32 world of 1byte blocks)
const RESERVED_SECTOR_COUNT: usize = RESERVED_SIZE / SECTOR_SIZE;
// #[repr(transparent)]
// struct IVec2Hash(IVec2);
#[derive(Serialize, Deserialize)]
struct WorldSaveDataHeader {
pub name: Cow<'static, str>,
pub seed: u64,
sector_count: u32,
chunk_map: HashMap<IVec2, u32>
}
impl Default for WorldSaveDataHeader {
fn default() -> Self {
Self {
name: "World".into(),
seed: 0,
sector_count: RESERVED_SECTOR_COUNT as u32,
chunk_map: HashMap::new()
}
}
}
struct WorldSaveFile {
pub file: File,
pub header: WorldSaveDataHeader,
}
impl WorldSaveFile {
pub fn new(file: File) -> Self {
WorldSaveFile {
file,
header: WorldSaveDataHeader::default()
}
}
fn read_header(&mut self) -> Result<()> {
self.file.rewind()?;
self.header = bincode::deserialize_from((&self.file).take(RESERVED_SIZE as u64))?;
Ok(())
}
fn write_header(&mut self) -> Result<()> {
self.file.rewind()?;
///XXX: this can cause the header to destroy chunk data (if it's WAY too long)
bincode::serialize_into(&self.file, &self.header)?;
Ok(())
}
fn allocate_sector(&mut self) -> u32 {
let value = self.header.sector_count + 1;
self.header.sector_count += 1;
value
}
pub fn save_chunk(&mut self, position: IVec2, data: &BlockDataRef) -> Result<()> {
let mut header_modified = false;
let sector = self.header.chunk_map.get(&position).copied().unwrap_or_else(|| {
header_modified = true;
self.allocate_sector()
});
let offset = sector as u64 * SECTOR_SIZE as u64;
//SAFETY: *nuzzles* t-t-twust me pwease OwO
let data: &[u8; SECTOR_SIZE] = unsafe { std::mem::transmute(data) };
self.file.seek(SeekFrom::Start(offset))?;
self.file.write_all(data)?;
if header_modified {
self.write_header()?;
}
self.file.sync_data()?;
Ok(())
}
}

View file

@ -6,3 +6,4 @@ pub mod transform;
pub mod entity; pub mod entity;
pub mod player; pub mod player;
pub mod queue; pub mod queue;
pub mod data;