
This pr uses the `extern crate self as` trick to make proc macros behave the same way inside and outside bevy. # Objective - Removes noise introduced by `crate as` in the whole bevy repo. - Fixes #17004. - Hardens proc macro path resolution. ## TODO - [x] `BevyManifest` needs cleanup. - [x] Cleanup remaining `crate as`. - [x] Add proper integration tests to the ci. ## Notes - `cargo-manifest-proc-macros` is written by me and based/inspired by the old `BevyManifest` implementation and [`bkchr/proc-macro-crate`](https://github.com/bkchr/proc-macro-crate). - What do you think about the new integration test machinery I added to the `ci`? More and better integration tests can be added at a later stage. The goal of these integration tests is to simulate an actual separate crate that uses bevy. Ideally they would lightly touch all bevy crates. ## Testing - Needs RA test - Needs testing from other users - Others need to run at least `cargo run -p ci integration-test` and verify that they work. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
92 lines
2.4 KiB
Rust
92 lines
2.4 KiB
Rust
use crate::{
|
|
prelude::{Bundle, Trigger},
|
|
system::System,
|
|
};
|
|
|
|
use super::IntoSystem;
|
|
|
|
/// Implemented for [`System`]s that have a [`Trigger`] as the first argument.
|
|
pub trait ObserverSystem<E: 'static, B: Bundle, Out = ()>:
|
|
System<In = Trigger<'static, E, B>, Out = Out> + Send + 'static
|
|
{
|
|
}
|
|
|
|
impl<
|
|
E: 'static,
|
|
B: Bundle,
|
|
Out,
|
|
T: System<In = Trigger<'static, E, B>, Out = Out> + Send + 'static,
|
|
> ObserverSystem<E, B, Out> for T
|
|
{
|
|
}
|
|
|
|
/// Implemented for systems that convert into [`ObserverSystem`].
|
|
///
|
|
/// # Usage notes
|
|
///
|
|
/// This trait should only be used as a bound for trait implementations or as an
|
|
/// argument to a function. If an observer system needs to be returned from a
|
|
/// function or stored somewhere, use [`ObserverSystem`] instead of this trait.
|
|
#[diagnostic::on_unimplemented(
|
|
message = "`{Self}` cannot become an `ObserverSystem`",
|
|
label = "the trait `IntoObserverSystem` is not implemented",
|
|
note = "for function `ObserverSystem`s, ensure the first argument is a `Trigger<T>` and any subsequent ones are `SystemParam`"
|
|
)]
|
|
pub trait IntoObserverSystem<E: 'static, B: Bundle, M, Out = ()>: Send + 'static {
|
|
/// The type of [`System`] that this instance converts into.
|
|
type System: ObserverSystem<E, B, Out>;
|
|
|
|
/// Turns this value into its corresponding [`System`].
|
|
fn into_system(this: Self) -> Self::System;
|
|
}
|
|
|
|
impl<
|
|
S: IntoSystem<Trigger<'static, E, B>, Out, M> + Send + 'static,
|
|
M,
|
|
Out,
|
|
E: 'static,
|
|
B: Bundle,
|
|
> IntoObserverSystem<E, B, M, Out> for S
|
|
where
|
|
S::System: ObserverSystem<E, B, Out>,
|
|
{
|
|
type System = <S as IntoSystem<Trigger<'static, E, B>, Out, M>>::System;
|
|
|
|
fn into_system(this: Self) -> Self::System {
|
|
IntoSystem::into_system(this)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{
|
|
event::Event,
|
|
observer::Trigger,
|
|
system::{In, IntoSystem},
|
|
world::World,
|
|
};
|
|
|
|
#[derive(Event)]
|
|
struct TriggerEvent;
|
|
|
|
#[test]
|
|
fn test_piped_observer_systems_no_input() {
|
|
fn a(_: Trigger<TriggerEvent>) {}
|
|
fn b() {}
|
|
|
|
let mut world = World::new();
|
|
world.add_observer(a.pipe(b));
|
|
}
|
|
|
|
#[test]
|
|
fn test_piped_observer_systems_with_inputs() {
|
|
fn a(_: Trigger<TriggerEvent>) -> u32 {
|
|
3
|
|
}
|
|
fn b(_: In<u32>) {}
|
|
|
|
let mut world = World::new();
|
|
world.add_observer(a.pipe(b));
|
|
}
|
|
}
|