diff --git a/Cargo.lock b/Cargo.lock index b6ae571a20..dce0f7d744 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1093,6 +1093,7 @@ dependencies = [ name = "bones_framework" version = "0.3.0" dependencies = [ + "bones_asset", "bones_lib", "document-features", "egui", @@ -1116,7 +1117,6 @@ dependencies = [ name = "bones_lib" version = "0.3.0" dependencies = [ - "bones_asset", "bones_ecs", ] diff --git a/demos/assets_minimal/src/main.rs b/demos/assets_minimal/src/main.rs index 8a577c804d..095fc1986f 100644 --- a/demos/assets_minimal/src/main.rs +++ b/demos/assets_minimal/src/main.rs @@ -22,8 +22,11 @@ fn main() { // First create bones game. let mut game = Game::new(); - // We must register all of our asset types before they can be loaded. - game.asset_server().register_asset::(); + game + // We initialize the asset server. + .init_shared_resource::() + // We must register all of our asset types before they can be loaded. + .register_asset::(); // Create a new session for the game menu. Each session is it's own bones world with it's own // plugins, systems, and entities. diff --git a/demos/features/assets/game.yaml b/demos/features/assets/game.yaml index f212544e2e..91240b9199 100644 --- a/demos/features/assets/game.yaml +++ b/demos/features/assets/game.yaml @@ -1,3 +1,4 @@ +menu_image: ./menu-image.png sprite_demo: ./sprite/fractal.png atlas_demo: ./atlas/atlas-demo.yaml tilemap_demo: ./tilemap/tilemap.yaml diff --git a/demos/features/assets/menu-image.png b/demos/features/assets/menu-image.png new file mode 100644 index 0000000000..39b5937521 Binary files /dev/null and b/demos/features/assets/menu-image.png differ diff --git a/demos/features/src/main.rs b/demos/features/src/main.rs index 8fc7240704..9667ea4c5a 100644 --- a/demos/features/src/main.rs +++ b/demos/features/src/main.rs @@ -14,6 +14,8 @@ use bones_framework::prelude::*; // Allow asset to be loaded from "game.yaml" assets. #[type_data(metadata_asset("game"))] struct GameMeta { + /// The image displayed on the menu. + menu_image: Handle, /// The image for the sprite demo sprite_demo: Handle, /// Character information that will be loaded from a separate asset file. @@ -80,7 +82,7 @@ pub fn create_game() -> Game { let mut game = Game::new(); // Configure the asset server - game.asset_server() + game.init_shared_resource::() // Register the default asset types .register_default_assets() // Register our custom asset types @@ -118,9 +120,11 @@ fn menu_startup( /// Our main menu system. fn menu_system( + meta: Root, egui_ctx: ResMut, mut sessions: ResMut, mut session_options: ResMut, + egui_textures: Res, // Get the localization field from our `GameMeta` localization: Localization, ) { @@ -172,6 +176,13 @@ fn menu_system( .create("path2d_demo") .install_plugin(path2d_demo_plugin); } + + ui.add_space(40.0); + + // When using a bones image in egui, we have to get it's corresponding egui texture + // from the egui textures resource. + ui.label("Bones Image Rendered in Egui"); + ui.image(egui_textures.get(meta.menu_image), [100., 100.]); }); }); } diff --git a/framework_crates/bones_bevy_renderer/src/lib.rs b/framework_crates/bones_bevy_renderer/src/lib.rs index 127f365831..04fd22bacd 100644 --- a/framework_crates/bones_bevy_renderer/src/lib.rs +++ b/framework_crates/bones_bevy_renderer/src/lib.rs @@ -74,22 +74,40 @@ impl BonesImageIds { pub fn load_bones_images( &mut self, bones_assets: &mut bones::AssetServer, + bones_egui_textures: &mut bones::EguiTextures, bevy_images: &mut Assets, + bevy_egui_textures: &mut bevy_egui::EguiUserTextures, ) { - for asset in bones_assets.store.assets.values_mut() { + for (handle, cid) in bones_assets.store.asset_ids.iter() { + let asset = bones_assets.store.assets.get_mut(cid).unwrap(); if let Ok(image) = asset.data.try_cast_mut::() { - self.load_bones_image(image, bevy_images) + self.load_bones_image( + handle.typed(), + image, + bones_egui_textures, + bevy_images, + bevy_egui_textures, + ) } } } /// Load a bones image into bevy. - pub fn load_bones_image(&mut self, image: &mut bones::Image, bevy_images: &mut Assets) { + pub fn load_bones_image( + &mut self, + bones_handle: bones::Handle, + image: &mut bones::Image, + bones_egui_textures: &mut bones::EguiTextures, + bevy_images: &mut Assets, + bevy_egui_textures: &mut bevy_egui::EguiUserTextures, + ) { let Self { map, next_id } = self; let mut taken_image = bones::Image::External(0); // Dummy value temporarily std::mem::swap(image, &mut taken_image); if let bones::Image::Data(data) = taken_image { let handle = bevy_images.add(Image::from_dynamic(data, true)); + let egui_texture = bevy_egui_textures.add_image(handle.clone()); + bones_egui_textures.insert(bones_handle, egui_texture); map.insert(*next_id, handle); *image = bones::Image::External(*next_id); *next_id += 1; @@ -103,7 +121,7 @@ pub struct BonesData { /// The bones game. pub game: bones::Game, /// The bones asset server cell. - pub asset_server: bones::AtomicResource, + pub asset_server: Option>, } impl BonesBevyRenderer { @@ -122,7 +140,7 @@ impl BonesBevyRenderer { } /// Return a bevy [`App`] configured to run the bones game. - pub fn app(self) -> App { + pub fn app(mut self) -> App { let mut app = App::new(); // Initialize Bevy plugins we use @@ -142,10 +160,15 @@ impl BonesBevyRenderer { }) .init_resource::(); - { - let mut bones_image_ids = BonesImageIds::default(); - let mut asset_server = self.game.asset_server(); - let mut bevy_images = app.world.resource_mut::>(); + let mut bones_image_ids = BonesImageIds::default(); + let mut bones_egui_textures = bones::EguiTextures::default(); + 'asset_load: { + let Some(mut asset_server) = self.game.shared_resource::() else { + break 'asset_load; + }; + let world = app.world.cell(); + let mut bevy_images = world.resource_mut::>(); + let mut bevy_egui_textures = world.resource_mut::(); if !asset_server.asset_types.is_empty() { #[cfg(not(target_arch = "wasm32"))] @@ -160,22 +183,33 @@ impl BonesBevyRenderer { .expect("Could not load game assets"); // Take all loaded image assets and conver them to external images that reference bevy handles - bones_image_ids.load_bones_images(&mut asset_server, &mut bevy_images); + bones_image_ids.load_bones_images( + &mut asset_server, + &mut bones_egui_textures, + &mut bevy_images, + &mut bevy_egui_textures, + ); } #[cfg(target_arch = "wasm32")] { - bones_image_ids.load_bones_images(&mut asset_server, &mut bevy_images); + bones_image_ids.load_bones_images( + &mut asset_server, + &mut bones_egui_textures, + &mut bevy_images, + &mut bevy_egui_textures, + ); // TODO: Implement WASM asset loader. unimplemented!("WASM asset loading is not implemented yet."); } } - - app.insert_resource(bones_image_ids); } + self.game.insert_shared_resource(bones_egui_textures); + app.insert_resource(bones_image_ids); + // Insert the bones data app.insert_resource(BonesData { - asset_server: self.game.asset_server.clone_cell(), + asset_server: self.game.shared_resource_cell::(), game: self.game, }) .init_resource::(); @@ -257,76 +291,82 @@ fn step_bones_game( In((mouse_inputs, keyboard_inputs)): In<(bones::MouseInputs, bones::KeyboardInputs)>, world: &mut World, ) { - world.resource_scope(|world: &mut World, mut data: Mut| { - world.resource_scope( - |world: &mut World, mut bones_image_ids: Mut| { - world.resource_scope(|world: &mut World, mut bevy_images: Mut>| { - let egui_ctx = { - let mut egui_query = - world.query_filtered::<&mut EguiContext, With>(); - let mut egui_ctx = egui_query.get_single_mut(world).unwrap(); - egui_ctx.get_mut().clone() - }; - let BonesData { game, asset_server } = &mut *data; - let bevy_time = world.resource::