WIP exclusive system, but I can't seem to make it work nicely
This commit is contained in:
parent
692fbed157
commit
5d846fdeff
1 changed files with 80 additions and 62 deletions
142
src/map.rs
142
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<Receiver<TileBundle>>);
|
||||
|
||||
#[derive(Component, Debug)]
|
||||
pub struct TileInit(Task<()>);
|
||||
pub struct TileLoaderTask(Task<()>);
|
||||
|
||||
pub fn init(mut commands: Commands, assets: Res<AssetServer>) {
|
||||
// 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<AssetServer>) {
|
|||
|
||||
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<Tilemap>>,
|
||||
Query<&TileChan, With<Tilemap>>,
|
||||
Query<&mut TileInit>,
|
||||
ResMut<NextState<View>>,
|
||||
)>,
|
||||
tilemap: QueryState<Entity, With<Tilemap>>,
|
||||
storage: &mut QueryState<&mut TileStorage, With<Tilemap>>,
|
||||
chan: QueryState<&TileChan, With<Tilemap>>,
|
||||
task: QueryState<&mut TileLoaderTask, With<Tilemap>>,
|
||||
params: &mut SystemState<ResMut<NextState<View>>>,
|
||||
) {
|
||||
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<AddingTile> = Vec::with_capacity(MAX_TILES_TO_LOAD_IN_ONE_UPDATE);
|
||||
let mut added_tiles: Vec<AddedTile> = 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::<TileLoaderTask>();
|
||||
// }
|
||||
// } else {
|
||||
// next_view.set(View::InGame)
|
||||
// }
|
||||
|
||||
// let (tilemap, mut storage) = entity_query.single_mut();
|
||||
// let tiles: Vec<TileBundle> = 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::<TileChan>();
|
||||
// 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<TileBundle> = 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::<TileChan>();
|
||||
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::<TileInit>();
|
||||
}
|
||||
world.spawn_batch(
|
||||
tile_bundles
|
||||
.into_iter()
|
||||
.map(|t| (HideFromInspector, t))
|
||||
.into_iter(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn exit(mut commands: Commands, q: Query<Entity, With<Tilemap>>) {
|
||||
|
|
Loading…
Reference in a new issue