Allow registering of resources via ReflectResource / ReflectComponent (#15496)
# Objective - Resolves #15453 ## Solution - Added new `World::resource_id` and `World::register_resource` methods to support this feature - Added new `ReflectResource::register_resource` method, and new pointer to this new function - Added new `ReflectComponent::register_component` ## Testing - Tested this locally, but couldn't test the entire crate locally, just this new feature, expect that CI will do the rest of the work. --- ## Showcase ```rs #[derive(Component, Reflect)] #[reflect(Component)] struct MyComp; let mut world = World::new(); let mut registry = TypeRegistration::of::<MyComp>(); registry.insert::<ReflectComponent>(FromType::<MyComp>::from_type()); let data = registry.data::<ReflectComponent>().unwrap(); // Its now possible to register the Component in the world this way let component_id = data.register_component(&mut world); // They will be the same assert_eq!(component_id, world.component_id::<MyComp>().unwrap()); ``` ```rs #[derive(Resource, Reflect)] #[reflect(Resource)] struct MyResource; let mut world = World::new(); let mut registry = TypeRegistration::of::<MyResource>(); registry.insert::<ReflectResource>(FromType::<MyResource>::from_type()); let data = registry.data::<ReflectResource>().unwrap(); // Same with resources let component_id = data.register_resource(&mut world); // They match assert_eq!(component_id, world.resource_id::<MyResource>().unwrap()); ```
This commit is contained in:
parent
c1486654d7
commit
c32e0b9ec2
@ -60,7 +60,7 @@
|
||||
use super::from_reflect_with_fallback;
|
||||
use crate::{
|
||||
change_detection::Mut,
|
||||
component::Component,
|
||||
component::{Component, ComponentId},
|
||||
entity::Entity,
|
||||
world::{
|
||||
unsafe_world_cell::UnsafeEntityCell, EntityMut, EntityWorldMut, FilteredEntityMut,
|
||||
@ -119,6 +119,8 @@ pub struct ReflectComponentFns {
|
||||
pub reflect_unchecked_mut: unsafe fn(UnsafeEntityCell<'_>) -> Option<Mut<'_, dyn Reflect>>,
|
||||
/// Function pointer implementing [`ReflectComponent::copy()`].
|
||||
pub copy: fn(&World, &mut World, Entity, Entity, &TypeRegistry),
|
||||
/// Function pointer implementing [`ReflectComponent::register_component()`].
|
||||
pub register_component: fn(&mut World) -> ComponentId,
|
||||
}
|
||||
|
||||
impl ReflectComponentFns {
|
||||
@ -220,6 +222,11 @@ impl ReflectComponent {
|
||||
);
|
||||
}
|
||||
|
||||
/// Register the type of this [`Component`] in [`World`], returning its [`ComponentId`].
|
||||
pub fn register_component(&self, world: &mut World) -> ComponentId {
|
||||
(self.0.register_component)(world)
|
||||
}
|
||||
|
||||
/// Create a custom implementation of [`ReflectComponent`].
|
||||
///
|
||||
/// This is an advanced feature,
|
||||
@ -303,6 +310,9 @@ impl<C: Component + Reflect + TypePath> FromType<C> for ReflectComponent {
|
||||
let c = unsafe { entity.get_mut::<C>() };
|
||||
c.map(|c| c.map_unchanged(|value| value as &mut dyn Reflect))
|
||||
},
|
||||
register_component: |world: &mut World| -> ComponentId {
|
||||
world.register_component::<C>()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
use crate::{
|
||||
change_detection::Mut,
|
||||
component::ComponentId,
|
||||
system::Resource,
|
||||
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
||||
};
|
||||
@ -59,6 +60,8 @@ pub struct ReflectResourceFns {
|
||||
pub reflect_unchecked_mut: unsafe fn(UnsafeWorldCell<'_>) -> Option<Mut<'_, dyn Reflect>>,
|
||||
/// Function pointer implementing [`ReflectResource::copy()`].
|
||||
pub copy: fn(&World, &mut World, &TypeRegistry),
|
||||
/// Function pointer implementing [`ReflectResource::register_resource()`].
|
||||
pub register_resource: fn(&mut World) -> ComponentId,
|
||||
}
|
||||
|
||||
impl ReflectResourceFns {
|
||||
@ -145,6 +148,11 @@ impl ReflectResource {
|
||||
(self.0.copy)(source_world, destination_world, registry);
|
||||
}
|
||||
|
||||
/// Register the type of this [`Resource`] in [`World`], returning the [`ComponentId`]
|
||||
pub fn register_resource(&self, world: &mut World) -> ComponentId {
|
||||
(self.0.register_resource)(world)
|
||||
}
|
||||
|
||||
/// Create a custom implementation of [`ReflectResource`].
|
||||
///
|
||||
/// This is an advanced feature,
|
||||
@ -217,6 +225,10 @@ impl<R: Resource + FromReflect + TypePath> FromType<R> for ReflectResource {
|
||||
from_reflect_with_fallback::<R>(source_resource, destination_world, registry);
|
||||
destination_world.insert_resource(destination_resource);
|
||||
},
|
||||
|
||||
register_resource: |world: &mut World| -> ComponentId {
|
||||
world.register_resource::<R>()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,6 +334,25 @@ impl World {
|
||||
self.components.component_id::<T>()
|
||||
}
|
||||
|
||||
/// Registers a new [`Resource`] type and returns the [`ComponentId`] created for it.
|
||||
///
|
||||
/// Note that the resource doesn't have a value in world, it's only registered.
|
||||
/// if you want to insert the [`Resource`] in the [`World`], use [`World::init_resource`] or [`World::insert_resource`] instead.
|
||||
pub fn register_resource<R: Resource>(&mut self) -> ComponentId {
|
||||
self.components.register_resource::<R>()
|
||||
}
|
||||
|
||||
/// Returns the [`ComponentId`] of the given [`Resource`] type `T`.
|
||||
///
|
||||
/// The returned `ComponentId` is specific to the `World` instance
|
||||
/// it was retrieved from and should not be used with another `World` instance.
|
||||
///
|
||||
/// Returns [`None`] if the `Resource` type has not yet been initialized within
|
||||
/// the `World` using [`World::register_resource`], [`World::init_resource`] or [`World::insert_resource`].
|
||||
pub fn resource_id<T: Resource>(&self) -> Option<ComponentId> {
|
||||
self.components.get_resource_id(TypeId::of::<T>())
|
||||
}
|
||||
|
||||
/// Retrieves an [`EntityRef`] that exposes read-only operations for the given `entity`.
|
||||
/// This will panic if the `entity` does not exist. Use [`World::get_entity`] if you want
|
||||
/// to check for entity existence instead of implicitly panic-ing.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user