bevy_ecs/reflect/
from_world.rs

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