diff --git a/Cargo.toml b/Cargo.toml index 5726c47..dbcd701 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -bevy = { version = "0.14.0", default-features = false, features = [ +bevy = { version = "0.14.0", default_features = false, features = [ "bevy_asset", "bevy_audio", "bevy_color", diff --git a/src/main.rs b/src/main.rs index 8e86411..a9ba240 100644 --- a/src/main.rs +++ b/src/main.rs @@ -145,7 +145,7 @@ fn load_menu(mut app_state: ResMut>) { fn load_game(mut app_state: ResMut>) { // need to check if the map is fully loaded before switching - app_state.set(View::InGame); + // app_state.set(View::InGame); } fn startup(mut commands: Commands) { diff --git a/src/map.rs b/src/map.rs index 1680157..9f8942f 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,24 +1,18 @@ -use std::sync::mpsc::{channel, Receiver}; - +use crate::View; use crate::{inspector::HideFromInspector, prelude::*}; -use bevy::{ - ecs::{system::SystemState, world::CommandQueue}, - tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task}, -}; -// use bevy::{ -// ecs::world::CommandQueue, -// tasks::{AsyncComputeTaskPool, Task}, -// }; +use bevy::tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task}; use bevy_ecs_tilemap::prelude::*; use rand::prelude::*; use rand_pcg::Pcg64; use rand_seeder::Seeder; +use std::sync::mpsc::{channel, Receiver}; +use std::sync::Mutex; #[derive(Component, Debug)] pub struct Tilemap; -#[derive(Resource, Debug)] -pub struct TileChan(Receiver); +#[derive(Component, Debug)] +pub struct TileChan(Mutex>); #[derive(Component, Debug)] pub struct TileInit(Task<()>); @@ -52,8 +46,8 @@ pub fn init(mut commands: Commands, assets: Res) { .id(); let pool = AsyncComputeTaskPool::get(); + let (tx, rx) = channel::(); let task = pool.spawn(async move { - let (tx, rx) = channel::(); for x in 0..size.x { for y in 0..size.y { let position = TilePos::new(x, y); @@ -71,20 +65,60 @@ pub fn init(mut commands: Commands, assets: Res) { .unwrap(); } } - tx + return (); }); - commands.entity(tilemap).insert(TileInit(task)); + commands + .entity(tilemap) + .insert((TileInit(task), TileChan(Mutex::new(rx)))); } -pub fn tile_loaders(mut commands: Commands, mut tasks: Query<&mut TileInit>) { +pub fn tile_loaders( + mut commands: Commands, + mut query: Query<(Entity, &mut TileStorage, &TileChan), With>, + mut tasks: Query<&mut TileInit>, + mut app_state: ResMut>, +) { // TODO: to avoid locking up the universe we only want to handle a certain number per iteration (Update) - for mut task in &mut tasks { - if let Some(mut commands_queue) = block_on(future::poll_once(&mut task.0)) { - // append the returned command queue to have it execute later - commands.append(&mut commands_queue); + let (tilemap, mut storage, chan) = query.single_mut(); + let chan = chan.0.lock().unwrap(); + let mut counter = 0; + let mut tiles_done = false; + loop { + match chan.recv() { + Ok(ev) => { + let ref_position = &ev.position; + let tile = commands.spawn((HideFromInspector, ev)).id(); + storage.set(ref_position, tile); + counter += 1; + if counter > 5_000 { + info!("Finished 100k!"); + break; + } + } + Err(err) => { + error!("{err:#?}"); + tiles_done = true; + break; + } } } + + info!("Task: {tasks:#?}"); + for mut task in &mut tasks { + let poll = future::poll_once(&mut task.0); + info!("Poll: {poll:#?}"); + if block_on(poll).is_some() { + commands.entity(tilemap).remove::(); + // need to check if the map is fully loaded before switching + // app_state.set(View::InGame); + // TODO: transition to game? + info!("poll was some"); + } + } + if tasks.iter().peekable().peek().is_none() && tiles_done { + app_state.set(View::InGame); + } } pub fn exit(mut commands: Commands, q: Query>) {