
# Objective  ^ enable this Concretely, I need to - list all handle ids for an asset type - fetch the asset as `dyn Reflect`, given a `HandleUntyped` - when encountering a `Handle<T>`, find out what asset type that handle refers to (`T`'s type id) and turn the handle into a `HandleUntyped` ## Solution - add `ReflectAsset` type containing function pointers for working with assets ```rust pub struct ReflectAsset { type_uuid: Uuid, assets_resource_type_id: TypeId, // TypeId of the `Assets<T>` resource get: fn(&World, HandleUntyped) -> Option<&dyn Reflect>, get_mut: fn(&mut World, HandleUntyped) -> Option<&mut dyn Reflect>, get_unchecked_mut: unsafe fn(&World, HandleUntyped) -> Option<&mut dyn Reflect>, add: fn(&mut World, &dyn Reflect) -> HandleUntyped, set: fn(&mut World, HandleUntyped, &dyn Reflect) -> HandleUntyped, len: fn(&World) -> usize, ids: for<'w> fn(&'w World) -> Box<dyn Iterator<Item = HandleId> + 'w>, remove: fn(&mut World, HandleUntyped) -> Option<Box<dyn Reflect>>, } ``` - add `ReflectHandle` type relating the handle back to the asset type and providing a way to create a `HandleUntyped` ```rust pub struct ReflectHandle { type_uuid: Uuid, asset_type_id: TypeId, downcast_handle_untyped: fn(&dyn Any) -> Option<HandleUntyped>, } ``` - add the corresponding `FromType` impls - add a function `app.register_asset_reflect` which is supposed to be called after `.add_asset` and registers `ReflectAsset` and `ReflectHandle` in the type registry --- ## Changelog - add `ReflectAsset` and `ReflectHandle` types, which allow code to use reflection to manipulate arbitrary assets without knowing their types at compile time
82 lines
2.6 KiB
Rust
82 lines
2.6 KiB
Rust
mod bundle;
|
|
mod dynamic_texture_atlas_builder;
|
|
mod mesh2d;
|
|
mod render;
|
|
mod sprite;
|
|
mod texture_atlas;
|
|
mod texture_atlas_builder;
|
|
|
|
pub mod collide_aabb;
|
|
|
|
pub mod prelude {
|
|
#[doc(hidden)]
|
|
pub use crate::{
|
|
bundle::{SpriteBundle, SpriteSheetBundle},
|
|
sprite::Sprite,
|
|
texture_atlas::{TextureAtlas, TextureAtlasSprite},
|
|
ColorMaterial, ColorMesh2dBundle, TextureAtlasBuilder,
|
|
};
|
|
}
|
|
|
|
pub use bundle::*;
|
|
pub use dynamic_texture_atlas_builder::*;
|
|
pub use mesh2d::*;
|
|
pub use render::*;
|
|
pub use sprite::*;
|
|
pub use texture_atlas::*;
|
|
pub use texture_atlas_builder::*;
|
|
|
|
use bevy_app::prelude::*;
|
|
use bevy_asset::{AddAsset, Assets, HandleUntyped};
|
|
use bevy_core_pipeline::core_2d::Transparent2d;
|
|
use bevy_ecs::schedule::{IntoSystemDescriptor, SystemLabel};
|
|
use bevy_reflect::TypeUuid;
|
|
use bevy_render::{
|
|
render_phase::AddRenderCommand,
|
|
render_resource::{Shader, SpecializedRenderPipelines},
|
|
RenderApp, RenderStage,
|
|
};
|
|
|
|
#[derive(Default)]
|
|
pub struct SpritePlugin;
|
|
|
|
pub const SPRITE_SHADER_HANDLE: HandleUntyped =
|
|
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 2763343953151597127);
|
|
|
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemLabel)]
|
|
pub enum SpriteSystem {
|
|
ExtractSprites,
|
|
}
|
|
|
|
impl Plugin for SpritePlugin {
|
|
fn build(&self, app: &mut App) {
|
|
let mut shaders = app.world.resource_mut::<Assets<Shader>>();
|
|
let sprite_shader = Shader::from_wgsl(include_str!("render/sprite.wgsl"));
|
|
shaders.set_untracked(SPRITE_SHADER_HANDLE, sprite_shader);
|
|
app.add_asset::<TextureAtlas>()
|
|
.register_asset_reflect::<TextureAtlas>()
|
|
.register_type::<Sprite>()
|
|
.register_type::<Anchor>()
|
|
.register_type::<Mesh2dHandle>()
|
|
.add_plugin(Mesh2dRenderPlugin)
|
|
.add_plugin(ColorMaterialPlugin);
|
|
|
|
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
|
render_app
|
|
.init_resource::<ImageBindGroups>()
|
|
.init_resource::<SpritePipeline>()
|
|
.init_resource::<SpecializedRenderPipelines<SpritePipeline>>()
|
|
.init_resource::<SpriteMeta>()
|
|
.init_resource::<ExtractedSprites>()
|
|
.init_resource::<SpriteAssetEvents>()
|
|
.add_render_command::<Transparent2d, DrawSprite>()
|
|
.add_system_to_stage(
|
|
RenderStage::Extract,
|
|
render::extract_sprites.label(SpriteSystem::ExtractSprites),
|
|
)
|
|
.add_system_to_stage(RenderStage::Extract, render::extract_sprite_events)
|
|
.add_system_to_stage(RenderStage::Queue, queue_sprites);
|
|
};
|
|
}
|
|
}
|