Skip to content

Commit 7576312

Browse files
authored
Make ReflectEvent more accessible (#22450)
# Objective `ReflectEventFns` mentions being able to create custom implementations of it, but that's not actually currently possible. ## Solution - Make `ReflectEventFns::trigger` field `pub`. - Add `ReflectEvent::new` and `ReflectEvent::fn_pointers` to enable creation of custom implementations. ## Testing Not sure what exactly we would be testing.
1 parent 2b1ae2e commit 7576312

File tree

1 file changed

+51
-17
lines changed

1 file changed

+51
-17
lines changed

crates/bevy_ecs/src/reflect/event.rs

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,33 @@ pub struct ReflectEvent(ReflectEventFns);
1818
/// The raw function pointers needed to make up a [`ReflectEvent`].
1919
///
2020
/// This is used when creating custom implementations of [`ReflectEvent`] with
21-
/// [`ReflectEventFns::new()`].
21+
/// [`ReflectEvent::new()`].
2222
///
2323
/// > **Note:**
24-
/// > Creating custom implementations of [`ReflectEvent`] is an advanced feature that most users
25-
/// > will not need.
26-
/// > Usually a [`ReflectEvent`] is created for a type by deriving [`Reflect`]
27-
/// > and adding the `#[reflect(Event)]` attribute.
28-
/// > After adding the component to the [`TypeRegistry`],
29-
/// > its [`ReflectEvent`] can then be retrieved when needed.
24+
/// > Creating custom implementations of [`ReflectEvent`] is an advanced feature
25+
/// > that most users will not need. Usually a [`ReflectEvent`] is created for a
26+
/// > type by deriving [`Reflect`] and adding the `#[reflect(Event)]` attribute.
27+
/// > After adding the event to the [`TypeRegistry`], its [`ReflectEvent`] can
28+
/// > then be retrieved when needed.
3029
///
31-
/// Creating a custom [`ReflectEvent`] may be useful if you need to create new component types
32-
/// at runtime, for example, for scripting implementations.
30+
/// Creating a custom [`ReflectEvent`] may be useful if you need to create new
31+
/// event types at runtime, for example, for scripting implementations.
3332
///
3433
/// By creating a custom [`ReflectEvent`] and inserting it into a type's
35-
/// [`TypeRegistration`][bevy_reflect::TypeRegistration],
36-
/// you can modify the way that reflected event of that type will be triggered in the Bevy
37-
/// world.
34+
/// [`TypeRegistration`][bevy_reflect::TypeRegistration], you can modify the way
35+
/// that reflected event of that type will be triggered in the Bevy world.
3836
#[derive(Clone)]
3937
pub struct ReflectEventFns {
40-
trigger: fn(&mut World, &dyn PartialReflect, &TypeRegistry),
38+
/// Function pointer implementing [`ReflectEvent::trigger`].
39+
pub trigger: fn(&mut World, &dyn PartialReflect, &TypeRegistry),
4140
}
4241

4342
impl ReflectEventFns {
44-
/// Get the default set of [`ReflectEventFns`] for a specific event type using its
45-
/// [`FromType`] implementation.
43+
/// Get the default set of [`ReflectEventFns`] for a specific event type
44+
/// using its [`FromType`] implementation.
4645
///
47-
/// This is useful if you want to start with the default implementation before overriding some
48-
/// of the functions to create a custom implementation.
46+
/// This is useful if you want to start with the default implementation
47+
/// before overriding some of the functions to create a custom implementation.
4948
pub fn new<'a, T: Event + FromReflect + TypePath>() -> Self
5049
where
5150
T::Trigger<'a>: Default,
@@ -59,6 +58,41 @@ impl ReflectEvent {
5958
pub fn trigger(&self, world: &mut World, event: &dyn PartialReflect, registry: &TypeRegistry) {
6059
(self.0.trigger)(world, event, registry);
6160
}
61+
62+
/// Create a custom implementation of [`ReflectEvent`].
63+
///
64+
/// This is an advanced feature,
65+
/// useful for scripting implementations,
66+
/// that should not be used by most users
67+
/// unless you know what you are doing.
68+
///
69+
/// Usually you should derive [`Reflect`] and add the `#[reflect(Event)]`
70+
/// attribute to generate a [`ReflectEvent`] implementation automatically.
71+
///
72+
/// See [`ReflectEventFns`] for more information.
73+
pub fn new(fns: ReflectEventFns) -> Self {
74+
ReflectEvent(fns)
75+
}
76+
77+
/// The underlying function pointers implementing methods on [`ReflectEvent`].
78+
///
79+
/// This is useful when you want to keep track locally of an individual
80+
/// function pointer.
81+
///
82+
/// Calling [`TypeRegistry::get`] followed by
83+
/// [`TypeRegistration::data::<ReflectEvent>`] can be costly if done several
84+
/// times per frame. Consider cloning [`ReflectEvent`] and keeping it
85+
/// between frames, cloning a `ReflectEvent` is very cheap.
86+
///
87+
/// If you only need a subset of the methods on `ReflectEvent`,
88+
/// use `fn_pointers` to get the underlying [`ReflectEventFns`]
89+
/// and copy the subset of function pointers you care about.
90+
///
91+
/// [`TypeRegistration::data::<ReflectEvent>`]: bevy_reflect::TypeRegistration::data
92+
/// [`TypeRegistry::get`]: bevy_reflect::TypeRegistry::get
93+
pub fn fn_pointers(&self) -> &ReflectEventFns {
94+
&self.0
95+
}
6296
}
6397

6498
impl<'a, E: Event + Reflect + TypePath> FromType<E> for ReflectEvent

0 commit comments

Comments
 (0)