From 155a118bf091f34d8b3668bb925935c0013daa59 Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Sun, 4 Aug 2024 20:26:59 -0500 Subject: [PATCH] Revert "WIP exclusive system, but I can't seem to make it work nicely" This reverts commit 5d846fdefffff6899cdd67ab275c88b17cc796ca. --- src/map.rs | 142 +++++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 80 deletions(-) diff --git a/src/map.rs b/src/map.rs index 944e88a..25bf576 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,7 +1,6 @@ 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::*; @@ -17,7 +16,7 @@ pub struct Tilemap; pub struct TileChan(Mutex>); #[derive(Component, Debug)] -pub struct TileLoaderTask(Task<()>); +pub struct TileInit(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? @@ -72,93 +71,76 @@ pub fn init(mut commands: Commands, assets: Res) { commands .entity(tilemap) - .insert((TileLoaderTask(task), TileChan(Mutex::new(rx)))); + .insert((TileInit(task), TileChan(Mutex::new(rx)))); } const MAX_TILES_TO_LOAD_IN_ONE_UPDATE: usize = 5_000; pub fn tile_loaders( world: &mut World, - tilemap: QueryState>, - storage: &mut QueryState<&mut TileStorage, With>, - chan: QueryState<&TileChan, With>, - task: QueryState<&mut TileLoaderTask, With>, - params: &mut SystemState>>, + params: &mut SystemState<( + Query<(Entity, &mut TileStorage), With>, + Query<&TileChan, With>, + Query<&mut TileInit>, + ResMut>, + )>, ) { - // 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 query, mut chan, mut tasks, mut next_view) = params.get_mut(world); + let mut tiles_done = true; + let (tilemap, mut storage) = query.single_mut(); - // 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 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 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>) {