a16adc751b
5 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
![]() |
a85a3a2a15
|
allow Call and Closure expressions in hook macro attributes (#18017)
# Objective This PR adds: - function call hook attributes `#[component(on_add = func(42))]` - main feature of this commit - closure hook attributes `#[component(on_add = |w, ctx| { /* ... */ })]` - maybe too verbose - but was easy to add - was suggested on discord This allows to reuse common functionality without replicating a lot of boilerplate. A small example is a hook which just adds different default sprites. The sprite loading code would be the same for every component. Unfortunately we can't use the required components feature, since we need at least an `AssetServer` or other `Resource`s or `Component`s to load the sprite. ```rs fn load_sprite(path: &str) -> impl Fn(DeferredWorld, HookContext) { |mut world, ctx| { // ... use world to load sprite } } #[derive(Component)] #[component(on_add = load_sprite("knight.png"))] struct Knight; #[derive(Component)] #[component(on_add = load_sprite("monster.png"))] struct Monster; ``` --- The commit also reorders the logic of the derive macro a bit. It's probably a bit less lazy now, but the functionality shouldn't be performance critical and is executed at compile time anyways. ## Solution - Introduce `HookKind` enum in the component proc macro module - extend parsing to allow more cases of expressions ## Testing I have some code laying around. I'm not sure where to put it yet though. Also is there a way to check compilation failures? Anyways, here it is: ```rs use bevy::prelude::*; #[derive(Component)] #[component( on_add = fooing_and_baring, on_insert = fooing_and_baring, on_replace = fooing_and_baring, on_despawn = fooing_and_baring, on_remove = fooing_and_baring )] pub struct FooPath; fn fooing_and_baring( world: bevy::ecs::world::DeferredWorld, ctx: bevy::ecs::component::HookContext, ) { } #[derive(Component)] #[component( on_add = baring_and_bazzing("foo"), on_insert = baring_and_bazzing("foo"), on_replace = baring_and_bazzing("foo"), on_despawn = baring_and_bazzing("foo"), on_remove = baring_and_bazzing("foo") )] pub struct FooCall; fn baring_and_bazzing( path: &str, ) -> impl Fn(bevy::ecs::world::DeferredWorld, bevy::ecs::component::HookContext) { |world, ctx| {} } #[derive(Component)] #[component( on_add = |w,ctx| {}, on_insert = |w,ctx| {}, on_replace = |w,ctx| {}, on_despawn = |w,ctx| {}, on_remove = |w,ctx| {} )] pub struct FooClosure; #[derive(Component, Debug)] #[relationship(relationship_target = FooTargets)] #[component( on_add = baring_and_bazzing("foo"), // on_insert = baring_and_bazzing("foo"), // on_replace = baring_and_bazzing("foo"), on_despawn = baring_and_bazzing("foo"), on_remove = baring_and_bazzing("foo") )] pub struct FooTargetOf(Entity); #[derive(Component, Debug)] #[relationship_target(relationship = FooTargetOf)] #[component( on_add = |w,ctx| {}, on_insert = |w,ctx| {}, // on_replace = |w,ctx| {}, // on_despawn = |w,ctx| {}, on_remove = |w,ctx| {} )] pub struct FooTargets(Vec<Entity>); // MSG: mismatched types expected fn pointer `for<'w> fn(bevy::bevy_ecs::world::DeferredWorld<'w>, bevy::bevy_ecs::component::HookContext)` found struct `Bar` // // pub struct Bar; // #[derive(Component)] // #[component( // on_add = Bar, // )] // pub struct FooWrongPath; // MSG: this function takes 1 argument but 2 arguements were supplied // // #[derive(Component)] // #[component( // on_add = wrong_bazzing("foo"), // )] // pub struct FooWrongCall; // // fn wrong_bazzing(path: &str) -> impl Fn(bevy::ecs::world::DeferredWorld) { // |world| {} // } // MSG: expected 1 argument, found 2 // // #[derive(Component)] // #[component( // on_add = |w| {}, // )] // pub struct FooWrongCall; ``` --- ## Showcase I'll try to continue to work on this to have a small section in the release notes. |
||
![]() |
20277006ce
|
Add benchmarks and compile_fail tests back to workspace (#16858)
# Objective - Our benchmarks and `compile_fail` tests lag behind the rest of the engine because they are not in the Cargo workspace, so not checked by CI. - Fixes #16801, please see it for further context! ## Solution - Add benchmarks and `compile_fail` tests to the Cargo workspace. - Fix any leftover formatting issues and documentation. ## Testing - I think CI should catch most things! ## Questions <details> <summary>Outdated issue I was having with function reflection being optional</summary> The `reflection_types` example is failing in Rust-Analyzer for me, but not a normal check. ```rust error[E0004]: non-exhaustive patterns: `ReflectRef::Function(_)` not covered --> examples/reflection/reflection_types.rs:81:11 | 81 | match value.reflect_ref() { | ^^^^^^^^^^^^^^^^^^^ pattern `ReflectRef::Function(_)` not covered | note: `ReflectRef<'_>` defined here --> /Users/bdeep/dev/bevy/bevy/crates/bevy_reflect/src/kind.rs:178:1 | 178 | pub enum ReflectRef<'a> { | ^^^^^^^^^^^^^^^^^^^^^^^ ... 188 | Function(&'a dyn Function), | -------- not covered = note: the matched value is of type `ReflectRef<'_>` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | 126 ~ ReflectRef::Opaque(_) => {}, 127 + ReflectRef::Function(_) => todo!() | ``` I think it is because the following line is feature-gated: |
||
![]() |
d70595b667
|
Add core and alloc over std Lints (#15281)
# Objective - Fixes #6370 - Closes #6581 ## Solution - Added the following lints to the workspace: - `std_instead_of_core` - `std_instead_of_alloc` - `alloc_instead_of_core` - Used `cargo +nightly fmt` with [item level use formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Item%5C%3A) to split all `use` statements into single items. - Used `cargo clippy --workspace --all-targets --all-features --fix --allow-dirty` to _attempt_ to resolve the new linting issues, and intervened where the lint was unable to resolve the issue automatically (usually due to needing an `extern crate alloc;` statement in a crate root). - Manually removed certain uses of `std` where negative feature gating prevented `--all-features` from finding the offending uses. - Used `cargo +nightly fmt` with [crate level use formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Crate%5C%3A) to re-merge all `use` statements matching Bevy's previous styling. - Manually fixed cases where the `fmt` tool could not re-merge `use` statements due to conditional compilation attributes. ## Testing - Ran CI locally ## Migration Guide The MSRV is now 1.81. Please update to this version or higher. ## Notes - This is a _massive_ change to try and push through, which is why I've outlined the semi-automatic steps I used to create this PR, in case this fails and someone else tries again in the future. - Making this change has no impact on user code, but does mean Bevy contributors will be warned to use `core` and `alloc` instead of `std` where possible. - This lint is a critical first step towards investigating `no_std` options for Bevy. --------- Co-authored-by: François Mockers <francois.mockers@vleue.com> |
||
![]() |
6522795889
|
Specify test group names in github summary for compile fail tests (#14330)
# Objective The github action summary titles every compile test group as `compile_fail_utils`.  ## Solution Manually specify group names for compile fail tests. ## Testing - Wait for compile fail tests to run. - Observe the generated summary. |
||
![]() |
bdb4899978
|
Move compile fail tests (#13196)
# Objective
- Follow-up of #13184 :)
- We use `ui_test` to test compiler errors for our custom macros.
- There are four crates related to compile fail tests
- `bevy_ecs_compile_fail_tests`, `bevy_macros_compile_fail_tests`, and
`bevy_reflect_compile_fail_tests`, which actually test the macros.
-
[`bevy_compile_test_utils`](
|