Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bevy_reflect: Allow parameters to be passed to type data #13723

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ impl App {
#[cfg(feature = "bevy_reflect")]
pub fn register_type_data<
T: bevy_reflect::Reflect + bevy_reflect::TypePath,
D: bevy_reflect::TypeData + bevy_reflect::FromType<T>,
D: bevy_reflect::CreateTypeData<T>,
>(
&mut self,
) -> &mut Self {
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_app/src/sub_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl SubApp {
#[cfg(feature = "bevy_reflect")]
pub fn register_type_data<
T: bevy_reflect::Reflect + bevy_reflect::TypePath,
D: bevy_reflect::TypeData + bevy_reflect::FromType<T>,
D: bevy_reflect::CreateTypeData<T>,
>(
&mut self,
) -> &mut Self {
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_asset/src/reflect.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::any::{Any, TypeId};

use bevy_ecs::world::{unsafe_world_cell::UnsafeWorldCell, World};
use bevy_reflect::{FromReflect, FromType, Reflect};
use bevy_reflect::{CreateTypeData, FromReflect, Reflect};

use crate::{Asset, Assets, Handle, UntypedAssetId, UntypedHandle};

Expand Down Expand Up @@ -124,8 +124,8 @@ impl ReflectAsset {
}
}

impl<A: Asset + FromReflect> FromType<A> for ReflectAsset {
fn from_type() -> Self {
impl<A: Asset + FromReflect> CreateTypeData<A> for ReflectAsset {
fn create_type_data(_input: ()) -> Self {
ReflectAsset {
handle_type_id: TypeId::of::<Handle<A>>(),
assets_resource_type_id: TypeId::of::<Assets<A>>(),
Expand Down Expand Up @@ -220,8 +220,8 @@ impl ReflectHandle {
}
}

impl<A: Asset> FromType<Handle<A>> for ReflectHandle {
fn from_type() -> Self {
impl<A: Asset> CreateTypeData<Handle<A>> for ReflectHandle {
fn create_type_data(_input: ()) -> Self {
ReflectHandle {
asset_type_id: TypeId::of::<A>(),
downcast_handle_untyped: |handle: &dyn Any| {
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/change_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ impl<'w, T> From<Mut<'w, T>> for MutUntyped<'w> {
mod tests {
use bevy_ecs_macros::Resource;
use bevy_ptr::PtrMut;
use bevy_reflect::{FromType, ReflectFromPtr};
use bevy_reflect::{CreateTypeData, ReflectFromPtr};
use std::ops::{Deref, DerefMut};

use crate::{
Expand Down Expand Up @@ -1326,7 +1326,7 @@ mod tests {
ticks,
};

let reflect_from_ptr = <ReflectFromPtr as FromType<i32>>::from_type();
let reflect_from_ptr = <ReflectFromPtr as CreateTypeData<i32>>::create_type_data(());

let mut new = value.map_unchanged(|ptr| {
// SAFETY: The underlying type of `ptr` matches `reflect_from_ptr`.
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_ecs/src/reflect/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
prelude::Bundle,
world::{EntityMut, EntityWorldMut},
};
use bevy_reflect::{FromReflect, FromType, Reflect, ReflectRef, TypeRegistry};
use bevy_reflect::{CreateTypeData, FromReflect, Reflect, ReflectRef, TypeRegistry};

use super::{from_reflect_with_fallback, ReflectComponent};

Expand Down Expand Up @@ -38,12 +38,12 @@ pub struct ReflectBundleFns {

impl ReflectBundleFns {
/// Get the default set of [`ReflectBundleFns`] for a specific bundle type using its
/// [`FromType`] implementation.
/// [`CreateTypeData`] implementation.
///
/// This is useful if you want to start with the default implementation before overriding some
/// of the functions to create a custom implementation.
pub fn new<T: Bundle + Reflect + FromReflect>() -> Self {
<ReflectBundle as FromType<T>>::from_type().0
<ReflectBundle as CreateTypeData<T>>::create_type_data(()).0
}
}

Expand Down Expand Up @@ -122,8 +122,8 @@ impl ReflectBundle {
}
}

impl<B: Bundle + Reflect> FromType<B> for ReflectBundle {
fn from_type() -> Self {
impl<B: Bundle + Reflect> CreateTypeData<B> for ReflectBundle {
fn create_type_data(_input: ()) -> Self {
ReflectBundle(ReflectBundleFns {
insert: |entity, reflected_bundle, registry| {
let bundle = entity.world_scope(|world| {
Expand Down
20 changes: 10 additions & 10 deletions crates/bevy_ecs/src/reflect/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
//! [`get_type_registration`] method (see the relevant code[^1]).
//!
//! ```
//! # use bevy_reflect::{FromType, Reflect};
//! # use bevy_reflect::{CreateTypeData, Reflect};
//! # use bevy_ecs::prelude::{ReflectComponent, Component};
//! # #[derive(Default, Reflect, Component)]
//! # struct A;
//! # impl A {
//! # fn foo() {
//! # let mut registration = bevy_reflect::TypeRegistration::of::<A>();
//! registration.insert::<ReflectComponent>(FromType::<Self>::from_type());
//! registration.insert::<ReflectComponent>(CreateTypeData::<Self>::create_type_data(()));
//! # }
//! # }
//! ```
Expand All @@ -32,10 +32,10 @@
//! The user can access the `ReflectComponent` for type `T` through the type registry,
//! as per the `trait_reflection.rs` example.
//!
//! The `FromType::<Self>::from_type()` in the previous line calls the `FromType<C>`
//! implementation of `ReflectComponent`.
//! The `CreateTypeData::<Self>::create_type_data(())` in the previous line calls the
//! `CreateTypeData<C>` implementation of `ReflectComponent`.
//!
//! The `FromType<C>` impl creates a function per field of [`ReflectComponentFns`].
//! The `CreateTypeData<C>` impl creates a function per field of [`ReflectComponentFns`].
//! In those functions, we call generic methods on [`World`] and [`EntityWorldMut`].
//!
//! The result is a `ReflectComponent` completely independent of `C`, yet capable
Expand Down Expand Up @@ -67,7 +67,7 @@ use crate::{
FilteredEntityRef, World,
},
};
use bevy_reflect::{FromReflect, FromType, Reflect, TypeRegistry};
use bevy_reflect::{CreateTypeData, FromReflect, Reflect, TypeRegistry};

/// A struct used to operate on reflected [`Component`] trait of a type.
///
Expand Down Expand Up @@ -123,12 +123,12 @@ pub struct ReflectComponentFns {

impl ReflectComponentFns {
/// Get the default set of [`ReflectComponentFns`] for a specific component type using its
/// [`FromType`] implementation.
/// [`CreateTypeData`] implementation.
///
/// This is useful if you want to start with the default implementation before overriding some
/// of the functions to create a custom implementation.
pub fn new<T: Component + Reflect + FromReflect>() -> Self {
<ReflectComponent as FromType<T>>::from_type().0
<ReflectComponent as CreateTypeData<T>>::create_type_data(()).0
}
}

Expand Down Expand Up @@ -256,8 +256,8 @@ impl ReflectComponent {
}
}

impl<C: Component + Reflect> FromType<C> for ReflectComponent {
fn from_type() -> Self {
impl<C: Component + Reflect> CreateTypeData<C> for ReflectComponent {
fn create_type_data(_input: ()) -> Self {
ReflectComponent(ReflectComponentFns {
insert: |entity, reflected_component, registry| {
let component = entity.world_scope(|world| {
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/reflect/entity_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub trait ReflectCommandExt {
///
/// # use bevy_ecs::prelude::*;
/// # use bevy_ecs::reflect::ReflectCommandExt;
/// # use bevy_reflect::{FromReflect, FromType, Reflect, TypeRegistry};
/// # use bevy_reflect::{FromReflect, CreateTypeData, Reflect, TypeRegistry};
/// // A resource that can hold any component that implements reflect as a boxed reflect component
/// #[derive(Resource)]
/// struct Prefab{
Expand Down Expand Up @@ -105,7 +105,7 @@ pub trait ReflectCommandExt {
///
/// # use bevy_ecs::prelude::*;
/// # use bevy_ecs::reflect::ReflectCommandExt;
/// # use bevy_reflect::{FromReflect, FromType, Reflect, TypeRegistry};
/// # use bevy_reflect::{FromReflect, CreateTypeData, Reflect, TypeRegistry};
///
/// // A resource that can hold any component that implements reflect as a boxed reflect component
/// #[derive(Resource)]
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_ecs/src/reflect/from_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//!
//! Same as [`super::component`], but for [`FromWorld`].

use bevy_reflect::{FromType, Reflect};
use bevy_reflect::{CreateTypeData, Reflect};

use crate::world::{FromWorld, World};

Expand All @@ -26,12 +26,12 @@ pub struct ReflectFromWorldFns {

impl ReflectFromWorldFns {
/// Get the default set of [`ReflectFromWorldFns`] for a specific type using its
/// [`FromType`] implementation.
/// [`CreateTypeData`] implementation.
///
/// This is useful if you want to start with the default implementation before overriding some
/// of the functions to create a custom implementation.
pub fn new<T: Reflect + FromWorld>() -> Self {
<ReflectFromWorld as FromType<T>>::from_type().0
<ReflectFromWorld as CreateTypeData<T>>::create_type_data(()).0
}
}

Expand Down Expand Up @@ -77,8 +77,8 @@ impl ReflectFromWorld {
}
}

impl<B: Reflect + FromWorld> FromType<B> for ReflectFromWorld {
fn from_type() -> Self {
impl<B: Reflect + FromWorld> CreateTypeData<B> for ReflectFromWorld {
fn create_type_data(_input: ()) -> Self {
ReflectFromWorld(ReflectFromWorldFns {
from_world: |world| Box::new(B::from_world(world)),
})
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_ecs/src/reflect/map_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
entity::{Entity, EntityHashMap, MapEntities, SceneEntityMapper},
world::World,
};
use bevy_reflect::FromType;
use bevy_reflect::CreateTypeData;

/// For a specific type of component, this maps any fields with values of type [`Entity`] to a new world.
/// Since a given `Entity` ID is only valid for the world it came from, when performing deserialization
Expand Down Expand Up @@ -48,8 +48,8 @@ impl ReflectMapEntities {
}
}

impl<C: Component + MapEntities> FromType<C> for ReflectMapEntities {
fn from_type() -> Self {
impl<C: Component + MapEntities> CreateTypeData<C> for ReflectMapEntities {
fn create_type_data(_input: ()) -> Self {
ReflectMapEntities {
map_entities: |world, entity_mapper, entities| {
for &entity in entities {
Expand Down Expand Up @@ -93,8 +93,8 @@ impl ReflectMapEntitiesResource {
}
}

impl<R: crate::system::Resource + MapEntities> FromType<R> for ReflectMapEntitiesResource {
fn from_type() -> Self {
impl<R: crate::system::Resource + MapEntities> CreateTypeData<R> for ReflectMapEntitiesResource {
fn create_type_data(_input: ()) -> Self {
ReflectMapEntitiesResource {
map_entities: |world, entity_mapper| {
if let Some(mut resource) = world.get_resource_mut::<R>() {
Expand Down
10 changes: 5 additions & 5 deletions crates/bevy_ecs/src/reflect/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
system::Resource,
world::{unsafe_world_cell::UnsafeWorldCell, World},
};
use bevy_reflect::{FromReflect, FromType, Reflect, TypeRegistry};
use bevy_reflect::{CreateTypeData, FromReflect, Reflect, TypeRegistry};

use super::from_reflect_with_fallback;

Expand Down Expand Up @@ -63,12 +63,12 @@ pub struct ReflectResourceFns {

impl ReflectResourceFns {
/// Get the default set of [`ReflectResourceFns`] for a specific resource type using its
/// [`FromType`] implementation.
/// [`CreateTypeData`] implementation.
///
/// This is useful if you want to start with the default implementation before overriding some
/// of the functions to create a custom implementation.
pub fn new<T: Resource + FromReflect>() -> Self {
<ReflectResource as FromType<T>>::from_type().0
<ReflectResource as CreateTypeData<T>>::create_type_data(()).0
}
}

Expand Down Expand Up @@ -176,8 +176,8 @@ impl ReflectResource {
}
}

impl<R: Resource + FromReflect> FromType<R> for ReflectResource {
fn from_type() -> Self {
impl<R: Resource + FromReflect> CreateTypeData<R> for ReflectResource {
fn create_type_data(_input: ()) -> Self {
ReflectResource(ReflectResourceFns {
insert: |world, reflected_resource, registry| {
let resource = from_reflect_with_fallback::<R>(reflected_resource, world, registry);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use bevy_reflect::{FromType, Reflect};
use bevy_reflect::{CreateTypeData, Reflect};
use std::marker::PhantomData;

#[derive(Clone)]
struct ReflectMyTrait;

impl<T> FromType<T> for ReflectMyTrait {
fn from_type() -> Self {
impl<T> CreateTypeData<T> for ReflectMyTrait {
fn create_type_data(_: ()) -> Self {
Self
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//@check-pass
use bevy_reflect::{FromType, Reflect};
use bevy_reflect::{CreateTypeData, Reflect};
use std::marker::PhantomData;

#[derive(Clone)]
struct ReflectMyTrait;

impl<T> FromType<T> for ReflectMyTrait {
fn from_type() -> Self {
impl<T> CreateTypeData<T> for ReflectMyTrait {
fn create_type_data(_: ()) -> Self {
Self
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//@no-rustfix
use bevy_reflect::{CreateTypeData, Reflect};

#[derive(Clone)]
struct ReflectMyTrait;

impl<T> CreateTypeData<T, f32> for ReflectMyTrait {
fn create_type_data(_: f32) -> Self {
todo!()
}
}

#[derive(Reflect)]
#[reflect(MyTrait)]
//~^ ERROR: mismatched types
struct RequiredArgs;

#[derive(Reflect)]
#[reflect(MyTrait(123))]
//~^ ERROR: mismatched types
struct WrongArgs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//@check-pass
use bevy_reflect::{CreateTypeData, Reflect};

#[derive(Clone)]
struct ReflectMyTrait;

impl<T> CreateTypeData<T> for ReflectMyTrait {
fn create_type_data(_: ()) -> Self {
todo!()
}
}

impl<T> CreateTypeData<T, i32> for ReflectMyTrait {
fn create_type_data(_: i32) -> Self {
todo!()
}
}

impl<T> CreateTypeData<T, (i32, i32)> for ReflectMyTrait {
fn create_type_data(_: (i32, i32)) -> Self {
todo!()
}
}

#[derive(Reflect)]
#[reflect(MyTrait)]
struct NoArgs;

#[derive(Reflect)]
#[reflect(MyTrait(1 + 2))]
struct OneArg;

#[derive(Reflect)]
#[reflect(MyTrait(1 + 2, 3 + 4))]
struct TwoArgs;
Loading