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}