diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 863c7dd..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,3 +0,0 @@ -[target.x86_64-unknown-linux-gnu] -linker = "clang" -rustflags = ["-C", "link-arg=-fuse-ld=/nix/store/46n1qljc0drdz4r2k9smxxb8kl79di25-mold-2.32.1/bin/mold"] diff --git a/flake.nix b/flake.nix index 6edd8f6..41aeb9e 100644 --- a/flake.nix +++ b/flake.nix @@ -108,18 +108,20 @@ nativeBuildInputs = buildTimeDeps pkgs; buildInputs = linkTimeDeps pkgs; - # hash = pkgs.lib.fakeHash; - - # a hack to avoid using mold as our linker when building with nix - postUnpack = '' - ls -la - rm -r ./*/.cargo - ''; }; + ZSTD_SYS_USE_PKG_CONFIG = "1"; + LIBSSH2_SYS_USE_PKG_CONFIG = "1"; + RUSTFLAGS = pkgs.lib.optionalString pkgs.stdenv.isLinux "-C link-arg=-fuse-ld=mold"; + default = outputs.packages.${pkgs.system}.kodotag; }); + apps = forSystems (system: { + kodotag = outputs.packages.${system}.kodotag; + default = outputs.apps.${system}.kodotag; + }); + devShells = genPkgs (pkgs: { default = pkgs.mkShell { inherit (self.checks.${pkgs.system}.git-hooks) shellHook; diff --git a/src/main.rs b/src/main.rs index 61226a6..faa7820 100644 --- a/src/main.rs +++ b/src/main.rs @@ -79,6 +79,8 @@ fn main() -> AppExit { .init_state::() .init_state::(); + app.enable_state_scoped_entities::(); + app.configure_sets( Update, ( @@ -100,6 +102,7 @@ fn main() -> AppExit { OnEnter(View::LoadingGame), (player::startup, statue::startup, map::spawn), ) + .add_systems(OnEnter(View::InGame), (map::finalize)) .add_systems( OnExit(View::InGame), (player::exit, statue::exit, map::exit), diff --git a/src/main_menu.rs b/src/main_menu.rs index dd94655..909905b 100644 --- a/src/main_menu.rs +++ b/src/main_menu.rs @@ -1,5 +1,7 @@ use bevy::prelude::*; +use crate::View; + #[derive(Component, Debug)] pub struct MainMenu; @@ -7,6 +9,7 @@ pub fn startup(mut commands: Commands) { commands .spawn(( MainMenu, + StateScoped(View::MainMenu), Name::new("MenuRoot"), NodeBundle { style: Style { diff --git a/src/map.rs b/src/map.rs index 4cb6aa9..17477fc 100644 --- a/src/map.rs +++ b/src/map.rs @@ -1,6 +1,6 @@ use crate::{inspector::HideFromInspector, prelude::*}; use bevy::{ - ecs::world::CommandQueue, + ecs::{system::SystemState, world::CommandQueue}, tasks::{block_on, futures_lite::future, AsyncComputeTaskPool, Task}, }; // use bevy::{ @@ -11,13 +11,15 @@ use bevy_ecs_tilemap::prelude::*; use rand::prelude::*; use rand_pcg::Pcg64; use rand_seeder::Seeder; -use std::sync::mpsc::channel; #[derive(Component, Debug)] pub struct Tilemap; #[derive(Component)] -struct MapGen(Task); +struct MapGenTask(Task); + +#[derive(Resource, Deref)] +struct TileStorageHandle(TileStorage); pub fn spawn(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? @@ -25,45 +27,65 @@ pub fn spawn(mut commands: Commands, assets: Res) { let mut rng: Pcg64 = Seeder::from("default_seed").make_rng(); let size = TilemapSize::new(1024, 1024); let tilemap = commands.spawn((Tilemap, Name::new("Tilemap"))).id(); - - let mut storage = TileStorage::empty(size); - // let mutex_storage = Mutex::new(storage); - - let task_pool = AsyncComputeTaskPool::get(); - - let (tx, rx) = channel::(); - let tilebundlegenerator = task_pool.spawn(async move { - // 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 - }); - tx.send(TileBundle { - position, - tilemap_id: TilemapId(tilemap), - texture_index, - ..Default::default() - }); - } - } - }); - + 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 tile = commands.spawn().id(); - storage.set(&position, tile); + 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::>::new(world); + let storage = state.get_mut(world); + let entity = world + .spawn(( + HideFromInspector, + TileBundle { + position, + tilemap_id: TilemapId(tilemap), + texture_index, + ..Default::default() + }, + )) + .id(); + storage.set(&position, entity); + }); + command_queue + }); } } +} +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, + tilemap: Query>, + assets: Res, +) { + // TODO: dedupe with load + let size = TilemapSize::new(1024, 1024); let texture = TilemapTexture::Single(assets.load("img/Tileset Grass.png")); let tile_size = TilemapTileSize::new(16., 16.); let grid_size = TilemapGridSize::new(16., 16.); let map_type = TilemapType::Square; - + let storage = storage.0; + let tilemap = tilemap.single(); commands.entity(tilemap).insert(TilemapBundle { grid_size, map_type, @@ -76,82 +98,6 @@ pub fn spawn(mut commands: Commands, assets: Res) { }); } -// pub fn spawn_in_background(mut commands: Commands, assets: Res) { -// let pool = AsyncComputeTaskPool::get(); -// let tilemap_entity = commands.spawn(Name::new("TilemapEntity")).id(); -// let texture_handle: Handle = assets.load("img/Tileset Grass.png"); -// let mut rng: Pcg64 = Seeder::from("default_seed").make_rng(); -// let map_size = UVec2::new(1024, 1024); -// let tile_size = Vec2 { x: 16.0, y: 16.0 }; -// // tiletypes? -// let task = pool.spawn(async move { -// let mut queue = CommandQueue::default(); -// for x in 0..map_size.x { -// for y in 0..map_size.y { -// let pos = Vec2::new(x as f32, y as f32) * tile_size; -// let texture_index = TileTextureIndex(if rng.gen_range(0..1000) > 925 { -// rng.gen_range(0..(16 * 8)) -// } else { -// 0 -// }); -// queue.push(move |world: &mut World| { -// let tile_entity = world -// .spawn(( -// HideFromInspector, -// TileBundle { -// position: tile_pos, -// tilemap_id: TilemapId(tilemap_entity), -// texture_index, -// ..Default::default() -// }, -// )) -// .id(); -// tile_storage_ref.set(&tile_pos, tile_entity); -// }); -// } -// } - -// queue.push(move |world: &mut World| { -// world.spawn(( -// Tilemap, -// Name::new("Tilemap"), -// TilemapBundle { -// grid_size, -// map_type, -// size, -// storage, -// texture, -// tile_size, -// transform: get_tilemap_center_transform(&size, &grid_size, &map_type, f32::MIN), -// ..default() -// }, -// )); -// }); - -// queue -// }); - -// commands.entity(tilemap_entity).insert(MapGen(task)); -// } - -// fn handle_tasks(mut commands: Commands, mut tasks: Query<&mut MapGen>) { -// for mut task in &mut tasks { -// if let Some(mut queue) = block_on(future::poll_once(&mut task.0)) { -// commands.append(&mut queue); -// } -// } -// } - -fn load(mut commands: Commands, mut tasks: Query<&mut MapGen>) { - // 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>) { for id in q.iter() { commands.entity(id).despawn_recursive(); diff --git a/src/player.rs b/src/player.rs index 3a59304..48da0f9 100644 --- a/src/player.rs +++ b/src/player.rs @@ -2,7 +2,7 @@ use std::f32::consts::TAU; use crate::camera::Watched; use crate::movement::{Heading, Mover, Speed, Velocity, YSortable}; -use crate::prelude::*; +use crate::{prelude::*, View}; use bevy::sprite::MaterialMesh2dBundle; const PLAYER_SPEED: f32 = 200.; @@ -35,6 +35,7 @@ pub fn startup( commands .spawn(( Player, + StateScoped(View::InGame), Name::new("Player"), VisibilityBundle { visibility: Visibility::Inherited, diff --git a/src/statue.rs b/src/statue.rs index f2a5306..64984c4 100644 --- a/src/statue.rs +++ b/src/statue.rs @@ -1,5 +1,5 @@ use crate::movement::YSortable; -use crate::prelude::*; +use crate::{prelude::*, View}; #[derive(Component, Debug, Default)] pub struct Statue; @@ -51,7 +51,7 @@ pub fn spawn_statue( }, ..default() }; - commands.spawn((Name::new("Statue"), bundle)); + commands.spawn((Name::new("Statue"), StateScoped(View::InGame), bundle)); } }