This commit is contained in:
griffi-gh 2023-01-16 19:45:27 +01:00
parent 25238acd9b
commit 2cc4b6f2e0
7 changed files with 108 additions and 15 deletions

View file

@ -9,3 +9,4 @@ image = { version = "0.24", default_features = false, features = ["png"] }
log = "0.4"
env_logger = "0.10"
strum = { version = "0.24", features = ["derive"] }
glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] }

View file

@ -1,3 +1,11 @@
#[derive(Clone, Debug)]
pub struct GameOptions {
pub render_distance: u8,
}
impl Default for GameOptions {
fn default() -> Self {
Self {
render_distance: 8,
}
}
}

View file

@ -1,13 +1,20 @@
use glam::{Vec2, IVec2};
use std::collections::HashMap;
use crate::game::options::GameOptions;
mod chunk;
use chunk::Chunk;
mod thread;
use chunk::{Chunk, CHUNK_SIZE};
pub struct World {
chunks: HashMap<(i32, i32), Chunk>
pub chunks: HashMap<IVec2, Chunk>
}
impl World {
// pub fn update_loaded_chunks(around: ) {
// }
pub fn update_loaded_chunks(&mut self, around_position: Vec2, game_opt: &GameOptions) {
let render_dist = game_opt.render_distance as i32;
let inside_chunk = (around_position / CHUNK_SIZE as f32).as_ivec2();
todo!()
}
}

View file

@ -1,3 +1,4 @@
use glam::IVec2;
use glium::VertexBuffer;
use crate::game::{
blocks::Block,
@ -8,16 +9,37 @@ pub const CHUNK_SIZE: usize = 16;
pub const CHUNK_HEIGHT: usize = 255;
pub enum ChunkState {
//AwaitsLoading,
//Loaded,
//AwaitsMesh,
//Rendered,
//AwaitsUnload
AwaitsLoading,
Loaded,
AwaitsMesh,
Rendered,
AwaitsUnload
}
pub struct Chunk {
pub coords: (i32, i32),
pub block_data: Option<[[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]>,
pub vertex_buffer: Option<VertexBuffer<ChunkVertex>>,
pub state: ChunkState
pub enum DesiredState {
Unloaded,
Loaded,
Rendered,
}
pub type ChunkData = [[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE];
pub type ChunkMesh = VertexBuffer<ChunkVertex>;
pub struct Chunk {
pub position: IVec2,
pub block_data: Option<ChunkData>,
pub vertex_buffer: Option<ChunkMesh>,
pub state: ChunkState,
pub desired: DesiredState,
}
impl Chunk {
pub fn new(position: IVec2) -> Self {
Self {
position,
block_data: None,
vertex_buffer: None,
state: ChunkState::AwaitsLoading,
desired: DesiredState::Loaded,
}
}
}

47
src/game/world/thread.rs Normal file
View file

@ -0,0 +1,47 @@
use glam::IVec2;
use std::{
thread::{self, JoinHandle},
collections::HashMap,
mem
};
use super::chunk::{ChunkData, Chunk};
mod world_gen;
mod mesh_gen;
struct WorldThreading {
//drain_filter is not stable yet so
//Options are needed here to take ownership,
//None values should never appear here!
pub load_tasks: HashMap<IVec2, Option<JoinHandle<ChunkData>>>,
pub mesh_tasks: HashMap<IVec2, Option<JoinHandle<ChunkData>>>,
}
impl WorldThreading {
pub fn is_done(&self) -> bool {
self.load_tasks.is_empty() &&
self.mesh_tasks.is_empty()
}
pub fn queue_load(&mut self, position: IVec2) {
let handle = thread::spawn(|| {
world_gen::generate_chunk()
});
if self.load_tasks.insert(position, Some(handle)).is_some() {
log::warn!("load: discarded {}, reason: new task started", position);
}
}
pub fn apply_tasks(&mut self, chunks: &mut HashMap<IVec2, Chunk>) {
self.load_tasks.retain(|position, handle| {
if !chunks.contains_key(position) {
log::warn!("load: discarded {}, reason: chunk no longer exists", position);
return false
}
if !handle.as_ref().expect("Something went terribly wrong").is_finished() {
return true
}
let handle = mem::take(handle).unwrap();
let data = handle.join().unwrap();
chunks.get_mut(position).unwrap().block_data = Some(data);
false
});
}
}

View file

View file

@ -0,0 +1,8 @@
use crate::game::{
world::chunk::{ChunkData, CHUNK_SIZE, CHUNK_HEIGHT},
blocks::Block
};
pub fn generate_chunk() -> ChunkData {
[[[Block::Stone; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]
}