diff --git a/kubi/src/main.rs b/kubi/src/main.rs index cdf9bca..14772f3 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -4,7 +4,7 @@ use shipyard::{ World, Workload, IntoWorkload, UniqueView, UniqueViewMut, - NonSendSync + NonSendSync, WorkloadModificator }; use glium::{ glutin::{ @@ -13,7 +13,6 @@ use glium::{ } }; use glam::vec3; -use state::GameState; use std::time::Instant; mod logging; @@ -38,7 +37,7 @@ pub(crate) mod init; use world::{ init_game_world, - loading::update_loaded_world_around_player, + loading::{update_loaded_world_around_player, switch_to_ingame_if_loaded}, raycast::update_raycasts, queue::apply_queued_blocks }; use player::spawn_player; @@ -65,6 +64,7 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; +use state::{GameState, is_ingame, is_ingame_or_loading, is_loading}; use init::initialize_from_args; fn startup() -> Workload { @@ -84,24 +84,33 @@ fn startup() -> Workload { } fn update() -> Workload { ( - process_inputs, - update_controllers, - generate_move_events, - update_loaded_world_around_player, - update_raycasts, - block_placement_system, - apply_queued_blocks, update_cursor_lock_state, - compute_cameras, + process_inputs, exit_on_esc, + ( + switch_to_ingame_if_loaded, + ).into_workload().run_if(is_loading), + ( + update_loaded_world_around_player, + ).into_workload().run_if(is_ingame_or_loading), + ( + update_controllers, + generate_move_events, + update_raycasts, + block_placement_system, + apply_queued_blocks, + ).into_workload().run_if(is_ingame), + compute_cameras, ).into_workload() } fn render() -> Workload { ( clear_background, - draw_world, - draw_current_chunk_border, - render_selection_box, + ( + draw_world, + draw_current_chunk_border, + render_selection_box, + ).into_sequential_workload().run_if(is_ingame) ).into_sequential_workload() } fn after_frame_end() -> Workload { diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 9319256..1f1297f 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -1,10 +1,27 @@ -use strum::EnumIter; -use shipyard::Unique; +use shipyard::{Unique, UniqueView}; -#[derive(Unique, EnumIter)] +#[derive(Unique, PartialEq, Eq)] #[track(All)] pub enum GameState { Connecting, LoadingWorld, InGame } + +pub fn is_ingame( + state: UniqueView +) -> bool { + *state == GameState::InGame +} + +pub fn is_loading( + state: UniqueView +) -> bool { + matches!(*state, GameState::LoadingWorld) +} + +pub fn is_ingame_or_loading( + state: UniqueView +) -> bool { + matches!(*state, GameState::InGame | GameState::LoadingWorld) +} diff --git a/kubi/src/world/chunk.rs b/kubi/src/world/chunk.rs index 7d3733d..cd8f77e 100644 --- a/kubi/src/world/chunk.rs +++ b/kubi/src/world/chunk.rs @@ -30,6 +30,11 @@ pub enum CurrentChunkState { RecalculatingMesh, Unloading, } +impl CurrentChunkState { + pub fn matches(self, desired: DesiredChunkState) -> bool { + desired.matches(self) + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub enum DesiredChunkState { @@ -39,6 +44,13 @@ pub enum DesiredChunkState { Rendered, ToUnload, } +impl DesiredChunkState { + pub fn matches(self, current: CurrentChunkState) -> bool { + (matches!(self, DesiredChunkState::Nothing) && matches!(current, CurrentChunkState::Nothing)) || + (matches!(self, DesiredChunkState::Loaded) && matches!(current, CurrentChunkState::Loaded)) || + (matches!(self, DesiredChunkState::Rendered) && matches!(current, CurrentChunkState::Rendered)) + } +} pub struct Chunk { pub position: IVec3, diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index a248857..2254009 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -5,7 +5,8 @@ use crate::{ player::MainPlayer, transform::Transform, settings::GameSettings, - rendering::Renderer + rendering::Renderer, + state::GameState }; use super::{ ChunkStorage, ChunkMeshStorage, @@ -168,7 +169,8 @@ fn process_completed_tasks( task_manager: UniqueView, mut world: UniqueViewMut, mut meshes: NonSendSync>, - renderer: NonSendSync> + renderer: NonSendSync>, + state: UniqueView ) { let mut ops: usize = 0; while let Some(res) = task_manager.receive() { @@ -231,8 +233,19 @@ fn process_completed_tasks( ops += 1; } } - if ops >= MAX_CHUNK_OPS { + if (ops >= MAX_CHUNK_OPS) && matches!(*state, GameState::InGame) { break } } } + +pub fn switch_to_ingame_if_loaded( + world: UniqueView, + mut state: UniqueViewMut +) { + if world.chunks.iter().all(|(_, chunk)| { + chunk.desired_state.matches(chunk.current_state) + }) { + *state = GameState::InGame; + } +}