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