fix scene loading (#988)

This commit is contained in:
Carter Anderson 2020-12-03 13:57:36 -08:00 committed by GitHub
parent 59d98de194
commit 704a116778
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 116 additions and 83 deletions

View file

@ -3,6 +3,7 @@ use crate::{
};
use bevy_app::{prelude::Events, AppBuilder};
use bevy_ecs::{FromResources, ResMut};
use bevy_reflect::RegisterTypeBuilder;
use bevy_utils::HashMap;
use crossbeam_channel::Sender;
use std::fmt::Debug;
@ -219,6 +220,7 @@ impl AddAsset for AppBuilder {
self.add_resource(assets)
.add_system_to_stage(super::stage::ASSET_EVENTS, Assets::<T>::asset_event_system)
.add_system_to_stage(crate::stage::LOAD_ASSETS, update_asset_storage_system::<T>)
.register_type::<Handle<T>>()
.add_event::<AssetEvent<T>>()
}

View file

@ -9,7 +9,7 @@ use crate::{
path::{AssetPath, AssetPathId},
Asset, Assets,
};
use bevy_reflect::{Reflect, ReflectDeserialize};
use bevy_reflect::{Reflect, ReflectComponent, ReflectDeserialize};
use bevy_utils::Uuid;
use crossbeam_channel::{Receiver, Sender};
use serde::{Deserialize, Serialize};
@ -57,9 +57,10 @@ impl HandleId {
///
/// Handles contain a unique id that corresponds to a specific asset in the [Assets](crate::Assets) collection.
#[derive(Reflect)]
#[reflect(Component)]
pub struct Handle<T>
where
T: 'static,
T: Asset,
{
pub id: HandleId,
#[reflect(ignore)]
@ -82,17 +83,6 @@ impl Debug for HandleType {
}
}
impl<T> Handle<T> {
// TODO: remove "uuid" parameter whenever rust support type constraints in const fns
pub const fn weak_from_u64(uuid: Uuid, id: u64) -> Self {
Self {
id: HandleId::new(uuid, id),
handle_type: HandleType::Weak,
marker: PhantomData,
}
}
}
impl<T: Asset> Handle<T> {
pub(crate) fn strong(id: HandleId, ref_change_sender: Sender<RefChange>) -> Self {
ref_change_sender.send(RefChange::Increment(id)).unwrap();
@ -111,7 +101,7 @@ impl<T: Asset> Handle<T> {
}
}
pub fn as_weak<U>(&self) -> Handle<U> {
pub fn as_weak<U: Asset>(&self) -> Handle<U> {
Handle {
id: self.id,
handle_type: HandleType::Weak,
@ -152,7 +142,7 @@ impl<T: Asset> Handle<T> {
}
}
impl<T> Drop for Handle<T> {
impl<T: Asset> Drop for Handle<T> {
fn drop(&mut self) {
match self.handle_type {
HandleType::Strong(ref sender) => {
@ -164,45 +154,51 @@ impl<T> Drop for Handle<T> {
}
}
impl<T> From<Handle<T>> for HandleId {
impl<T: Asset> From<Handle<T>> for HandleId {
fn from(value: Handle<T>) -> Self {
value.id
}
}
impl From<HandleUntyped> for HandleId {
fn from(value: HandleUntyped) -> Self {
value.id
}
}
impl From<&str> for HandleId {
fn from(value: &str) -> Self {
AssetPathId::from(value).into()
}
}
impl<T> From<&Handle<T>> for HandleId {
impl<T: Asset> From<&Handle<T>> for HandleId {
fn from(value: &Handle<T>) -> Self {
value.id
}
}
impl<T> Hash for Handle<T> {
impl<T: Asset> Hash for Handle<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
Hash::hash(&self.id, state);
}
}
impl<T> PartialEq for Handle<T> {
impl<T: Asset> PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl<T> Eq for Handle<T> {}
impl<T: Asset> Eq for Handle<T> {}
impl<T> PartialOrd for Handle<T> {
impl<T: Asset> PartialOrd for Handle<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.id.cmp(&other.id))
}
}
impl<T> Ord for Handle<T> {
impl<T: Asset> Ord for Handle<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
@ -214,7 +210,7 @@ impl<T: Asset> Default for Handle<T> {
}
}
impl<T> Debug for Handle<T> {
impl<T: Asset> Debug for Handle<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let name = std::any::type_name::<T>().split("::").last().unwrap();
write!(f, "{:?}Handle<{}>({:?})", self.handle_type, name, self.id)
@ -231,8 +227,8 @@ impl<T: Asset> Clone for Handle<T> {
}
// SAFE: T is phantom data and Handle::id is an integer
unsafe impl<T> Send for Handle<T> {}
unsafe impl<T> Sync for Handle<T> {}
unsafe impl<T: Asset> Send for Handle<T> {}
unsafe impl<T: Asset> Sync for Handle<T> {}
/// A non-generic version of [Handle]
///
@ -244,6 +240,13 @@ pub struct HandleUntyped {
}
impl HandleUntyped {
pub const fn weak_from_u64(uuid: Uuid, id: u64) -> Self {
Self {
id: HandleId::new(uuid, id),
handle_type: HandleType::Weak,
}
}
pub(crate) fn strong(id: HandleId, ref_change_sender: Sender<RefChange>) -> Self {
ref_change_sender.send(RefChange::Increment(id)).unwrap();
Self {

View file

@ -1,17 +1,17 @@
use crate::{AudioSource, Decodable};
use bevy_asset::Handle;
use bevy_asset::{Asset, Handle};
use parking_lot::RwLock;
use std::{collections::VecDeque, fmt};
/// The external struct used to play audio
pub struct Audio<P = AudioSource>
where
P: Decodable,
P: Asset + Decodable,
{
pub queue: RwLock<VecDeque<Handle<P>>>,
}
impl<P> fmt::Debug for Audio<P>
impl<P: Asset> fmt::Debug for Audio<P>
where
P: Decodable,
{
@ -22,7 +22,7 @@ where
impl<P> Default for Audio<P>
where
P: Decodable,
P: Asset + Decodable,
{
fn default() -> Self {
Self {
@ -33,7 +33,7 @@ where
impl<P> Audio<P>
where
P: Decodable,
P: Asset + Decodable,
<P as Decodable>::Decoder: rodio::Source + Send + Sync,
<<P as Decodable>::Decoder as Iterator>::Item: rodio::Sample + Send + Sync,
{

View file

@ -1,5 +1,5 @@
use bevy_ecs::prelude::*;
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use bevy_utils::{HashMap, HashSet};
use std::{
borrow::Cow,
@ -9,6 +9,7 @@ use std::{
/// A collection of labels
#[derive(Default, Reflect)]
#[reflect(Component)]
pub struct Labels {
labels: HashSet<Cow<'static, str>>,
}

View file

@ -25,7 +25,7 @@ impl Default for PbrBundle {
fn default() -> Self {
Self {
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
FORWARD_PIPELINE_HANDLE,
FORWARD_PIPELINE_HANDLE.typed(),
)]),
mesh: Default::default(),
material: Default::default(),

View file

@ -1,4 +1,4 @@
use bevy_asset::{Assets, Handle};
use bevy_asset::{Assets, HandleUntyped};
use bevy_reflect::TypeUuid;
use bevy_render::{
pipeline::{
@ -10,8 +10,8 @@ use bevy_render::{
texture::TextureFormat,
};
pub const FORWARD_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
Handle::weak_from_u64(PipelineDescriptor::TYPE_UUID, 13148362314012771389);
pub const FORWARD_PIPELINE_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 13148362314012771389);
pub(crate) fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
PipelineDescriptor {

View file

@ -2,10 +2,11 @@ use super::CameraProjection;
use bevy_app::prelude::{EventReader, Events};
use bevy_ecs::{Added, Component, Entity, Local, Query, QuerySet, Res};
use bevy_math::Mat4;
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use bevy_window::{WindowCreated, WindowId, WindowResized, Windows};
#[derive(Default, Debug, Reflect)]
#[reflect(Component)]
pub struct Camera {
pub projection_matrix: Mat4,
pub name: Option<String>,

View file

@ -1,6 +1,6 @@
use super::DepthCalculation;
use bevy_math::Mat4;
use bevy_reflect::{Reflect, ReflectDeserialize};
use bevy_reflect::{Reflect, ReflectComponent, ReflectDeserialize};
use serde::{Deserialize, Serialize};
pub trait CameraProjection {
@ -10,6 +10,7 @@ pub trait CameraProjection {
}
#[derive(Debug, Clone, Reflect)]
#[reflect(Component)]
pub struct PerspectiveProjection {
pub fov: f32,
pub aspect_ratio: f32,
@ -51,6 +52,7 @@ pub enum WindowOrigin {
}
#[derive(Debug, Clone, Reflect)]
#[reflect(Component)]
pub struct OrthographicProjection {
pub left: f32,
pub right: f32,

View file

@ -2,7 +2,7 @@ use super::{Camera, DepthCalculation};
use crate::Draw;
use bevy_core::FloatOrd;
use bevy_ecs::{Entity, Query, With};
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use bevy_transform::prelude::GlobalTransform;
#[derive(Debug)]
@ -12,6 +12,7 @@ pub struct VisibleEntity {
}
#[derive(Default, Debug, Reflect)]
#[reflect(Component)]
pub struct VisibleEntities {
#[reflect(ignore)]
pub value: Vec<VisibleEntity>,

View file

@ -8,7 +8,7 @@ use crate::{
};
use bevy_asset::{Asset, Assets, Handle};
use bevy_ecs::{Query, Res, ResMut, SystemParam};
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use std::{ops::Range, sync::Arc};
use thiserror::Error;
@ -45,6 +45,7 @@ pub enum RenderCommand {
/// A component that indicates how to draw an entity.
#[derive(Debug, Clone, Reflect)]
#[reflect(Component)]
pub struct Draw {
pub is_visible: bool,
pub is_transparent: bool,

View file

@ -7,7 +7,7 @@ use crate::{
};
use bevy_asset::{Assets, Handle};
use bevy_ecs::{Query, Res, ResMut};
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use bevy_utils::HashSet;
#[derive(Debug, Default, Clone, Reflect)]
@ -40,6 +40,7 @@ impl RenderPipeline {
}
#[derive(Debug, Clone, Reflect)]
#[reflect(Component)]
pub struct RenderPipelines {
pub pipelines: Vec<RenderPipeline>,
#[reflect(ignore)]

View file

@ -10,11 +10,12 @@ use crate::{
texture::{Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsage},
Color,
};
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use bevy_window::WindowId;
/// A component that indicates that an entity should be drawn in the "main pass"
#[derive(Default, Reflect)]
#[reflect(Component)]
pub struct MainPass;
#[derive(Debug)]

View file

@ -34,8 +34,10 @@ pub struct SceneSpawner {
#[derive(Error, Debug)]
pub enum SceneSpawnError {
#[error("scene contains an unregistered component")]
#[error("scene contains the unregistered component `{type_name}`. consider adding `#[reflect(Component)]` to your type")]
UnregisteredComponent { type_name: String },
#[error("scene contains the unregistered type `{type_name}`. consider registering the type using `app.register_type::<T>()`")]
UnregisteredType { type_name: String },
#[error("scene does not exist")]
NonExistentScene { handle: Handle<DynamicScene> },
#[error("scene does not exist")]
@ -118,7 +120,7 @@ impl SceneSpawner {
for component in scene_entity.components.iter() {
let registration = type_registry
.get_with_name(component.type_name())
.ok_or_else(|| SceneSpawnError::UnregisteredComponent {
.ok_or_else(|| SceneSpawnError::UnregisteredType {
type_name: component.type_name().to_string(),
})?;
let reflect_component =
@ -166,17 +168,24 @@ impl SceneSpawner {
.entry(*scene_entity)
.or_insert_with(|| world.reserve_entity());
for type_info in archetype.types() {
if let Some(registration) = type_registry.get(type_info.id()) {
if let Some(component_reflect) = registration.data::<ReflectComponent>() {
component_reflect.copy_component(
&scene.world,
world,
resources,
*scene_entity,
entity,
);
let registration = type_registry.get(type_info.id()).ok_or_else(|| {
SceneSpawnError::UnregisteredType {
type_name: type_info.type_name().to_string(),
}
}
})?;
let reflect_component =
registration.data::<ReflectComponent>().ok_or_else(|| {
SceneSpawnError::UnregisteredComponent {
type_name: registration.name().to_string(),
}
})?;
reflect_component.copy_component(
&scene.world,
world,
resources,
*scene_entity,
entity,
);
}
}
}
@ -278,7 +287,9 @@ pub fn scene_spawner_system(world: &mut World, resources: &mut Resources) {
}
scene_spawner.despawn_queued_scenes(world).unwrap();
scene_spawner.spawn_queued_scenes(world, resources).unwrap();
scene_spawner
.spawn_queued_scenes(world, resources)
.unwrap_or_else(|err| panic!("{}", err));
scene_spawner
.update_spawned_scenes(world, resources, &updated_spawned_scenes)
.unwrap();

View file

@ -27,9 +27,9 @@ pub struct SpriteBundle {
impl Default for SpriteBundle {
fn default() -> Self {
Self {
mesh: QUAD_HANDLE,
mesh: QUAD_HANDLE.typed(),
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
SPRITE_PIPELINE_HANDLE,
SPRITE_PIPELINE_HANDLE.typed(),
)]),
draw: Draw {
is_transparent: true,
@ -65,13 +65,13 @@ impl Default for SpriteSheetBundle {
fn default() -> Self {
Self {
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
SPRITE_SHEET_PIPELINE_HANDLE,
SPRITE_SHEET_PIPELINE_HANDLE.typed(),
)]),
draw: Draw {
is_transparent: true,
..Default::default()
},
mesh: QUAD_HANDLE,
mesh: QUAD_HANDLE.typed(),
main_pass: MainPass,
sprite: Default::default(),
texture_atlas: Default::default(),

View file

@ -25,7 +25,7 @@ pub mod prelude {
}
use bevy_app::prelude::*;
use bevy_asset::{AddAsset, Assets, Handle};
use bevy_asset::{AddAsset, Assets, Handle, HandleUntyped};
use bevy_math::Vec2;
use bevy_reflect::{RegisterTypeBuilder, TypeUuid};
use bevy_render::{
@ -38,7 +38,8 @@ use sprite::sprite_system;
#[derive(Default)]
pub struct SpritePlugin;
pub const QUAD_HANDLE: Handle<Mesh> = Handle::weak_from_u64(Mesh::TYPE_UUID, 14240461981130137526);
pub const QUAD_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(Mesh::TYPE_UUID, 14240461981130137526);
impl Plugin for SpritePlugin {
fn build(&self, app: &mut AppBuilder) {

View file

@ -1,5 +1,5 @@
use crate::{ColorMaterial, Sprite, TextureAtlas, TextureAtlasSprite};
use bevy_asset::{Assets, Handle};
use bevy_asset::{Assets, HandleUntyped};
use bevy_ecs::Resources;
use bevy_reflect::TypeUuid;
use bevy_render::{
@ -13,11 +13,11 @@ use bevy_render::{
texture::TextureFormat,
};
pub const SPRITE_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
Handle::weak_from_u64(PipelineDescriptor::TYPE_UUID, 2785347840338765446);
pub const SPRITE_PIPELINE_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 2785347840338765446);
pub const SPRITE_SHEET_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
Handle::weak_from_u64(PipelineDescriptor::TYPE_UUID, 9016885805180281612);
pub const SPRITE_SHEET_PIPELINE_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 9016885805180281612);
pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
PipelineDescriptor {

View file

@ -3,6 +3,7 @@ use bevy_render::{
color::Color,
draw::{Draw, DrawContext, DrawError, Drawable},
mesh,
mesh::Mesh,
pipeline::{PipelineSpecialization, VertexBufferDescriptor},
prelude::Msaa,
renderer::{BindGroup, RenderResourceBindings, RenderResourceId},
@ -57,7 +58,7 @@ impl<'a> Drawable for DrawableText<'a> {
fn draw(&mut self, draw: &mut Draw, context: &mut DrawContext) -> Result<(), DrawError> {
context.set_pipeline(
draw,
&bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE,
&bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE.typed(),
&PipelineSpecialization {
sample_count: self.msaa.samples,
vertex_buffer_descriptor: self.font_quad_vertex_descriptor.clone(),
@ -68,7 +69,10 @@ impl<'a> Drawable for DrawableText<'a> {
let render_resource_context = &**context.render_resource_context;
if let Some(RenderResourceId::Buffer(vertex_attribute_buffer_id)) = render_resource_context
.get_asset_resource(&bevy_sprite::QUAD_HANDLE, mesh::VERTEX_ATTRIBUTE_BUFFER_ID)
.get_asset_resource(
&bevy_sprite::QUAD_HANDLE.typed::<Mesh>(),
mesh::VERTEX_ATTRIBUTE_BUFFER_ID,
)
{
draw.set_vertex_buffer(0, vertex_attribute_buffer_id, 0);
} else {
@ -77,7 +81,10 @@ impl<'a> Drawable for DrawableText<'a> {
let mut indices = 0..0;
if let Some(RenderResourceId::Buffer(quad_index_buffer)) = render_resource_context
.get_asset_resource(&bevy_sprite::QUAD_HANDLE, mesh::INDEX_BUFFER_ASSET_INDEX)
.get_asset_resource(
&bevy_sprite::QUAD_HANDLE.typed::<Mesh>(),
mesh::INDEX_BUFFER_ASSET_INDEX,
)
{
draw.set_index_buffer(quad_index_buffer, 0);
if let Some(buffer_info) = render_resource_context.get_buffer_info(quad_index_buffer) {

View file

@ -1,10 +1,10 @@
use bevy_ecs::{Entity, MapEntities};
use bevy_reflect::{Reflect, ReflectMapEntities};
use bevy_reflect::{Reflect, ReflectComponent, ReflectMapEntities};
use smallvec::SmallVec;
use std::ops::Deref;
#[derive(Default, Clone, Debug, Reflect)]
#[reflect(MapEntities)]
#[reflect(Component, MapEntities)]
pub struct Children(pub(crate) SmallVec<[Entity; 8]>);
impl MapEntities for Children {

View file

@ -1,9 +1,10 @@
use super::Transform;
use bevy_math::{Mat3, Mat4, Quat, Vec3};
use bevy_reflect::Reflect;
use bevy_reflect::{Reflect, ReflectComponent};
use std::ops::Mul;
#[derive(Debug, PartialEq, Clone, Copy, Reflect)]
#[reflect(Component)]
pub struct GlobalTransform {
pub translation: Vec3,
pub rotation: Quat,

View file

@ -1,9 +1,9 @@
use bevy_ecs::{Entity, FromResources, MapEntities};
use bevy_reflect::{Reflect, ReflectMapEntities};
use bevy_reflect::{Reflect, ReflectComponent, ReflectMapEntities};
use std::ops::{Deref, DerefMut};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Reflect)]
#[reflect(MapEntities)]
#[reflect(Component, MapEntities)]
pub struct Parent(pub Entity);
// TODO: We need to impl either FromResources or Default so Parent can be registered as Properties.
@ -41,7 +41,7 @@ impl DerefMut for Parent {
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Reflect)]
#[reflect(MapEntities)]
#[reflect(Component, MapEntities)]
pub struct PreviousParent(pub(crate) Entity);
impl MapEntities for PreviousParent {

View file

@ -31,9 +31,9 @@ pub struct NodeBundle {
impl Default for NodeBundle {
fn default() -> Self {
NodeBundle {
mesh: QUAD_HANDLE,
mesh: QUAD_HANDLE.typed(),
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
UI_PIPELINE_HANDLE,
UI_PIPELINE_HANDLE.typed(),
)]),
node: Default::default(),
style: Default::default(),
@ -62,9 +62,9 @@ pub struct ImageBundle {
impl Default for ImageBundle {
fn default() -> Self {
ImageBundle {
mesh: QUAD_HANDLE,
mesh: QUAD_HANDLE.typed(),
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
UI_PIPELINE_HANDLE,
UI_PIPELINE_HANDLE.typed(),
)]),
node: Default::default(),
image: Default::default(),
@ -127,9 +127,9 @@ impl Default for ButtonBundle {
fn default() -> Self {
ButtonBundle {
button: Button,
mesh: QUAD_HANDLE,
mesh: QUAD_HANDLE.typed(),
render_pipelines: RenderPipelines::from_pipelines(vec![RenderPipeline::new(
UI_PIPELINE_HANDLE,
UI_PIPELINE_HANDLE.typed(),
)]),
interaction: Default::default(),
focus_policy: Default::default(),

View file

@ -1,5 +1,5 @@
use crate::Node;
use bevy_asset::{Assets, Handle};
use bevy_asset::{Assets, HandleUntyped};
use bevy_ecs::Resources;
use bevy_reflect::TypeUuid;
use bevy_render::{
@ -18,8 +18,8 @@ use bevy_render::{
texture::TextureFormat,
};
pub const UI_PIPELINE_HANDLE: Handle<PipelineDescriptor> =
Handle::weak_from_u64(PipelineDescriptor::TYPE_UUID, 3234320022263993878);
pub const UI_PIPELINE_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(PipelineDescriptor::TYPE_UUID, 3234320022263993878);
pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
PipelineDescriptor {