diff --git a/crates/bevy_asset/Cargo.toml b/crates/bevy_asset/Cargo.toml index 11bd704b09..aed57dcf9c 100644 --- a/crates/bevy_asset/Cargo.toml +++ b/crates/bevy_asset/Cargo.toml @@ -5,6 +5,8 @@ authors = ["Carter Anderson "] edition = "2018" [dependencies] +bevy_app = { path = "../bevy_app" } bevy_core = { path = "../bevy_core" } +legion = { path = "../bevy_legion" } uuid = { version = "0.8", features = ["v4", "serde"] } \ No newline at end of file diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 8d59e93442..b97a7f48e2 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -1,12 +1,19 @@ mod handle; pub use handle::*; +use bevy_app::{stage, AppBuilder, Events}; use bevy_core::bytes::GetBytes; +use legion::prelude::*; use std::collections::HashMap; +pub enum AssetEvent { + Created { handle: Handle }, +} + pub struct AssetStorage { assets: HashMap, names: HashMap>, + events: Events>, } impl AssetStorage { @@ -14,6 +21,7 @@ impl AssetStorage { AssetStorage { assets: HashMap::new(), names: HashMap::new(), + events: Events::default(), } } @@ -24,16 +32,21 @@ impl AssetStorage { pub fn add(&mut self, asset: T) -> Handle { let id = HandleId::new(); self.assets.insert(id, asset); - Handle::from_id(id) + let handle = Handle::from_id(id); + self.events.send(AssetEvent::Created { handle }); + handle } pub fn add_with_handle(&mut self, handle: Handle, asset: T) { self.assets.insert(handle.id, asset); + self.events.send(AssetEvent::Created { handle }); } pub fn add_default(&mut self, asset: T) -> Handle { self.assets.insert(DEFAULT_HANDLE_ID, asset); - Handle::default() + let handle = Handle::default(); + self.events.send(AssetEvent::Created { handle }); + handle } pub fn set_name(&mut self, name: &str, handle: Handle) { @@ -59,6 +72,13 @@ impl AssetStorage { pub fn iter(&self) -> impl Iterator, &T)> { self.assets.iter().map(|(k, v)| (Handle::from_id(*k), v)) } + + pub fn asset_event_system( + mut events: ResourceMut>>, + mut storage: ResourceMut>, + ) { + events.extend(storage.events.drain()) + } } impl GetBytes for Handle { @@ -70,3 +90,23 @@ impl GetBytes for Handle { None } } + +pub trait AddAsset { + fn add_asset(&mut self) -> &mut Self + where + T: Send + Sync + 'static; +} + +impl AddAsset for AppBuilder { + fn add_asset(&mut self) -> &mut Self + where + T: Send + Sync + 'static, + { + self.add_resource(AssetStorage::::new()) + .add_system_to_stage( + stage::EVENT_UPDATE, + AssetStorage::::asset_event_system.system(), + ) + .add_event::>() + } +} diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 45bf991e17..eb13f7cf5e 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -8,7 +8,7 @@ mod forward_pbr_render_graph; pub use forward_pbr_render_graph::*; use bevy_app::{stage, AppBuilder, AppPlugin}; -use bevy_asset::AssetStorage; +use bevy_asset::AddAsset; use bevy_render::{render_graph::RenderGraph, shader}; use legion::prelude::IntoSystem; use material::StandardMaterial; @@ -19,11 +19,10 @@ pub struct PbrPlugin; impl AppPlugin for PbrPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_resource(AssetStorage::::new()) - .add_system_to_stage( - stage::POST_UPDATE, - shader::asset_handle_shader_def_system::.system(), - ); + app.add_asset::().add_system_to_stage( + stage::POST_UPDATE, + shader::asset_handle_shader_def_system::.system(), + ); let resources = app.resources(); let mut render_graph = resources.get_mut::().unwrap(); render_graph.add_pbr_graph(resources); diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 3388b73110..33f835726b 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -41,7 +41,7 @@ use self::{ use base_render_graph::{BaseRenderGraphBuilder, BaseRenderGraphConfig}; use bevy_app::{stage, AppBuilder, AppPlugin}; -use bevy_asset::AssetStorage; +use bevy_asset::AddAsset; use mesh::mesh_resource_provider_system; use render_graph::RenderGraph; @@ -71,11 +71,11 @@ impl AppPlugin for RenderPlugin { app.add_stage_after(stage::POST_UPDATE, RENDER_RESOURCE_STAGE) .add_stage_after(RENDER_RESOURCE_STAGE, RENDER_STAGE) // resources + .add_asset::() + .add_asset::() + .add_asset::() + .add_asset::() .add_resource(render_graph) - .add_resource(AssetStorage::::new()) - .add_resource(AssetStorage::::new()) - .add_resource(AssetStorage::::new()) - .add_resource(AssetStorage::::new()) .add_resource(PipelineAssignments::new()) .add_resource(PipelineCompiler::new()) .add_resource(RenderResourceAssignments::default()) diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index f40cef971a..dc2e70012e 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -18,7 +18,7 @@ pub use sprite::*; pub use ui_update_system::*; use bevy_app::{stage, AppBuilder, AppPlugin}; -use bevy_asset::{AssetStorage, Handle}; +use bevy_asset::{AddAsset, AssetStorage, Handle}; use bevy_render::{ mesh::{shape::Quad, Mesh}, render_graph::RenderGraph, @@ -35,10 +35,7 @@ pub const QUAD_HANDLE: Handle = Handle::from_u128(142404619811301375266013 impl AppPlugin for UiPlugin { fn build(&self, app: &mut AppBuilder) { - let mut color_materials = AssetStorage::::new(); - color_materials.add_default(ColorMaterial::default()); - - app.add_resource(color_materials) + app.add_asset::() .add_system_to_stage( stage::POST_UPDATE, asset_handle_shader_def_system::.system(), @@ -57,5 +54,8 @@ impl AppPlugin for UiPlugin { size: Vec2::new(1.0, 1.0), }), ); + + let mut color_materials = resources.get_mut::>().unwrap(); + color_materials.add_default(ColorMaterial::default()); } } diff --git a/examples/shader/shader_custom_material.rs b/examples/shader/shader_custom_material.rs index 19e13c28cc..6f358d9c52 100644 --- a/examples/shader/shader_custom_material.rs +++ b/examples/shader/shader_custom_material.rs @@ -3,6 +3,7 @@ use bevy::prelude::*; fn main() { App::build() .add_default_plugins() + .add_asset::() .add_startup_system(setup) .run(); } @@ -66,11 +67,10 @@ fn setup(world: &mut World, resources: &mut Resources) { }; // create materials - let mut material_storage = AssetStorage::::new(); + let mut material_storage = resources.get_mut::>().unwrap(); let material = material_storage.add(MyMaterial { color: Color::rgb(0.0, 0.8, 0.0), }); - resources.insert(material_storage); let mut mesh_storage = resources.get_mut::>().unwrap(); let cube_handle = mesh_storage.add(Mesh::from(shape::Cube)); diff --git a/examples/shader/shader_defs.rs b/examples/shader/shader_defs.rs index a52161e11a..1aabec37eb 100644 --- a/examples/shader/shader_defs.rs +++ b/examples/shader/shader_defs.rs @@ -3,6 +3,7 @@ use bevy::{prelude::*, render::shader}; fn main() { App::build() .add_default_plugins() + .add_asset::() .add_startup_system(setup) .add_system_to_stage( stage::POST_UPDATE, @@ -76,7 +77,7 @@ fn setup(world: &mut World, resources: &mut Resources) { }; // create materials - let mut material_storage = AssetStorage::::new(); + let mut material_storage = resources.get_mut::>().unwrap(); let green_material = material_storage.add(MyMaterial { color: Color::rgb(0.0, 0.8, 0.0), always_red: false, @@ -86,7 +87,6 @@ fn setup(world: &mut World, resources: &mut Resources) { color: Color::rgb(0.0, 0.0, 0.0), always_red: true, }); - resources.insert(material_storage); let mut mesh_storage = resources.get_mut::>().unwrap(); let cube_handle = mesh_storage.add(Mesh::from(shape::Cube)); diff --git a/src/prelude.rs b/src/prelude.rs index b3b4c8da4b..2015b5713b 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,5 +1,5 @@ #[cfg(feature = "asset")] -pub use crate::asset::{AssetStorage, Handle}; +pub use crate::asset::{AddAsset, AssetEvent, AssetStorage, Handle}; #[cfg(feature = "core")] pub use crate::core::{ time::Time,