diff --git a/src/map.rs b/src/map.rs index 25bf576..944e88a 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,6 +1,7 @@ use crate::View; use crate::{inspector::HideFromInspector, prelude::*}; use bevy::ecs::system::SystemState; +use bevy::ecs::world::CommandQueue; use bevy::tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task}; use bevy_ecs_tilemap::prelude::*; use rand::prelude::*; @@ -16,7 +17,7 @@ pub struct Tilemap; pub struct TileChan(Mutex>); #[derive(Component, Debug)] -pub struct TileInit(Task<()>); +pub struct TileLoaderTask(Task<()>); pub fn init(mut commands: Commands, assets: Res) { // TODO: I'm pretty determined to not have this sieze up the game despite the large number of entities being added. Should work with a "loading" screen and doing this in the background? @@ -71,76 +72,93 @@ pub fn init(mut commands: Commands, assets: Res) { commands .entity(tilemap) - .insert((TileInit(task), TileChan(Mutex::new(rx)))); + .insert((TileLoaderTask(task), TileChan(Mutex::new(rx)))); } const MAX_TILES_TO_LOAD_IN_ONE_UPDATE: usize = 5_000; pub fn tile_loaders( world: &mut World, - params: &mut SystemState<( - Query<(Entity, &mut TileStorage), With>, - Query<&TileChan, With>, - Query<&mut TileInit>, - ResMut>, - )>, + tilemap: QueryState>, + storage: &mut QueryState<&mut TileStorage, With>, + chan: QueryState<&TileChan, With>, + task: QueryState<&mut TileLoaderTask, With>, + params: &mut SystemState>>, ) { - let (mut query, mut chan, mut tasks, mut next_view) = params.get_mut(world); - let mut tiles_done = true; - let (tilemap, mut storage) = query.single_mut(); + // TODO: this state should maybe be converted to a resource or something? + let mut tiles_done = false; + let mut task_done = false; + type AddingTile = (HideFromInspector, TileBundle); + type AddedTile<'a> = (Entity, &'a TilePos); + let mut tiles_to_add: Vec = Vec::with_capacity(MAX_TILES_TO_LOAD_IN_ONE_UPDATE); + let mut added_tiles: Vec = Vec::with_capacity(MAX_TILES_TO_LOAD_IN_ONE_UPDATE); - let mut tasks_iter = tasks.iter_mut().peekable(); - let mut remove_tasks = false; - if tasks_iter.peek().is_none() && tiles_done { - next_view.set(View::InGame) - } else { - for mut task in tasks_iter { - let poll = future::poll_once(&mut task.0); - if block_on(poll).is_some() { - remove_tasks = true; - // task is done, remove it so we don't poll it again - } + // let mut task = task; + + // { + // task_done = true; + // let mut task = task_query.get_single(); + // if let Ok(task) = task { + // let poll = future::poll_once(task.0); + // if block_on(poll).is_some() { + // task_done = true; + // // task is done, remove it so we don't poll it again + // world.entity_mut(tilemap).remove::(); + // } + // } else { + // next_view.set(View::InGame) + // } + + // let (tilemap, mut storage) = entity_query.single_mut(); + // let tiles: Vec = vec![]; + // if let Ok(channel) = channel_query.get_single_mut() { + // let channel = channel.0.lock().unwrap(); + // tiles_done = false; + // let mut counter = 0; + // loop { + // match channel.recv() { + // Ok(tile) => { + // let position = &tile.position; + // let tile = world.spawn((HideFromInspector, tile)).id(); + // storage.set(position, tile); + // counter += 1; + // if counter >= MAX_TILES_TO_LOAD_IN_ONE_UPDATE { + // info!("Finished {}!", counter); + // break; + // } + // } + // Err(_) => { + // world.entity_mut(tilemap).remove::(); + // if counter > 0 { + // info!("Finished {counter}! Probably finishing mapgen soon..."); + // } + // // the channel is likely closed, so let's note that and be done + // tiles_done = true; + // break; + // } + // } + // } + // } + + for tile in tiles_to_add { + added_tiles.push((id, &tile.1.position)); + let id = world.spawn(tile).id(); + } + + // world.spawn_batch( + // tiles + // .into_iter() + // .map(|t| (HideFromInspector, t)) + // .into_iter(), + // ); + + { + let mut storage = storage.single_mut(world); + // storage.set(& + let mut next_view = params.get_mut(world); + if task_done && tiles_done { + next_view.set(View::InGame) } } - - let tile_bundles: Vec = vec![]; - if let Ok(chan) = chan.get_single_mut() { - let chan = chan.0.lock().unwrap(); - tiles_done = false; - let mut counter = 0; - loop { - match chan.recv() { - Ok(ev) => { - let ref_position = &ev.position; - let tile = world.spawn((HideFromInspector, ev)).id(); - storage.set(ref_position, tile); - counter += 1; - if counter >= MAX_TILES_TO_LOAD_IN_ONE_UPDATE { - info!("Finished {}!", counter); - break; - } - } - Err(_) => { - world.entity_mut(tilemap).remove::(); - if counter > 0 { - info!("Finished {counter}! Probably finishing mapgen soon..."); - } - // the channel is likely closed, so let's note that and be done - tiles_done = true; - break; - } - } - } - } - - if remove_tasks { - world.entity_mut(tilemap).remove::(); - } - world.spawn_batch( - tile_bundles - .into_iter() - .map(|t| (HideFromInspector, t)) - .into_iter(), - ); } pub fn exit(mut commands: Commands, q: Query>) {