//! Definitions for [`Event`] reflection.1//! This allows triggering events whose type is only known at runtime.2//!3//! This module exports two types: [`ReflectEventFns`] and [`ReflectEvent`].4//!5//! Same as [`component`](`super::component`), but for events.67use crate::{event::Event, reflect::from_reflect_with_fallback, world::World};8use bevy_reflect::{FromReflect, FromType, PartialReflect, Reflect, TypePath, TypeRegistry};910/// A struct used to operate on reflected [`Event`] trait of a type.11///12/// A [`ReflectEvent`] for type `T` can be obtained via13/// [`bevy_reflect::TypeRegistration::data`].14#[derive(Clone)]15pub struct ReflectEvent(ReflectEventFns);1617/// The raw function pointers needed to make up a [`ReflectEvent`].18///19/// This is used when creating custom implementations of [`ReflectEvent`] with20/// [`ReflectEvent::new()`].21///22/// > **Note:**23/// > Creating custom implementations of [`ReflectEvent`] is an advanced feature24/// > that most users will not need. Usually a [`ReflectEvent`] is created for a25/// > type by deriving [`Reflect`] and adding the `#[reflect(Event)]` attribute.26/// > After adding the event to the [`TypeRegistry`], its [`ReflectEvent`] can27/// > then be retrieved when needed.28///29/// Creating a custom [`ReflectEvent`] may be useful if you need to create new30/// event types at runtime, for example, for scripting implementations.31///32/// By creating a custom [`ReflectEvent`] and inserting it into a type's33/// [`TypeRegistration`][bevy_reflect::TypeRegistration], you can modify the way34/// that reflected event of that type will be triggered in the Bevy world.35#[derive(Clone)]36pub struct ReflectEventFns {37/// Function pointer implementing [`ReflectEvent::trigger`].38pub trigger: fn(&mut World, &dyn PartialReflect, &TypeRegistry),39}4041impl ReflectEventFns {42/// Get the default set of [`ReflectEventFns`] for a specific event type43/// using its [`FromType`] implementation.44///45/// This is useful if you want to start with the default implementation46/// before overriding some of the functions to create a custom implementation.47pub fn new<'a, T: Event + FromReflect + TypePath>() -> Self48where49T::Trigger<'a>: Default,50{51<ReflectEvent as FromType<T>>::from_type().052}53}5455impl ReflectEvent {56/// Triggers a reflected [`Event`] like [`trigger()`](World::trigger).57pub fn trigger(&self, world: &mut World, event: &dyn PartialReflect, registry: &TypeRegistry) {58(self.0.trigger)(world, event, registry);59}6061/// Create a custom implementation of [`ReflectEvent`].62///63/// This is an advanced feature,64/// useful for scripting implementations,65/// that should not be used by most users66/// unless you know what you are doing.67///68/// Usually you should derive [`Reflect`] and add the `#[reflect(Event)]`69/// attribute to generate a [`ReflectEvent`] implementation automatically.70///71/// See [`ReflectEventFns`] for more information.72pub fn new(fns: ReflectEventFns) -> Self {73ReflectEvent(fns)74}7576/// The underlying function pointers implementing methods on [`ReflectEvent`].77///78/// This is useful when you want to keep track locally of an individual79/// function pointer.80///81/// Calling [`TypeRegistry::get`] followed by82/// [`TypeRegistration::data::<ReflectEvent>`] can be costly if done several83/// times per frame. Consider cloning [`ReflectEvent`] and keeping it84/// between frames, cloning a `ReflectEvent` is very cheap.85///86/// If you only need a subset of the methods on `ReflectEvent`,87/// use `fn_pointers` to get the underlying [`ReflectEventFns`]88/// and copy the subset of function pointers you care about.89///90/// [`TypeRegistration::data::<ReflectEvent>`]: bevy_reflect::TypeRegistration::data91/// [`TypeRegistry::get`]: bevy_reflect::TypeRegistry::get92pub fn fn_pointers(&self) -> &ReflectEventFns {93&self.094}95}9697impl<'a, E: Event + Reflect + TypePath> FromType<E> for ReflectEvent98where99<E as Event>::Trigger<'a>: Default,100{101fn from_type() -> Self {102ReflectEvent(ReflectEventFns {103trigger: |world, reflected_event, registry| {104let event = from_reflect_with_fallback::<E>(reflected_event, world, registry);105world.trigger(event);106},107})108}109}110111112