From 315fb69a32b96d7a14c4f1a28ebd2890f956f03d Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Fri, 2 Aug 2024 23:31:32 -0500 Subject: [PATCH] Can't seem to get an eventwriter in the context of an asynccomputetask -- at least not easily I did find this, though https://github.com/bevyengine/bevy/issues/8983 Which shows a mutex around a reciever - maybe that could work so I can use channels? --- src/main.rs | 2 ++ src/map.rs | 53 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8e86411..2eff81c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use bevy::audio::{AudioPlugin, SpatialScale}; use bevy::window::{PrimaryWindow, WindowMode}; use bevy_ecs_tilemap::TilemapPlugin; use input::Input; +use map::TileLoadEvent; use prelude::*; use statue::SpawnStatueEvent; @@ -92,6 +93,7 @@ fn main() -> AppExit { ); app.add_event::(); + app.add_event::(); app.add_systems( OnEnter(View::LoadingMenu), diff --git a/src/map.rs b/src/map.rs index 1680157..61aff28 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,10 +1,5 @@ -use std::sync::mpsc::{channel, Receiver}; - use crate::{inspector::HideFromInspector, prelude::*}; -use bevy::{ - ecs::{system::SystemState, world::CommandQueue}, - tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task}, -}; +use bevy::tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task}; // use bevy::{ // ecs::world::CommandQueue, // tasks::{AsyncComputeTaskPool, Task}, @@ -17,13 +12,17 @@ use rand_seeder::Seeder; #[derive(Component, Debug)] pub struct Tilemap; -#[derive(Resource, Debug)] -pub struct TileChan(Receiver); - #[derive(Component, Debug)] -pub struct TileInit(Task<()>); +pub struct TileLoader(Task<()>); -pub fn init(mut commands: Commands, assets: Res) { +#[derive(Event)] +pub struct TileLoadEvent(TileBundle); + +pub fn init( + mut commands: Commands, + assets: Res, + mut loads: EventWriter, +) { // 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(); @@ -53,7 +52,6 @@ pub fn init(mut commands: Commands, assets: Res) { let pool = AsyncComputeTaskPool::get(); 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); @@ -62,27 +60,38 @@ pub fn init(mut commands: Commands, assets: Res) { } else { 0 }); - tx.send(TileBundle { + loads.send(TileLoadEvent(TileBundle { position, tilemap_id: TilemapId(tilemap), texture_index, - ..Default::default() - }) - .unwrap(); + ..default() + })); } } - tx + + return (); }); - commands.entity(tilemap).insert(TileInit(task)); + commands.entity(tilemap).insert(TileLoader(task)); } -pub fn tile_loaders(mut commands: Commands, mut tasks: Query<&mut TileInit>) { +pub fn tile_loaders( + mut commands: Commands, + mut storage: Query<&mut TileStorage>, + mut tasks: Query<&mut TileLoader>, + mut loads: EventReader, +) { // TODO: to avoid locking up the universe we only want to handle a certain number per iteration (Update) + let mut storage = storage.single_mut(); + for ev in loads.read() { + let ref_position = &ev.0.position; + let tile = commands.spawn((HideFromInspector, ev.0)).id(); + storage.set(ref_position, tile); + } + 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); + if block_on(future::poll_once(&mut task.0)).is_some() { + // TODO: transition to game? } } }