bevy_ecs/reflect/
event.rs

1//! Definitions for [`Event`] reflection.
2//! This allows triggering events whose type is only known at runtime.
3//!
4//! This module exports two types: [`ReflectEventFns`] and [`ReflectEvent`].
5//!
6//! Same as [`component`](`super::component`), but for events.
7
8use crate::{event::Event, reflect::from_reflect_with_fallback, world::World};
9use bevy_reflect::{FromReflect, FromType, PartialReflect, Reflect, TypePath, TypeRegistry};
10
11/// A struct used to operate on reflected [`Event`] trait of a type.
12///
13/// A [`ReflectEvent`] for type `T` can be obtained via
14/// [`bevy_reflect::TypeRegistration::data`].
15#[derive(Clone)]
16pub struct ReflectEvent(ReflectEventFns);
17
18/// The raw function pointers needed to make up a [`ReflectEvent`].
19///
20/// This is used when creating custom implementations of [`ReflectEvent`] with
21/// [`ReflectEventFns::new()`].
22///
23/// > **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.
30///
31/// Creating a custom [`ReflectEvent`] may be useful if you need to create new component types
32/// at runtime, for example, for scripting implementations.
33///
34/// 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.
38#[derive(Clone)]
39pub struct ReflectEventFns {
40    trigger: fn(&mut World, &dyn PartialReflect, &TypeRegistry),
41}
42
43impl ReflectEventFns {
44    /// Get the default set of [`ReflectEventFns`] for a specific event type using its
45    /// [`FromType`] implementation.
46    ///
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.
49    pub fn new<'a, T: Event + FromReflect + TypePath>() -> Self
50    where
51        T::Trigger<'a>: Default,
52    {
53        <ReflectEvent as FromType<T>>::from_type().0
54    }
55}
56
57impl ReflectEvent {
58    /// Triggers a reflected [`Event`] like [`trigger()`](World::trigger).
59    pub fn trigger(&self, world: &mut World, event: &dyn PartialReflect, registry: &TypeRegistry) {
60        (self.0.trigger)(world, event, registry);
61    }
62}
63
64impl<'a, E: Event + Reflect + TypePath> FromType<E> for ReflectEvent
65where
66    <E as Event>::Trigger<'a>: Default,
67{
68    fn from_type() -> Self {
69        ReflectEvent(ReflectEventFns {
70            trigger: |world, reflected_event, registry| {
71                let event = from_reflect_with_fallback::<E>(reflected_event, world, registry);
72                world.trigger(event);
73            },
74        })
75    }
76}