Move AppTypeRegistry to bevy_ecs (#8901)

# Objective

- Use `AppTypeRegistry` on API defined in `bevy_ecs`
(https://github.com/bevyengine/bevy/pull/8895#discussion_r1234748418)

A lot of the API on `Reflect` depends on a registry. When it comes to
the ECS. We should use `AppTypeRegistry` in the general case.

This is however impossible in `bevy_ecs`, since `AppTypeRegistry` is
defined in `bevy_app`.

## Solution

- Move `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`
- Still add the resource in the `App` plugin, since bevy_ecs itself
doesn't know of plugins

Note that `bevy_ecs` is a dependency of `bevy_app`, so nothing
revolutionary happens.

## Alternative

- Define the API as a trait in `bevy_app` over `bevy_ecs`. (though this
prevents us from using bevy_ecs internals)
- Do not rely on `AppTypeRegistry` for the API in question, requring
users to extract themselves the resource and pass it to the API methods.

---

## Changelog

- Moved `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`

## Migration Guide

- If you were **not** using a `prelude::*` to import `AppTypeRegistry`,
you should update your imports:

```diff
- use bevy::app::AppTypeRegistry;
+ use bevy::ecs::reflect::AppTypeRegistry
```
This commit is contained in:
Nicola Papale 2023-06-21 19:25:01 +02:00 committed by GitHub
parent e529d8c1b1
commit 0294bb191d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 43 additions and 29 deletions

View File

@ -25,11 +25,6 @@ bevy_utils::define_label!(
AppLabelId, AppLabelId,
); );
/// The [`Resource`] that stores the [`App`]'s [`TypeRegistry`](bevy_reflect::TypeRegistry).
#[cfg(feature = "bevy_reflect")]
#[derive(Resource, Clone, bevy_derive::Deref, bevy_derive::DerefMut, Default)]
pub struct AppTypeRegistry(pub bevy_reflect::TypeRegistryArc);
pub(crate) enum AppError { pub(crate) enum AppError {
DuplicatePlugin { plugin_name: String }, DuplicatePlugin { plugin_name: String },
} }

View File

@ -21,9 +21,6 @@ pub use schedule_runner::*;
#[allow(missing_docs)] #[allow(missing_docs)]
pub mod prelude { pub mod prelude {
#[cfg(feature = "bevy_reflect")]
#[doc(hidden)]
pub use crate::AppTypeRegistry;
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
app::App, app::App,

View File

@ -2,8 +2,9 @@ use crate::{
update_asset_storage_system, Asset, AssetEvents, AssetLoader, AssetServer, Handle, HandleId, update_asset_storage_system, Asset, AssetEvents, AssetLoader, AssetServer, Handle, HandleId,
LoadAssets, RefChange, ReflectAsset, ReflectHandle, LoadAssets, RefChange, ReflectAsset, ReflectHandle,
}; };
use bevy_app::{App, AppTypeRegistry}; use bevy_app::App;
use bevy_ecs::prelude::*; use bevy_ecs::prelude::*;
use bevy_ecs::reflect::AppTypeRegistry;
use bevy_reflect::{FromReflect, GetTypeRegistration, Reflect}; use bevy_reflect::{FromReflect, GetTypeRegistration, Reflect};
use bevy_utils::HashMap; use bevy_utils::HashMap;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;

View File

@ -253,7 +253,8 @@ impl<A: Asset> FromType<Handle<A>> for ReflectHandle {
mod tests { mod tests {
use std::any::TypeId; use std::any::TypeId;
use bevy_app::{App, AppTypeRegistry}; use bevy_app::App;
use bevy_ecs::reflect::AppTypeRegistry;
use bevy_reflect::{FromReflect, Reflect, ReflectMut, TypeUuid}; use bevy_reflect::{FromReflect, Reflect, ReflectMut, TypeUuid};
use crate::{AddAsset, AssetPlugin, HandleUntyped, ReflectAsset}; use crate::{AddAsset, AssetPlugin, HandleUntyped, ReflectAsset};

View File

@ -29,7 +29,7 @@ pub use bevy_ptr as ptr;
pub mod prelude { pub mod prelude {
#[doc(hidden)] #[doc(hidden)]
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
pub use crate::reflect::{ReflectComponent, ReflectResource}; pub use crate::reflect::{AppTypeRegistry, ReflectComponent, ReflectResource};
#[doc(hidden)] #[doc(hidden)]
pub use crate::{ pub use crate::{
bundle::Bundle, bundle::Bundle,

View File

@ -1,8 +1,12 @@
//! Types that enable reflection support. //! Types that enable reflection support.
use crate::entity::Entity; use std::ops::{Deref, DerefMut};
use crate as bevy_ecs;
use crate::{entity::Entity, system::Resource};
use bevy_reflect::{ use bevy_reflect::{
impl_from_reflect_value, impl_reflect_value, ReflectDeserialize, ReflectSerialize, impl_from_reflect_value, impl_reflect_value, ReflectDeserialize, ReflectSerialize,
TypeRegistryArc,
}; };
mod component; mod component;
@ -13,5 +17,26 @@ pub use component::{ReflectComponent, ReflectComponentFns};
pub use map_entities::ReflectMapEntities; pub use map_entities::ReflectMapEntities;
pub use resource::{ReflectResource, ReflectResourceFns}; pub use resource::{ReflectResource, ReflectResourceFns};
/// A [`Resource`] storing [`TypeRegistry`](bevy_reflect::TypeRegistry) for
/// type registrations relevant to a whole app.
#[derive(Resource, Clone, Default)]
pub struct AppTypeRegistry(pub TypeRegistryArc);
impl Deref for AppTypeRegistry {
type Target = TypeRegistryArc;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for AppTypeRegistry {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl_reflect_value!((in bevy_ecs) Entity(Hash, PartialEq, Serialize, Deserialize)); impl_reflect_value!((in bevy_ecs) Entity(Hash, PartialEq, Serialize, Deserialize));
impl_from_reflect_value!(Entity); impl_from_reflect_value!(Entity);

View File

@ -2,10 +2,9 @@ use std::any::TypeId;
use crate::{DynamicSceneBuilder, Scene, SceneSpawnError}; use crate::{DynamicSceneBuilder, Scene, SceneSpawnError};
use anyhow::Result; use anyhow::Result;
use bevy_app::AppTypeRegistry;
use bevy_ecs::{ use bevy_ecs::{
entity::{Entity, EntityMap}, entity::{Entity, EntityMap},
reflect::{ReflectComponent, ReflectMapEntities}, reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities},
world::World, world::World,
}; };
use bevy_reflect::{Reflect, TypePath, TypeRegistryArc, TypeUuid}; use bevy_reflect::{Reflect, TypePath, TypeRegistryArc, TypeUuid};
@ -185,8 +184,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use bevy_app::AppTypeRegistry; use bevy_ecs::{entity::EntityMap, reflect::AppTypeRegistry, system::Command, world::World};
use bevy_ecs::{entity::EntityMap, system::Command, world::World};
use bevy_hierarchy::{AddChild, Parent}; use bevy_hierarchy::{AddChild, Parent};
use crate::dynamic_scene_builder::DynamicSceneBuilder; use crate::dynamic_scene_builder::DynamicSceneBuilder;

View File

@ -1,9 +1,8 @@
use crate::{DynamicEntity, DynamicScene}; use crate::{DynamicEntity, DynamicScene};
use bevy_app::AppTypeRegistry;
use bevy_ecs::component::ComponentId; use bevy_ecs::component::ComponentId;
use bevy_ecs::{ use bevy_ecs::{
prelude::Entity, prelude::Entity,
reflect::{ReflectComponent, ReflectResource}, reflect::{AppTypeRegistry, ReflectComponent, ReflectResource},
world::World, world::World,
}; };
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
@ -21,7 +20,7 @@ use std::collections::BTreeMap;
/// # Example /// # Example
/// ``` /// ```
/// # use bevy_scene::DynamicSceneBuilder; /// # use bevy_scene::DynamicSceneBuilder;
/// # use bevy_app::AppTypeRegistry; /// # use bevy_ecs::reflect::AppTypeRegistry;
/// # use bevy_ecs::{ /// # use bevy_ecs::{
/// # component::Component, prelude::Entity, query::With, reflect::ReflectComponent, world::World, /// # component::Component, prelude::Entity, query::With, reflect::ReflectComponent, world::World,
/// # }; /// # };
@ -101,7 +100,7 @@ impl<'w> DynamicSceneBuilder<'w> {
/// Extracting entities can be used to extract entities from a query: /// Extracting entities can be used to extract entities from a query:
/// ``` /// ```
/// # use bevy_scene::DynamicSceneBuilder; /// # use bevy_scene::DynamicSceneBuilder;
/// # use bevy_app::AppTypeRegistry; /// # use bevy_ecs::reflect::AppTypeRegistry;
/// # use bevy_ecs::{ /// # use bevy_ecs::{
/// # component::Component, prelude::Entity, query::With, reflect::ReflectComponent, world::World, /// # component::Component, prelude::Entity, query::With, reflect::ReflectComponent, world::World,
/// # }; /// # };
@ -162,7 +161,7 @@ impl<'w> DynamicSceneBuilder<'w> {
/// Re-extracting a resource that was already extracted will have no effect. /// Re-extracting a resource that was already extracted will have no effect.
/// ``` /// ```
/// # use bevy_scene::DynamicSceneBuilder; /// # use bevy_scene::DynamicSceneBuilder;
/// # use bevy_app::AppTypeRegistry; /// # use bevy_ecs::reflect::AppTypeRegistry;
/// # use bevy_ecs::prelude::{ReflectResource, Resource, World}; /// # use bevy_ecs::prelude::{ReflectResource, Resource, World};
/// # use bevy_reflect::Reflect; /// # use bevy_reflect::Reflect;
/// #[derive(Resource, Default, Reflect)] /// #[derive(Resource, Default, Reflect)]
@ -204,10 +203,10 @@ impl<'w> DynamicSceneBuilder<'w> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use bevy_app::AppTypeRegistry;
use bevy_ecs::{ use bevy_ecs::{
component::Component, prelude::Entity, prelude::Resource, query::With, component::Component, prelude::Entity, prelude::Resource, query::With,
reflect::ReflectComponent, reflect::ReflectResource, world::World, reflect::AppTypeRegistry, reflect::ReflectComponent, reflect::ReflectResource,
world::World,
}; };
use bevy_reflect::Reflect; use bevy_reflect::Reflect;

View File

@ -1,7 +1,6 @@
use bevy_app::AppTypeRegistry;
use bevy_ecs::{ use bevy_ecs::{
entity::EntityMap, entity::EntityMap,
reflect::{ReflectComponent, ReflectMapEntities, ReflectResource}, reflect::{AppTypeRegistry, ReflectComponent, ReflectMapEntities, ReflectResource},
world::World, world::World,
}; };
use bevy_reflect::{TypePath, TypeUuid}; use bevy_reflect::{TypePath, TypeUuid};

View File

@ -1,8 +1,8 @@
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use crate::serde::SceneDeserializer; use crate::serde::SceneDeserializer;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use bevy_app::AppTypeRegistry;
use bevy_asset::{AssetLoader, LoadContext, LoadedAsset}; use bevy_asset::{AssetLoader, LoadContext, LoadedAsset};
use bevy_ecs::reflect::AppTypeRegistry;
use bevy_ecs::world::{FromWorld, World}; use bevy_ecs::world::{FromWorld, World};
use bevy_reflect::TypeRegistryArc; use bevy_reflect::TypeRegistryArc;
use bevy_utils::BoxedFuture; use bevy_utils::BoxedFuture;

View File

@ -1,9 +1,9 @@
use crate::{DynamicScene, Scene}; use crate::{DynamicScene, Scene};
use bevy_app::AppTypeRegistry;
use bevy_asset::{AssetEvent, Assets, Handle}; use bevy_asset::{AssetEvent, Assets, Handle};
use bevy_ecs::{ use bevy_ecs::{
entity::{Entity, EntityMap}, entity::{Entity, EntityMap},
event::{Events, ManualEventReader}, event::{Events, ManualEventReader},
reflect::AppTypeRegistry,
system::{Command, Resource}, system::{Command, Resource},
world::{Mut, World}, world::{Mut, World},
}; };

View File

@ -424,11 +424,10 @@ impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> {
mod tests { mod tests {
use crate::serde::{SceneDeserializer, SceneSerializer}; use crate::serde::{SceneDeserializer, SceneSerializer};
use crate::{DynamicScene, DynamicSceneBuilder}; use crate::{DynamicScene, DynamicSceneBuilder};
use bevy_app::AppTypeRegistry;
use bevy_ecs::entity::{Entity, EntityMap, EntityMapper, MapEntities}; use bevy_ecs::entity::{Entity, EntityMap, EntityMapper, MapEntities};
use bevy_ecs::prelude::{Component, ReflectComponent, ReflectResource, Resource, World}; use bevy_ecs::prelude::{Component, ReflectComponent, ReflectResource, Resource, World};
use bevy_ecs::query::{With, Without}; use bevy_ecs::query::{With, Without};
use bevy_ecs::reflect::ReflectMapEntities; use bevy_ecs::reflect::{AppTypeRegistry, ReflectMapEntities};
use bevy_ecs::world::FromWorld; use bevy_ecs::world::FromWorld;
use bevy_reflect::{FromReflect, Reflect, ReflectSerialize}; use bevy_reflect::{FromReflect, Reflect, ReflectSerialize};
use bincode::Options; use bincode::Options;