Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/reflect/from_world.rs
6600 views
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 [`component`](`super::component`), but for [`FromWorld`].
8
9
use alloc::boxed::Box;
10
use bevy_reflect::{FromType, Reflect};
11
12
use 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)]
19
pub struct ReflectFromWorld(ReflectFromWorldFns);
20
21
/// The raw function pointers needed to make up a [`ReflectFromWorld`].
22
#[derive(Clone)]
23
pub struct ReflectFromWorldFns {
24
/// Function pointer implementing [`ReflectFromWorld::from_world()`].
25
pub from_world: fn(&mut World) -> Box<dyn Reflect>,
26
}
27
28
impl 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
39
impl 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
81
impl<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
}
88
89