mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-12-26 05:38:20 -06:00
wip data
This commit is contained in:
parent
93f3066ee0
commit
264c72aeb0
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,3 +13,5 @@ target/
|
||||||
_src
|
_src
|
||||||
|
|
||||||
_visualizer.json
|
_visualizer.json
|
||||||
|
|
||||||
|
*.kubi
|
||||||
|
|
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -1033,11 +1033,13 @@ dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
"hashbrown 0.14.0",
|
"hashbrown 0.14.0",
|
||||||
"nohash-hasher",
|
"nohash-hasher",
|
||||||
|
"num_enum 0.7.1",
|
||||||
"postcard",
|
"postcard",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_xoshiro",
|
"rand_xoshiro",
|
||||||
"serde",
|
"serde",
|
||||||
"shipyard",
|
"shipyard",
|
||||||
|
"static_assertions",
|
||||||
"strum",
|
"strum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1223,7 +1225,7 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"jni-sys",
|
"jni-sys",
|
||||||
"ndk-sys",
|
"ndk-sys",
|
||||||
"num_enum",
|
"num_enum 0.5.11",
|
||||||
"raw-window-handle 0.5.2",
|
"raw-window-handle 0.5.2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -1371,7 +1373,16 @@ version = "0.5.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
|
checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9"
|
||||||
dependencies = [
|
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]]
|
[[package]]
|
||||||
|
@ -1386,6 +1397,18 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"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]]
|
[[package]]
|
||||||
name = "objc"
|
name = "objc"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
|
|
@ -8,6 +8,7 @@ publish = false
|
||||||
glam = { version = "0.24", features = ["debug-glam-assert", "fast-math", "serde"] }
|
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"] }
|
shipyard = { git = "https://github.com/leudz/shipyard", rev = "0934b426eb9a8", default-features = false, features = ["std"] }
|
||||||
strum = { version = "0.25", features = ["derive"] }
|
strum = { version = "0.25", features = ["derive"] }
|
||||||
|
num_enum = "0.7"
|
||||||
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"
|
bincode = "1.3"
|
||||||
|
@ -17,9 +18,8 @@ rand = { version = "0.8", default_features = false, features = ["std", "min_cons
|
||||||
rand_xoshiro = "0.6"
|
rand_xoshiro = "0.6"
|
||||||
hashbrown = { version = "0.14", features = ["serde"] }
|
hashbrown = { version = "0.14", features = ["serde"] }
|
||||||
nohash-hasher = "0.2"
|
nohash-hasher = "0.2"
|
||||||
|
|
||||||
#bytemuck = { version = "1.14", features = ["derive"] }
|
#bytemuck = { version = "1.14", features = ["derive"] }
|
||||||
#static_assertions = "1.1"
|
static_assertions = "1.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use strum::EnumIter;
|
use strum::EnumIter;
|
||||||
|
use num_enum::TryFromPrimitive;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)]
|
#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -22,7 +23,7 @@ pub enum BlockTexture {
|
||||||
WaterSolid,
|
WaterSolid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter)]
|
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter, TryFromPrimitive)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum Block {
|
pub enum Block {
|
||||||
Air,
|
Air,
|
||||||
|
|
|
@ -2,13 +2,20 @@ use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
mem::size_of,
|
mem::size_of,
|
||||||
io::{Read, Seek, SeekFrom, Write},
|
io::{Read, Seek, SeekFrom, Write},
|
||||||
borrow::Cow
|
borrow::Cow,
|
||||||
|
sync::{Arc, RwLock}
|
||||||
};
|
};
|
||||||
|
use num_enum::TryFromPrimitive;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use glam::IVec2;
|
use glam::IVec3;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use anyhow::Result;
|
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 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)
|
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;
|
const HEADER_MAGIC_IDENTITY: u32 = 1;
|
||||||
|
|
||||||
// #[repr(transparent)]
|
// #[repr(transparent)]
|
||||||
// struct IVec2Hash(IVec2);
|
// struct IVec3Hash(IVec3);
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct WorldSaveDataHeader {
|
pub struct WorldSaveDataHeader {
|
||||||
pub name: Cow<'static, str>,
|
pub name: Cow<'static, str>,
|
||||||
pub seed: u64,
|
pub seed: u64,
|
||||||
sector_count: u32,
|
sector_count: u32,
|
||||||
chunk_map: HashMap<IVec2, u32>,
|
chunk_map: HashMap<IVec3, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WorldSaveDataHeader {
|
impl Default for WorldSaveDataHeader {
|
||||||
|
@ -40,11 +47,14 @@ impl Default for WorldSaveDataHeader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorldSaveFile {
|
#[derive(Unique)]
|
||||||
|
pub struct WorldSaveFile {
|
||||||
pub file: File,
|
pub file: File,
|
||||||
pub header: WorldSaveDataHeader,
|
pub header: WorldSaveDataHeader,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type SharedSaveFile = Arc<RwLock<WorldSaveFile>>;
|
||||||
|
|
||||||
impl WorldSaveFile {
|
impl WorldSaveFile {
|
||||||
pub fn new(file: File) -> Self {
|
pub fn new(file: File) -> Self {
|
||||||
WorldSaveFile {
|
WorldSaveFile {
|
||||||
|
@ -82,13 +92,23 @@ impl WorldSaveFile {
|
||||||
Ok(())
|
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 {
|
fn allocate_sector(&mut self) -> u32 {
|
||||||
let value = self.header.sector_count + 1;
|
let value = self.header.sector_count + 1;
|
||||||
self.header.sector_count += 1;
|
self.header.sector_count += 1;
|
||||||
value
|
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 mut header_modified = false;
|
||||||
let sector = self.header.chunk_map.get(&position).copied().unwrap_or_else(|| {
|
let sector = self.header.chunk_map.get(&position).copied().unwrap_or_else(|| {
|
||||||
header_modified = true;
|
header_modified = true;
|
||||||
|
@ -96,7 +116,8 @@ impl WorldSaveFile {
|
||||||
});
|
});
|
||||||
|
|
||||||
let offset = sector as u64 * SECTOR_SIZE as u64;
|
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) };
|
let data: &[u8; SECTOR_SIZE] = unsafe { std::mem::transmute(data) };
|
||||||
|
|
||||||
self.file.seek(SeekFrom::Start(offset))?;
|
self.file.seek(SeekFrom::Start(offset))?;
|
||||||
|
@ -108,4 +129,41 @@ impl WorldSaveFile {
|
||||||
self.file.sync_data()?;
|
self.file.sync_data()?;
|
||||||
Ok(())
|
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 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::{
|
use crate::{
|
||||||
networking::{GameType, ServerAddress},
|
networking::{GameType, ServerAddress},
|
||||||
state::{GameState, NextState}
|
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(
|
pub fn initialize_from_args(
|
||||||
all_storages: AllStoragesView,
|
all_storages: AllStoragesView,
|
||||||
|
|
|
@ -6,11 +6,9 @@ use shipyard::{
|
||||||
NonSendSync, WorkloadModificator,
|
NonSendSync, WorkloadModificator,
|
||||||
SystemModificator
|
SystemModificator
|
||||||
};
|
};
|
||||||
use glium::{
|
use glium::glutin::{
|
||||||
glutin::{
|
event_loop::{EventLoop, ControlFlow},
|
||||||
event_loop::{EventLoop, ControlFlow},
|
event::{Event, WindowEvent}
|
||||||
event::{Event, WindowEvent}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
use glam::vec3;
|
use glam::vec3;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
Loading…
Reference in a new issue