mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-29 02:08:48 -06:00
block queue works
This commit is contained in:
parent
00f54a2f5f
commit
319cffbb4e
|
@ -1,7 +1,7 @@
|
||||||
use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut};
|
use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut};
|
||||||
use crate::{
|
use crate::{
|
||||||
player::MainPlayer,
|
player::MainPlayer,
|
||||||
world::{raycast::LookingAtBlock, ChunkStorage, block::Block},
|
world::{raycast::LookingAtBlock, ChunkStorage, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}},
|
||||||
input::{Inputs, PrevInputs},
|
input::{Inputs, PrevInputs},
|
||||||
events::{EventComponent, player_actions::PlayerActionEvent},
|
events::{EventComponent, player_actions::PlayerActionEvent},
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@ pub fn block_placement_system(
|
||||||
raycast: View<LookingAtBlock>,
|
raycast: View<LookingAtBlock>,
|
||||||
input: UniqueView<Inputs>,
|
input: UniqueView<Inputs>,
|
||||||
prev_input: UniqueView<PrevInputs>,
|
prev_input: UniqueView<PrevInputs>,
|
||||||
mut world: UniqueViewMut<ChunkStorage>,
|
mut block_event_queue: UniqueViewMut<BlockUpdateQueue>,
|
||||||
mut entities: EntitiesViewMut,
|
mut entities: EntitiesViewMut,
|
||||||
mut events: ViewMut<EventComponent>,
|
mut events: ViewMut<EventComponent>,
|
||||||
mut player_events: ViewMut<PlayerActionEvent>,
|
mut player_events: ViewMut<PlayerActionEvent>,
|
||||||
|
@ -21,21 +21,18 @@ pub fn block_placement_system(
|
||||||
if action_place ^ action_break {
|
if action_place ^ action_break {
|
||||||
//get raycast info
|
//get raycast info
|
||||||
let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return };
|
let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return };
|
||||||
//update block
|
//get coord and block type
|
||||||
let (place_position, place_block) = if action_place {
|
let (place_position, place_block) = if action_place {
|
||||||
let position = (ray.position - ray.direction * 0.5).floor().as_ivec3();
|
let position = (ray.position - ray.direction * 0.5).floor().as_ivec3();
|
||||||
let Some(block) = world.get_block_mut(position) else { return };
|
(position, Block::Dirt)
|
||||||
*block = Block::Dirt;
|
|
||||||
(position, *block)
|
|
||||||
} else {
|
} else {
|
||||||
let Some(block) = world.get_block_mut(ray.block_position) else { return };
|
(ray.block_position, Block::Air)
|
||||||
*block = Block::Air;
|
|
||||||
(ray.block_position, *block)
|
|
||||||
};
|
};
|
||||||
//mark chunk as dirty
|
//queue place
|
||||||
let (chunk_pos, _) = ChunkStorage::to_chunk_coords(place_position);
|
block_event_queue.push(BlockUpdateEvent {
|
||||||
let chunk = world.chunks.get_mut(&chunk_pos).unwrap();
|
position: place_position,
|
||||||
chunk.dirty = true;
|
value: place_block,
|
||||||
|
});
|
||||||
//send event
|
//send event
|
||||||
entities.add_entity(
|
entities.add_entity(
|
||||||
(&mut events, &mut player_events),
|
(&mut events, &mut player_events),
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub(crate) mod control_flow;
|
||||||
use world::{
|
use world::{
|
||||||
init_game_world,
|
init_game_world,
|
||||||
loading::update_loaded_world_around_player,
|
loading::update_loaded_world_around_player,
|
||||||
raycast::update_raycasts
|
raycast::update_raycasts, queue::apply_queued_blocks
|
||||||
};
|
};
|
||||||
use player::spawn_player;
|
use player::spawn_player;
|
||||||
use prefabs::load_prefabs;
|
use prefabs::load_prefabs;
|
||||||
|
@ -84,6 +84,7 @@ fn update() -> Workload {
|
||||||
update_loaded_world_around_player,
|
update_loaded_world_around_player,
|
||||||
update_raycasts,
|
update_raycasts,
|
||||||
block_placement_system,
|
block_placement_system,
|
||||||
|
apply_queued_blocks,
|
||||||
update_cursor_lock_state,
|
update_cursor_lock_state,
|
||||||
compute_cameras,
|
compute_cameras,
|
||||||
exit_on_esc,
|
exit_on_esc,
|
||||||
|
|
|
@ -15,10 +15,10 @@ pub mod neighbors;
|
||||||
pub mod raycast;
|
pub mod raycast;
|
||||||
pub mod queue;
|
pub mod queue;
|
||||||
|
|
||||||
use chunk::{Chunk, ChunkMesh};
|
use block::Block;
|
||||||
|
use chunk::{Chunk, ChunkMesh, CHUNK_SIZE};
|
||||||
use tasks::ChunkTaskManager;
|
use tasks::ChunkTaskManager;
|
||||||
|
use queue::BlockUpdateQueue;
|
||||||
use self::{chunk::CHUNK_SIZE, block::Block};
|
|
||||||
|
|
||||||
//TODO separate world struct for render data
|
//TODO separate world struct for render data
|
||||||
// because this is not send-sync
|
// because this is not send-sync
|
||||||
|
@ -111,4 +111,5 @@ pub fn init_game_world(
|
||||||
storages.add_unique_non_send_sync(ChunkMeshStorage::new());
|
storages.add_unique_non_send_sync(ChunkMeshStorage::new());
|
||||||
storages.add_unique(ChunkStorage::new());
|
storages.add_unique(ChunkStorage::new());
|
||||||
storages.add_unique(ChunkTaskManager::new());
|
storages.add_unique(ChunkTaskManager::new());
|
||||||
|
storages.add_unique(BlockUpdateQueue::new());
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub struct Chunk {
|
||||||
pub mesh_index: Option<usize>,
|
pub mesh_index: Option<usize>,
|
||||||
pub current_state: CurrentChunkState,
|
pub current_state: CurrentChunkState,
|
||||||
pub desired_state: DesiredChunkState,
|
pub desired_state: DesiredChunkState,
|
||||||
pub dirty: bool,
|
pub mesh_dirty: bool,
|
||||||
}
|
}
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
pub fn new(position: IVec3) -> Self {
|
pub fn new(position: IVec3) -> Self {
|
||||||
|
@ -56,7 +56,7 @@ impl Chunk {
|
||||||
mesh_index: None,
|
mesh_index: None,
|
||||||
current_state: Default::default(),
|
current_state: Default::default(),
|
||||||
desired_state: Default::default(),
|
desired_state: Default::default(),
|
||||||
dirty: false,
|
mesh_dirty: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ fn start_required_tasks(
|
||||||
// ===========
|
// ===========
|
||||||
//log::trace!("Started loading chunk {position}");
|
//log::trace!("Started loading chunk {position}");
|
||||||
},
|
},
|
||||||
DesiredChunkState::Rendered if (chunk.current_state == CurrentChunkState::Loaded || chunk.dirty) => {
|
DesiredChunkState::Rendered if (chunk.current_state == CurrentChunkState::Loaded || chunk.mesh_dirty) => {
|
||||||
//get needed data
|
//get needed data
|
||||||
let Some(neighbors) = world.neighbors_all(position) else {
|
let Some(neighbors) = world.neighbors_all(position) else {
|
||||||
continue
|
continue
|
||||||
|
@ -150,12 +150,12 @@ fn start_required_tasks(
|
||||||
task_manager.spawn_task(ChunkTask::GenerateMesh { data, position });
|
task_manager.spawn_task(ChunkTask::GenerateMesh { data, position });
|
||||||
//Update chunk state
|
//Update chunk state
|
||||||
let chunk = world.chunks.get_mut(&position).unwrap();
|
let chunk = world.chunks.get_mut(&position).unwrap();
|
||||||
if chunk.dirty {
|
if chunk.mesh_dirty {
|
||||||
chunk.current_state = CurrentChunkState::RecalculatingMesh;
|
chunk.current_state = CurrentChunkState::RecalculatingMesh;
|
||||||
} else {
|
} else {
|
||||||
chunk.current_state = CurrentChunkState::CalculatingMesh;
|
chunk.current_state = CurrentChunkState::CalculatingMesh;
|
||||||
}
|
}
|
||||||
chunk.dirty = false;
|
chunk.mesh_dirty = false;
|
||||||
// ===========
|
// ===========
|
||||||
//log::trace!("Started generating mesh for chunk {position}");
|
//log::trace!("Started generating mesh for chunk {position}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::collections::VecDeque;
|
|
||||||
use glam::IVec3;
|
use glam::IVec3;
|
||||||
use kubi_shared::blocks::Block;
|
use kubi_shared::blocks::Block;
|
||||||
use shipyard::{UniqueViewMut, Unique};
|
use shipyard::{UniqueViewMut, Unique};
|
||||||
|
@ -13,33 +12,31 @@ pub struct BlockUpdateEvent {
|
||||||
|
|
||||||
#[derive(Unique, Default, Clone)]
|
#[derive(Unique, Default, Clone)]
|
||||||
pub struct BlockUpdateQueue {
|
pub struct BlockUpdateQueue {
|
||||||
queue: VecDeque<BlockUpdateEvent>
|
queue: Vec<BlockUpdateEvent>
|
||||||
}
|
}
|
||||||
impl BlockUpdateQueue {
|
impl BlockUpdateQueue {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
pub fn push(&mut self, event: BlockUpdateEvent) {
|
pub fn push(&mut self, event: BlockUpdateEvent) {
|
||||||
self.queue.push_back(event)
|
self.queue.push(event)
|
||||||
}
|
|
||||||
pub fn pop(&mut self) -> Option<BlockUpdateEvent> {
|
|
||||||
self.queue.pop_front()
|
|
||||||
}
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.queue.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_events(
|
pub fn apply_queued_blocks(
|
||||||
mut queue: UniqueViewMut<BlockUpdateQueue>,
|
mut queue: UniqueViewMut<BlockUpdateQueue>,
|
||||||
mut world: UniqueViewMut<ChunkStorage>
|
mut world: UniqueViewMut<ChunkStorage>
|
||||||
) {
|
) {
|
||||||
while let Some(event) = queue.pop() {
|
queue.queue.retain(|&event| {
|
||||||
if let Some(block) = world.get_block_mut(event.position) {
|
if let Some(block) = world.get_block_mut(event.position) {
|
||||||
|
*block = event.value;
|
||||||
|
//mark chunk as dirty
|
||||||
|
//maybe i need to check for desired/current state here?
|
||||||
let (chunk_pos, _) = ChunkStorage::to_chunk_coords(event.position);
|
let (chunk_pos, _) = ChunkStorage::to_chunk_coords(event.position);
|
||||||
let chunk = world.chunks.get_mut(&chunk_pos).expect("This error should never happen, if it does then something is super fucked up and the whole project needs to be burnt down.");
|
let chunk = world.chunks.get_mut(&chunk_pos).expect("This error should never happen, if it does then something is super fucked up and the whole project needs to be burnt down.");
|
||||||
chunk.dirty = true;
|
chunk.mesh_dirty = true;
|
||||||
}
|
return false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue