Channels won't work _easily_ as the Receiver is not Send
I think I'll try using Bevy's event system
This commit is contained in:
parent
84bceda2a2
commit
5942539ead
|
@ -100,9 +100,8 @@ fn main() -> AppExit {
|
||||||
.add_systems(OnExit(View::MainMenu), main_menu::exit)
|
.add_systems(OnExit(View::MainMenu), main_menu::exit)
|
||||||
.add_systems(
|
.add_systems(
|
||||||
OnEnter(View::LoadingGame),
|
OnEnter(View::LoadingGame),
|
||||||
(player::startup, statue::startup, map::spawn),
|
(player::startup, statue::startup, map::init),
|
||||||
)
|
)
|
||||||
.add_systems(OnEnter(View::InGame), map::finalize)
|
|
||||||
.add_systems(
|
.add_systems(
|
||||||
OnExit(View::InGame),
|
OnExit(View::InGame),
|
||||||
(player::exit, statue::exit, map::exit),
|
(player::exit, statue::exit, map::exit),
|
||||||
|
@ -112,6 +111,7 @@ fn main() -> AppExit {
|
||||||
(
|
(
|
||||||
load_menu.run_if(in_state(View::LoadingMenu)),
|
load_menu.run_if(in_state(View::LoadingMenu)),
|
||||||
load_game.run_if(in_state(View::LoadingGame)),
|
load_game.run_if(in_state(View::LoadingGame)),
|
||||||
|
map::tile_loaders.run_if(in_state(View::LoadingGame)),
|
||||||
input::process_input,
|
input::process_input,
|
||||||
(update,).after(input::process_input),
|
(update,).after(input::process_input),
|
||||||
(
|
(
|
||||||
|
|
121
src/map.rs
121
src/map.rs
|
@ -1,3 +1,5 @@
|
||||||
|
use std::sync::mpsc::{channel, Receiver};
|
||||||
|
|
||||||
use crate::{inspector::HideFromInspector, prelude::*};
|
use crate::{inspector::HideFromInspector, prelude::*};
|
||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::{system::SystemState, world::CommandQueue},
|
ecs::{system::SystemState, world::CommandQueue},
|
||||||
|
@ -15,86 +17,28 @@ use rand_seeder::Seeder;
|
||||||
#[derive(Component, Debug)]
|
#[derive(Component, Debug)]
|
||||||
pub struct Tilemap;
|
pub struct Tilemap;
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Resource, Debug)]
|
||||||
struct MapGenTask(Task<CommandQueue>);
|
pub struct TileChan(Receiver<TileBundle>);
|
||||||
|
|
||||||
#[derive(Resource, Deref, DerefMut)]
|
#[derive(Component, Debug)]
|
||||||
struct TileStorageHandle(TileStorage);
|
pub struct TileInit(Task<()>);
|
||||||
|
|
||||||
pub fn spawn(mut commands: Commands, assets: Res<AssetServer>) {
|
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?
|
// 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?
|
||||||
|
|
||||||
let mut rng: Pcg64 = Seeder::from("default_seed").make_rng();
|
let mut rng: Pcg64 = Seeder::from("default_seed").make_rng();
|
||||||
let size = TilemapSize::new(1024, 1024);
|
let size = TilemapSize::new(1024, 1024);
|
||||||
let tilemap = commands.spawn((Tilemap, Name::new("Tilemap"))).id();
|
|
||||||
commands.insert_resource(TileStorageHandle(TileStorage::empty(size)));
|
|
||||||
let pool = AsyncComputeTaskPool::get();
|
|
||||||
// this task is for generating tilebundles
|
|
||||||
for x in 0..size.x {
|
|
||||||
for y in 0..size.y {
|
|
||||||
let position = TilePos::new(x, y);
|
|
||||||
let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 {
|
|
||||||
rng.gen_range(0..(16 * 8))
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
});
|
|
||||||
let task = pool.spawn(async move {
|
|
||||||
let mut command_queue = CommandQueue::default();
|
|
||||||
command_queue.push(move |world: &mut World| {
|
|
||||||
let mut state = SystemState::<ResMut<TileStorageHandle>>::new(world);
|
|
||||||
let entity = world
|
|
||||||
.spawn((
|
|
||||||
HideFromInspector,
|
|
||||||
TileBundle {
|
|
||||||
position,
|
|
||||||
tilemap_id: TilemapId(tilemap),
|
|
||||||
texture_index,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
))
|
|
||||||
.id();
|
|
||||||
|
|
||||||
let mut storage = state.get_mut(world);
|
|
||||||
storage.set(&position, entity);
|
|
||||||
});
|
|
||||||
command_queue
|
|
||||||
});
|
|
||||||
commands.entity(tilemap).insert(MapGenTask(task));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load(mut commands: Commands, mut tasks: Query<&mut MapGenTask>) {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn finalize(
|
|
||||||
// mut commands: Commands,
|
|
||||||
// mut storage: Res<TileStorageHandle>,
|
|
||||||
// tilemap: Query<Entity, With<Tilemap>>,
|
|
||||||
// assets: Res<AssetServer>,
|
|
||||||
world: &mut World,
|
|
||||||
) {
|
|
||||||
let storage = world.remove_resource::<TileStorageHandle>().unwrap();
|
|
||||||
|
|
||||||
// TODO: dedupe with load
|
|
||||||
let size = TilemapSize::new(1024, 1024);
|
|
||||||
let tile_size = TilemapTileSize::new(16., 16.);
|
let tile_size = TilemapTileSize::new(16., 16.);
|
||||||
let grid_size = TilemapGridSize::new(16., 16.);
|
let grid_size = TilemapGridSize::new(16., 16.);
|
||||||
let map_type = TilemapType::Square;
|
let map_type = TilemapType::Square;
|
||||||
let storage = storage.0;
|
|
||||||
let mut query = world.query_filtered::<Entity, With<Tilemap>>();
|
|
||||||
let tilemap = query.single(world);
|
|
||||||
let assets = world.resource::<AssetServer>();
|
|
||||||
let texture = TilemapTexture::Single(assets.load("img/Tileset Grass.png"));
|
let texture = TilemapTexture::Single(assets.load("img/Tileset Grass.png"));
|
||||||
let mut commands = world.commands();
|
let storage = TileStorage::empty(size);
|
||||||
commands.entity(tilemap).insert(TilemapBundle {
|
|
||||||
|
let tilemap = commands
|
||||||
|
.spawn((
|
||||||
|
Tilemap,
|
||||||
|
Name::new("Tilemap"),
|
||||||
|
TilemapBundle {
|
||||||
grid_size,
|
grid_size,
|
||||||
map_type,
|
map_type,
|
||||||
size,
|
size,
|
||||||
|
@ -103,7 +47,44 @@ pub fn finalize(
|
||||||
tile_size,
|
tile_size,
|
||||||
transform: get_tilemap_center_transform(&size, &grid_size, &map_type, f32::MIN),
|
transform: get_tilemap_center_transform(&size, &grid_size, &map_type, f32::MIN),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
},
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
|
||||||
|
let pool = AsyncComputeTaskPool::get();
|
||||||
|
let task = pool.spawn(async move {
|
||||||
|
let (tx, rx) = channel::<TileBundle>();
|
||||||
|
for x in 0..size.x {
|
||||||
|
for y in 0..size.y {
|
||||||
|
let position = TilePos::new(x, y);
|
||||||
|
let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 {
|
||||||
|
rng.gen_range(0..(16 * 8))
|
||||||
|
} else {
|
||||||
|
0
|
||||||
});
|
});
|
||||||
|
tx.send(TileBundle {
|
||||||
|
position,
|
||||||
|
tilemap_id: TilemapId(tilemap),
|
||||||
|
texture_index,
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tx
|
||||||
|
});
|
||||||
|
|
||||||
|
commands.entity(tilemap).insert(TileInit(task));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tile_loaders(mut commands: Commands, mut tasks: Query<&mut TileInit>) {
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exit(mut commands: Commands, q: Query<Entity, With<Tilemap>>) {
|
pub fn exit(mut commands: Commands, q: Query<Entity, With<Tilemap>>) {
|
||||||
|
|
Loading…
Reference in a new issue