bevy_ecs/reflect/from_world.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
//! Definitions for [`FromWorld`] reflection.
//! This allows creating instances of types that are known only at runtime and
//! require an `&mut World` to be initialized.
//!
//! This module exports two types: [`ReflectFromWorldFns`] and [`ReflectFromWorld`].
//!
//! Same as [`super::component`], but for [`FromWorld`].
use bevy_reflect::{FromType, Reflect};
use crate::world::{FromWorld, World};
/// A struct used to operate on the reflected [`FromWorld`] trait of a type.
///
/// A [`ReflectFromWorld`] for type `T` can be obtained via
/// [`bevy_reflect::TypeRegistration::data`].
#[derive(Clone)]
pub struct ReflectFromWorld(ReflectFromWorldFns);
/// The raw function pointers needed to make up a [`ReflectFromWorld`].
#[derive(Clone)]
pub struct ReflectFromWorldFns {
/// Function pointer implementing [`ReflectFromWorld::from_world()`].
pub from_world: fn(&mut World) -> Box<dyn Reflect>,
}
impl ReflectFromWorldFns {
/// Get the default set of [`ReflectFromWorldFns`] for a specific 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: Reflect + FromWorld>() -> Self {
<ReflectFromWorld as FromType<T>>::from_type().0
}
}
impl ReflectFromWorld {
/// Constructs default reflected [`FromWorld`] from world using [`from_world()`](FromWorld::from_world).
pub fn from_world(&self, world: &mut World) -> Box<dyn Reflect> {
(self.0.from_world)(world)
}
/// Create a custom implementation of [`ReflectFromWorld`].
///
/// This is an advanced feature,
/// useful for scripting implementations,
/// that should not be used by most users
/// unless you know what you are doing.
///
/// Usually you should derive [`Reflect`] and add the `#[reflect(FromWorld)]` bundle
/// to generate a [`ReflectFromWorld`] implementation automatically.
///
/// See [`ReflectFromWorldFns`] for more information.
pub fn new(fns: ReflectFromWorldFns) -> Self {
Self(fns)
}
/// The underlying function pointers implementing methods on `ReflectFromWorld`.
///
/// This is useful when you want to keep track locally of an individual
/// function pointer.
///
/// Calling [`TypeRegistry::get`] followed by
/// [`TypeRegistration::data::<ReflectFromWorld>`] can be costly if done several
/// times per frame. Consider cloning [`ReflectFromWorld`] and keeping it
/// between frames, cloning a `ReflectFromWorld` is very cheap.
///
/// If you only need a subset of the methods on `ReflectFromWorld`,
/// use `fn_pointers` to get the underlying [`ReflectFromWorldFns`]
/// and copy the subset of function pointers you care about.
///
/// [`TypeRegistration::data::<ReflectFromWorld>`]: bevy_reflect::TypeRegistration::data
/// [`TypeRegistry::get`]: bevy_reflect::TypeRegistry::get
pub fn fn_pointers(&self) -> &ReflectFromWorldFns {
&self.0
}
}
impl<B: Reflect + FromWorld> FromType<B> for ReflectFromWorld {
fn from_type() -> Self {
ReflectFromWorld(ReflectFromWorldFns {
from_world: |world| Box::new(B::from_world(world)),
})
}
}