mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-12-22 03:48:21 -06:00
wip data
This commit is contained in:
parent
e2bec4bf2e
commit
43ca458896
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,3 +13,5 @@ target/
|
|||
_src
|
||||
|
||||
_visualizer.json
|
||||
|
||||
*.kubi
|
||||
|
|
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -1033,11 +1033,13 @@ dependencies = [
|
|||
"glam",
|
||||
"hashbrown 0.14.0",
|
||||
"nohash-hasher",
|
||||
"num_enum 0.7.1",
|
||||
"postcard",
|
||||
"rand",
|
||||
"rand_xoshiro",
|
||||
"serde",
|
||||
"shipyard",
|
||||
"static_assertions",
|
||||
"strum",
|
||||
]
|
||||
|
||||
|
@ -1223,7 +1225,7 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
"jni-sys",
|
||||
"ndk-sys",
|
||||
"num_enum",
|
||||
"num_enum 0.5.11",
|
||||
"raw-window-handle 0.5.2",
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -1371,7 +1373,16 @@ version = "0.5.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
"num_enum_derive 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0"
|
||||
dependencies = [
|
||||
"num_enum_derive 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1386,6 +1397,18 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc"
|
||||
version = "0.2.7"
|
||||
|
|
|
@ -8,6 +8,7 @@ publish = false
|
|||
glam = { version = "0.24", features = ["debug-glam-assert", "fast-math", "serde"] }
|
||||
shipyard = { git = "https://github.com/leudz/shipyard", rev = "0934b426eb9a8", default-features = false, features = ["std"] }
|
||||
strum = { version = "0.25", features = ["derive"] }
|
||||
num_enum = "0.7"
|
||||
postcard = { version = "1.0", features = ["alloc"] }
|
||||
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
|
||||
bincode = "1.3"
|
||||
|
@ -17,9 +18,8 @@ rand = { version = "0.8", default_features = false, features = ["std", "min_cons
|
|||
rand_xoshiro = "0.6"
|
||||
hashbrown = { version = "0.14", features = ["serde"] }
|
||||
nohash-hasher = "0.2"
|
||||
|
||||
#bytemuck = { version = "1.14", features = ["derive"] }
|
||||
#static_assertions = "1.1"
|
||||
static_assertions = "1.1"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use serde::{Serialize, Deserialize};
|
||||
use strum::EnumIter;
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)]
|
||||
#[repr(u8)]
|
||||
|
@ -22,7 +23,7 @@ pub enum BlockTexture {
|
|||
WaterSolid,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter)]
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter, TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub enum Block {
|
||||
Air,
|
||||
|
|
|
@ -2,13 +2,20 @@ use std::{
|
|||
fs::File,
|
||||
mem::size_of,
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
borrow::Cow
|
||||
borrow::Cow,
|
||||
sync::{Arc, RwLock}
|
||||
};
|
||||
use num_enum::TryFromPrimitive;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use glam::IVec2;
|
||||
use glam::IVec3;
|
||||
use hashbrown::HashMap;
|
||||
use anyhow::Result;
|
||||
use crate::{block::Block, chunk::{CHUNK_SIZE, BlockDataRef}};
|
||||
use shipyard::Unique;
|
||||
use static_assertions::const_assert_eq;
|
||||
use crate::{
|
||||
block::Block,
|
||||
chunk::{CHUNK_SIZE, BlockDataRef, BlockData}
|
||||
};
|
||||
|
||||
const SECTOR_SIZE: usize = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * size_of::<Block>();
|
||||
const RESERVED_SIZE: usize = 1048576; //~1mb (16 sectors assuming 32x32x32 world of 1byte blocks)
|
||||
|
@ -20,13 +27,13 @@ const HEADER_MAGIC_STR: [u8; 4] = *b"KUBI";
|
|||
const HEADER_MAGIC_IDENTITY: u32 = 1;
|
||||
|
||||
// #[repr(transparent)]
|
||||
// struct IVec2Hash(IVec2);
|
||||
// struct IVec3Hash(IVec3);
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct WorldSaveDataHeader {
|
||||
pub struct WorldSaveDataHeader {
|
||||
pub name: Cow<'static, str>,
|
||||
pub seed: u64,
|
||||
sector_count: u32,
|
||||
chunk_map: HashMap<IVec2, u32>,
|
||||
chunk_map: HashMap<IVec3, u32>,
|
||||
}
|
||||
|
||||
impl Default for WorldSaveDataHeader {
|
||||
|
@ -40,11 +47,14 @@ impl Default for WorldSaveDataHeader {
|
|||
}
|
||||
}
|
||||
|
||||
struct WorldSaveFile {
|
||||
#[derive(Unique)]
|
||||
pub struct WorldSaveFile {
|
||||
pub file: File,
|
||||
pub header: WorldSaveDataHeader,
|
||||
}
|
||||
|
||||
pub type SharedSaveFile = Arc<RwLock<WorldSaveFile>>;
|
||||
|
||||
impl WorldSaveFile {
|
||||
pub fn new(file: File) -> Self {
|
||||
WorldSaveFile {
|
||||
|
@ -82,13 +92,23 @@ impl WorldSaveFile {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn initialize(&mut self) -> Result<()> {
|
||||
self.write_header()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn load_data(&mut self) -> Result<()> {
|
||||
self.read_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<()> {
|
||||
pub fn save_chunk(&mut self, position: IVec3, data: &BlockDataRef) -> Result<()> {
|
||||
let mut header_modified = false;
|
||||
let sector = self.header.chunk_map.get(&position).copied().unwrap_or_else(|| {
|
||||
header_modified = true;
|
||||
|
@ -96,7 +116,8 @@ impl WorldSaveFile {
|
|||
});
|
||||
|
||||
let offset = sector as u64 * SECTOR_SIZE as u64;
|
||||
//SAFETY: *nuzzles* t-t-twust me pwease OwO
|
||||
|
||||
const_assert_eq!(size_of::<Block>(), 1);
|
||||
let data: &[u8; SECTOR_SIZE] = unsafe { std::mem::transmute(data) };
|
||||
|
||||
self.file.seek(SeekFrom::Start(offset))?;
|
||||
|
@ -108,4 +129,41 @@ impl WorldSaveFile {
|
|||
self.file.sync_data()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///TODO partial chunk commit (No need to write whole 32kb for a single block change!)
|
||||
pub fn chunk_set_block() {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn chunk_exists(&self, position: IVec3) -> bool {
|
||||
self.header.chunk_map.contains_key(&position)
|
||||
}
|
||||
|
||||
pub fn load_chunk(&mut self, position: IVec3) -> Result<Option<BlockData>> {
|
||||
let Some(§or) = self.header.chunk_map.get(&position) else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let mut buffer = Box::new([0u8; CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * size_of::<Block>()]);
|
||||
let offset = sector as u64 * SECTOR_SIZE as u64;
|
||||
|
||||
self.file.seek(SeekFrom::Start(offset))?;
|
||||
self.file.read_exact(&mut buffer[..])?;
|
||||
|
||||
//should be safe under these conditions:
|
||||
//Block is a single byte
|
||||
//All block data bytes are in valid range
|
||||
const_assert_eq!(size_of::<Block>(), 1);
|
||||
for &byte in &buffer[..] {
|
||||
let block = Block::try_from_primitive(byte);
|
||||
match block {
|
||||
//Sanity check, not actually required: (should NEVER happen)
|
||||
Ok(block) => debug_assert_eq!(byte, block as u8),
|
||||
Err(_) => anyhow::bail!("invalid block data"),
|
||||
}
|
||||
}
|
||||
let data: BlockData = unsafe { std::mem::transmute(buffer) };
|
||||
|
||||
Ok(Some(data))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
use shipyard::{AllStoragesView, UniqueViewMut};
|
||||
use std::{env, net::SocketAddr};
|
||||
use std::{env, net::SocketAddr, fs::OpenOptions, path::{Path, PathBuf}, str::FromStr, sync::{Arc, RwLock}};
|
||||
use anyhow::Result;
|
||||
use crate::{
|
||||
networking::{GameType, ServerAddress},
|
||||
state::{GameState, NextState}
|
||||
};
|
||||
use kubi_shared::data::{WorldSaveFile, SharedSaveFile};
|
||||
|
||||
fn open_local_save_file(path: &Path) -> Result<WorldSaveFile> {
|
||||
let mut save_file = WorldSaveFile::new({
|
||||
OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open("world.kbi")?
|
||||
});
|
||||
if save_file.file.metadata().unwrap().len() == 0 {
|
||||
save_file.initialize()?;
|
||||
} else {
|
||||
save_file.load_data()?;
|
||||
}
|
||||
Ok(save_file)
|
||||
}
|
||||
|
||||
pub fn initialize_from_args(
|
||||
all_storages: AllStoragesView,
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
#![allow(clippy::too_many_arguments)] // allowed because systems often need a lot of arguments
|
||||
|
||||
use shipyard::{
|
||||
World, Workload, IntoWorkload,
|
||||
UniqueView, UniqueViewMut,
|
||||
NonSendSync, WorkloadModificator,
|
||||
World, Workload, IntoWorkload,
|
||||
UniqueView, UniqueViewMut,
|
||||
NonSendSync, WorkloadModificator,
|
||||
SystemModificator
|
||||
};
|
||||
use glium::{
|
||||
glutin::{
|
||||
event_loop::{EventLoop, ControlFlow},
|
||||
event::{Event, WindowEvent}
|
||||
}
|
||||
use glium::glutin::{
|
||||
event_loop::{EventLoop, ControlFlow},
|
||||
event::{Event, WindowEvent}
|
||||
};
|
||||
use glam::vec3;
|
||||
use std::time::Instant;
|
||||
|
|
Loading…
Reference in a new issue