Skip to content

Commit

Permalink
Enable Constructing ReflectComponent/Resource
Browse files Browse the repository at this point in the history
  • Loading branch information
zicklag committed Oct 14, 2022
1 parent 92ba622 commit be21e55
Showing 1 changed file with 150 additions and 0 deletions.
150 changes: 150 additions & 0 deletions crates/bevy_ecs/src/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,61 @@ pub struct ReflectComponent {
copy: fn(&World, &mut World, Entity, Entity),
}

/// The raw function pointers needed to make up a [`ReflectComponent`].
///
/// This is used when creating custom implementations of [`ReflectComponent`] with
/// [`ReflectComponent::new()`].
///
/// > **Note:**
/// > Creating custom implementations of [`ReflectComponent`] is an advanced feature that most users
/// > will not need.
/// > Usually you will obtain a [`ReflectComponent`] for a type by retrieving it from the
/// > [`TypeRegistry`][bevy_reflect::TypeRegistry].
///
/// Creating a custom [`ReflectComponent`] may be useful if you need to create new component types
/// at runtime, for example, for scripting implementations.
///
/// By creating a custom [`ReflectComponent`] and inserting it into a type's
/// [`TypeRegistration`][bevy_reflect::TypeRegistration],
/// you can modify the way that reflected components of that type will be inserted into the Bevy
/// world.
pub struct ReflectComponentFns {
/// Function pointer implementing [`ReflectComponent::insert()`].
pub insert: fn(&mut World, Entity, &dyn Reflect),
/// Function pointer implementing [`ReflectComponent::apply()`].
pub apply: fn(&mut World, Entity, &dyn Reflect),
/// Function pointer implementing [`ReflectComponent::apply_or_insert()`].
pub apply_or_insert: fn(&mut World, Entity, &dyn Reflect),
/// Function pointer implementing [`ReflectComponent::remove()`].
pub remove: fn(&mut World, Entity),
/// Function pointer implementing [`ReflectComponent::reflect()`].
pub reflect: fn(&World, Entity) -> Option<&dyn Reflect>,
/// Function pointer implementing [`ReflectComponent::reflect_mut()`].
pub reflect_mut: unsafe fn(&World, Entity) -> Option<Mut<dyn Reflect>>,
/// Function pointer implementing [`ReflectComponent::copy()`].
pub copy: fn(&World, &mut World, Entity, Entity),
}

impl ReflectComponentFns {
/// Get the default set of [`ReflectComponentFns`] for a specific component type using its
/// [`FromType`] 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 + FromWorld>() -> Self {
let c = <ReflectComponent as FromType<T>>::from_type();
Self {
insert: c.insert,
apply: c.apply,
apply_or_insert: c.apply_or_insert,
remove: c.remove,
reflect: c.reflect,
reflect_mut: c.reflect_mut,
copy: c.copy,
}
}
}

impl ReflectComponent {
/// Insert a reflected [`Component`] into the entity like [`insert()`](crate::world::EntityMut::insert).
///
Expand Down Expand Up @@ -112,6 +167,26 @@ impl ReflectComponent {
destination_entity,
);
}

/// Create a custom implementation of [`ReflectComponent`].
///
/// This is an advanced feature,
/// useful for scripting implementations,
/// that should not be used by most users
/// unless you know what you are doing.
///
/// See [`ReflectComponentFns`] for more information.
pub fn new(fns: ReflectComponentFns) -> Self {
Self {
insert: fns.insert,
apply: fns.apply,
apply_or_insert: fns.apply_or_insert,
remove: fns.remove,
reflect: fns.reflect,
reflect_mut: fns.reflect_mut,
copy: fns.copy,
}
}
}

impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
Expand Down Expand Up @@ -184,6 +259,61 @@ pub struct ReflectResource {
copy: fn(&World, &mut World),
}

/// The raw function pointers needed to make up a [`ReflectResource`].
///
/// This is used when creating custom implementations of [`ReflectResource`] with
/// [`ReflectResource::new()`].
///
/// > **Note:**
/// > Creating custom implementations of [`ReflectResource`] is an advanced feature that most users
/// > will not need.
/// > Usually you will obtain a [`ReflectResource`] for a type by retrieving it from the
/// > [`TypeRegistry`][bevy_reflect::TypeRegistry].
///
/// Creating a custom [`ReflectResource`] may be useful if you need to create new resource types at
/// runtime, for example, for scripting implementations.
///
/// By creating a custom [`ReflectResource`] and inserting it into a type's
/// [`TypeRegistration`][bevy_reflect::TypeRegistration],
/// you can modify the way that reflected resources of that type will be inserted into the bevy
/// world.
pub struct ReflectResourceFns {
/// Function pointer implementing [`ReflectResource::insert()`].
pub insert: fn(&mut World, &dyn Reflect),
/// Function pointer implementing [`ReflectResource::apply()`].
pub apply: fn(&mut World, &dyn Reflect),
/// Function pointer implementing [`ReflectResource::apply_or_insert()`].
pub apply_or_insert: fn(&mut World, &dyn Reflect),
/// Function pointer implementing [`ReflectResource::remove()`].
pub remove: fn(&mut World),
/// Function pointer implementing [`ReflectResource::reflect()`].
pub reflect: fn(&World) -> Option<&dyn Reflect>,
/// Function pointer implementing [`ReflectResource::reflect_unchecked_mut()`].
pub reflect_unchecked_mut: unsafe fn(&World) -> Option<Mut<dyn Reflect>>,
/// Function pointer implementing [`ReflectResource::copy()`].
pub copy: fn(&World, &mut World),
}

impl ReflectResourceFns {
/// Get the default set of [`ReflectResourceFns`] for a specific resource type using its
/// [`FromType`] 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 + Reflect + FromWorld>() -> Self {
let r = <ReflectResource as FromType<T>>::from_type();
Self {
insert: r.insert,
apply: r.apply,
apply_or_insert: r.apply_or_insert,
remove: r.remove,
reflect: r.reflect,
reflect_unchecked_mut: r.reflect_unchecked_mut,
copy: r.copy,
}
}
}

impl ReflectResource {
/// Insert a reflected [`Resource`] into the world like [`insert()`](World::insert_resource).
pub fn insert(&self, world: &mut World, resource: &dyn Reflect) {
Expand Down Expand Up @@ -242,6 +372,26 @@ impl ReflectResource {
pub fn copy(&self, source_world: &World, destination_world: &mut World) {
(self.copy)(source_world, destination_world);
}

/// Create a custom implementation of [`ReflectResource`].
///
/// This is an advanced feature,
/// useful for scripting implementations,
/// that should not be used by most users
/// unless you know what you are doing.
///
/// See [`ReflectResourceFns`] for more information.
pub fn new(&self, fns: ReflectResourceFns) -> Self {
Self {
insert: fns.insert,
apply: fns.apply,
apply_or_insert: fns.apply_or_insert,
remove: fns.remove,
reflect: fns.reflect,
reflect_unchecked_mut: fns.reflect_unchecked_mut,
copy: fns.copy,
}
}
}

impl<C: Resource + Reflect + FromWorld> FromType<C> for ReflectResource {
Expand Down

0 comments on commit be21e55

Please sign in to comment.