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}