Commit graph

4608 commits

Author SHA1 Message Date
Joseph
c440de06f1
Add a variant of Events::update that returns the removed events (#9542)
# Objective

Every frame, `Events::update` gets called, which clears out any old
events from the buffer. There should be a way of taking ownership of
these old events instead of throwing them away. My use-case is dumping
old events into a debug menu so they can be inspected later.

One potential workaround is to just have a system that clones any
incoming events and stores them in a list -- however, this requires the
events to implement `Clone`.

## Solution

Add `Events::update_drain`, which returns an iterator of the events that
were removed from the buffer.
2023-08-28 18:55:59 +00:00
ickshonpe
05b7f60ae5
UI node bundle comment fix (#9404)
# Objective

Doc comment for the `global_transform` field in `NodeBundle` says:

```
/// This field is automatically managed by the UI layout system.
```

The `GlobalTransform` component is the thing being managed, not the
`global_transform` field, and the `TransformPropagate` systems do the
managing, not the UI layout system.
2023-08-28 18:55:35 +00:00
DevinLeamy
a8dc8350c6
Add configure_schedules to App and Schedules to apply ScheduleBuildSettings to all schedules (#9514)
# Objective

- Fixes: #9508 
- Fixes: #9526 

## Solution

- Adds
```rust 
fn configure_schedules(&mut self, schedule_build_settings: ScheduleBuildSettings)
``` 
to `Schedules`, and `App` to simplify applying `ScheduleBuildSettings`
to all schedules.

---

## Migration Guide
- No breaking changes.
- Adds `Schedule::get_build_settings()` getter for the schedule's
`ScheduleBuildSettings`.
- Can replaced manual configuration of all schedules:
```rust
// Old 
for (_, schedule) in app.world.resource_mut::<Schedules>().iter_mut() {
    schedule.set_build_settings(build_settings);
}

// New
app.configure_schedules(build_settings);
```
2023-08-28 18:54:45 +00:00
Noah
72fc63e594
implement insert and remove reflected entity commands (#8895)
# Objective

To enable non exclusive system usage of reflected components and make
reflection more ergonomic to use by making it more in line with standard
entity commands.

## Solution

- Implements a new `EntityCommands` extension trait for reflection
related functions in the reflect module of bevy_ecs.
- Implements 4 new commands, `insert_reflect`,
`insert_reflect_with_registry`, `remove_reflect`, and
`remove_reflect_with_registry`. Both insert commands take a `Box<dyn
Reflect>` component while the remove commands take the component type
name.

- Made `EntityCommands` fields pub(crate) to allow access in the reflect
module. (Might be worth making these just public to enable user end
custom entity commands in a different pr)
- Added basic tests to ensure the commands are actually working.
- Documentation of functions.

---

## Changelog

Added:
-  Implements 4 new commands on the new entity commands extension.
- `insert_reflect`
- `remove_reflect`
- `insert_reflect_with_registry`
- `remove_reflect_with_registry`

The commands operate the same except the with_registry commands take a
generic parameter for a resource that implements `AsRef<TypeRegistry>`.
Otherwise the default commands use the `AppTypeRegistry` for reflection
data.

Changed:

- Made `EntityCommands` fields pub(crate) to allow access in the reflect
module.

> Hopefully this time it works. Please don't make me rebase again ☹
2023-08-28 18:21:20 +00:00
lelo
2e3900f6a9
Clarify what happens when setting the audio volume (#9480)
# Objective

- Fixes [#8835](https://github.com/bevyengine/bevy/issues/8835)

## Solution

- Added a note to the `set_volume` docstring which explains how volume
is interpreted.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: GitGhillie <jillisnoordhoek@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-08-28 18:21:12 +00:00
ickshonpe
9f27f011c1
Remove Val's try_* arithmetic methods (#9609)
# Objective

Remove `Val`'s `try_*` arithmetic methods.

fixes #9571

## Changelog

Removed these methods from `bevy_ui::ui_node::Val`:
- `try_add`
- `try_sub`
- `try_add_assign_with_size`
- `try_sub_assign_with_size` 
- `try_add_assign`
- `try_sub_assign`
- `try_add_assign_with_size`
- `try_sub_assign_with_size`


## Migration Guide

`Val`'s `try_*` arithmetic methods have been removed. To perform
arithmetic on `Val`s deconstruct them using pattern matching.
2023-08-28 18:11:30 +00:00
Zachary Harrold
1839ff7e2a
Replaced EntityCommand Implementation for FnOnce (#9604)
# Objective

- Fixes #4917
- Replaces #9602

## Solution

- Replaced `EntityCommand` implementation for `FnOnce` to apply to
`FnOnce(EntityMut)` instead of `FnOnce(Entity, &mut World)`

---

## Changelog

- `FnOnce(Entity, &mut World)` no longer implements `EntityCommand`.
This is a breaking change.

## Migration Guide

### 1. New-Type `FnOnce`

Create an `EntityCommand` type which implements the method you
previously wrote:

```rust
pub struct ClassicEntityCommand<F>(pub F);

impl<F> EntityCommand for ClassicEntityCommand<F>
where
    F: FnOnce(Entity, &mut World) + Send + 'static,
{
    fn apply(self, id: Entity, world: &mut World) {
        (self.0)(id, world);
    }
}

commands.add(ClassicEntityCommand(|id: Entity, world: &mut World| {
    /* ... */
}));
```

### 2. Extract `(Entity, &mut World)` from `EntityMut`

The method `into_world_mut` can be used to gain access to the `World`
from an `EntityMut`.

```rust
let old = |id: Entity, world: &mut World| {
    /* ... */
};

let new = |mut entity: EntityMut| {
    let id = entity.id();
    let world = entity.into_world_mut();
    /* ... */
};
```
2023-08-28 18:08:53 +00:00
Joseph
a47a5b30fe
Rename ManualEventIterator (#9592)
# Objective

The name `ManualEventIterator` is long and unnecessary, as this is the
iterator type used for both `EventReader` and `ManualEventReader`.

## Solution

Rename `ManualEventIterator` to `EventIterator`. To ease migration, add
a deprecated type alias with the old name.

---

## Changelog

- The types `ManualEventIterator{WithId}` have been renamed to
`EventIterator{WithId}`.

## Migration Guide

The type `ManualEventIterator` has been renamed to `EventIterator`.
Additonally, `ManualEventIteratorWithId` has been renamed to
`EventIteratorWithId`.
2023-08-28 17:49:25 +00:00
Joseph
da8ab16d83
Relax more Sync bounds on Local (#9589)
# Objective

#5483 allows for the creation of non-`Sync` locals. However, it's not
actually possible to use these types as there is a `Sync` bound on the
`Deref` impls.

## Solution

Remove the unnecessary bounds.
2023-08-28 17:47:15 +00:00
Mike
4e59671ae7
clean up configure_set(s) erroring (#9577)
# Objective

- have errors in configure_set and configure_sets show the line number
of the user calling location rather than pointing to schedule.rs
- use display formatting for the errors

## Example Error Text
```text
// dependency loop
// before
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: DependencyLoop("A")', crates\bevy_ecs\src\schedule\schedule.rs:682:39
// after
thread 'main' panicked at 'System set `A` depends on itself.', examples/stress_tests/bevymark.rs:16:9

// hierarchy loop
// before
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: HierarchyLoop("A")', crates\bevy_ecs\src\schedule\schedule.rs:682:3
// after
thread 'main' panicked at 'System set `A` contains itself.', examples/stress_tests/bevymark.rs:16:9

// configuring a system type set
// before
thread 'main' panicked at 'configuring system type sets is not allowed', crates\bevy_ecs\src\schedule\config.rs:394:9
//after
thread 'main' panicked at 'configuring system type sets is not allowed', examples/stress_tests/bevymark.rs:16:9
```

Code to produce errors:
```rust
use bevy::prelude::*;

#[derive(SystemSet, Clone, Debug, PartialEq, Eq, Hash)]
enum TestSet {
    A,
}

fn main() {
    fn foo() {}
    let mut app = App::empty();
    // Hierarchy Loop
    app.configure_set(Main, TestSet::A.in_set(TestSet::A));
    // Dependency Loop
    app.configure_set(Main, TestSet::A.after(TestSet::A));
    // Configure System Type Set
    app.configure_set(Main, foo.into_system_set());
}
```
2023-08-28 17:44:52 +00:00
jnhyatt
087a345579
Rename Bezier to CubicBezier for clarity (#9554)
# Objective

A Bezier curve is a curve defined by two or more control points. In the
simplest form, it's just a line. The (arguably) most common type of
Bezier curve is a cubic Bezier, defined by four control points. These
are often used in animation, etc. Bevy has a Bezier curve struct called
`Bezier`. However, this is technically a misnomer as it only represents
cubic Bezier curves.

## Solution

This PR changes the struct name to `CubicBezier` to more accurately
reflect the struct's usage. Since it's exposed in Bevy's prelude, it can
potentially collide with other `Bezier` implementations. While that
might instead be an argument for removing it from the prelude, there's
also something to be said for adding a more general `Bezier` into Bevy,
in which case we'd likely want to use the name `Bezier`. As a final
motivator, not only is the struct located in `cubic_spines.rs`, there
are also several other spline-related structs which follow the
`CubicXxx` naming convention where applicable. For example,
`CubicSegment` represents a cubic Bezier curve (with coefficients
pre-baked).

---

## Migration Guide

- Change all `Bezier` references to `CubicBezier`
2023-08-28 17:37:42 +00:00
Gino Valente
b7d68873ec
bevy_derive: Fix #[deref] breaking other attributes (#9551)
# Objective

Fixes #9550

## Solution

Removes a check that asserts that _all_ attribute metas are path-only,
rather than just the `#[deref]` attribute itself.

---

## Changelog

- Fixes an issue where deriving `Deref` with `#[deref]` on a field
causes other attributes to sometimes result in a compile error

---------

Co-authored-by: François <mockersf@gmail.com>
2023-08-28 17:36:18 +00:00
Ray Redondo
5012a0fd57
Update defaults for OrthographicProjection (#9537)
# Objective

These new defaults match what is used by `Camera2dBundle::default()`,
removing a potential footgun from overriding a field in the projection
component of the bundle.

## Solution

Adjusted the near clipping plane of `OrthographicProjection::default()`
to `-1000.`.

---

## Changelog

Changed: `OrthographicProjection::default()` now matches the value used
in `Camera2dBundle::default()`

## Migration Guide

Workarounds used to keep the projection consistent with the bundle
defaults are no longer required. Meanwhile, uses of
`OrthographicProjection` in 2D scenes may need to be adjusted; the
`near` clipping plane default was changed from `0.0` to `-1000.0`.
2023-08-28 17:31:56 +00:00
ickshonpe
aa20565f75
Add Without<Parent> filter to sync_simple_transforms' orphaned entities query (#9518)
# Objective

`sync_simple_transforms` only checks for removed parents and doesn't
filter for `Without<Parent>`, so it overwrites the `GlobalTransform` of
non-orphan entities that were orphaned and then reparented since the
last update.

Introduced by #7264

## Solution

Filter for `Without<Parent>`.

Fixes #9517, #9492

## Changelog

`sync_simple_transforms`:
* Added a `Without<Parent>` filter to the orphaned entities query.
2023-08-28 17:29:46 +00:00
Alex Kocharin
94c67afa4b
Fix panic when using .load_folder() with absolute paths (#9490)
Fixes https://github.com/bevyengine/bevy/issues/9458.

On case-insensitive filesystems (Windows, Mac, NTFS mounted in Linux,
etc.), a path can be represented in a multiple ways:

 - `c:\users\user\rust\assets\hello\world`
 - `c:/users/user/rust/assets/hello/world`
 - `C:\USERS\USER\rust\assets\hello\world`

If user specifies a path variant that doesn't match asset folder path
bevy calculates, `path.strip_prefix()` will fail, as demonstrated below:

```rs
dbg!(Path::new("c:/foo/bar/baz").strip_prefix("c:/foo"));
// Ok("bar/baz")

dbg!(Path::new("c:/FOO/bar/baz").strip_prefix("c:/foo"));
// StripPrefixError(())
```

This commit rewrites the code in question in a way that prefix stripping
is no longer necessary.

I've tested with the following paths on my computer:

```rs
let res = asset_server.load_folder("C:\\Users\\user\\rust\\assets\\foo\\bar");
dbg!(res);

let res = asset_server.load_folder("c:\\users\\user\\rust\\assets\\foo\\bar");
dbg!(res);

let res = asset_server.load_folder("C:/Users/user/rust/assets/foo/bar");
dbg!(res);
```
2023-08-28 17:23:44 +00:00
ickshonpe
a2bd93aedc
Make GridPlacement's fields non-zero and add accessor functions. (#9486)
# Objective

* There is no way to read the fields of `GridPlacement` once set. 
* Values of `0` for `GridPlacement`'s fields are invalid but can be set.
* A non-zero representation would be half the size.

fixes #9474

## Solution
* Add `get_start`, `get_end` and `get_span` accessor methods.
* Change`GridPlacement`'s constructor functions to panic on arguments of
zero.
* Use non-zero types instead of primitives for `GridPlacement`'s fields.

---

## Changelog

`bevy_ui::ui_node::GridPlacement`:
* Field types have been changed to `Option<NonZeroI16>` and
`Option<NonZeroU16>`. This is because zero values are not valid for
`GridPlacement`. Previously, Taffy interpreted these as auto variants.
* Constructor functions for `GridPlacement` panic on arguments of `0`.
* Added accessor functions: `get_start`, `get_end`, and `get_span`.
These return the inner primitive value (if present) of the respective
fields.

## Migration Guide
`GridPlacement`'s constructor functions no longer accept values of `0`.
Given any argument of `0` they will panic with a `GridPlacementError`.
2023-08-28 17:21:08 +00:00
Zachary Harrold
394e2b0c91
Replaced EntityMap with HashMap (#9461)
# Objective

- Fixes #9321

## Solution

- `EntityMap` has been replaced by a simple `HashMap<Entity, Entity>`.

---

## Changelog

- `EntityMap::world_scope` has been replaced with `World::world_scope`
to avoid creating a new trait. This is a public facing change to the
call semantics, but has no effect on results or behaviour.
- `EntityMap`, as a `HashMap`, now operates on `&Entity` rather than
`Entity`. This changes many standard access functions (e.g, `.get`) in a
public-facing way.

## Migration Guide

- Calls to `EntityMap::world_scope` can be directly replaced with the
following:
  `map.world_scope(&mut world)` -> `world.world_scope(&mut map)`
- Calls to legacy `EntityMap` methods such as `EntityMap::get` must
explicitly include de/reference symbols:
  `let entity = map.get(parent);` -> `let &entity = map.get(&parent);`
2023-08-28 17:18:16 +00:00
Pixelstorm
36f29a933f
Remove redundant check for AppExit events in ScheduleRunnerPlugin (#9421)
# Objective

Fixes #9420

## Solution

Remove one of the two `AppExit` event checks in the
`ScheduleRunnerPlugin`'s main loop. Specificially, the check that
happens immediately before calling `App.update()`, to be consistent with
the `WinitPlugin`.
2023-08-28 17:13:02 +00:00
robtfm
25e5239d2e
check root node for animations (#9407)
# Objective

fixes #8357 

gltf animations can affect multiple "root" nodes (i.e. top level nodes
within a gltf scene).

the current loader adds an AnimationPlayer to each root node which is
affected by any animation. when a clip which affects multiple root nodes
is played on a root node player, the root node name is not checked,
leading to potentially incorrect weights being applied.
also, the `AnimationClip::compatible_with` method will never return true
for those clips, as it checks that all paths start with the root node
name - not all paths start with the same name so it can't return true.

## Solution

- check the first path node name matches the given root
- change compatible_with to return true if `any` match is found

a better alternative would probably be to attach the player to the scene
root instead of the first child, and then walk the full path from there.
this would be breaking (and would stop multiple animations that *don't*
overlap from being played concurrently), but i'm happy to modify to that
if it's preferred.

---------

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-08-28 17:06:12 +00:00
François
b28f6334da
only take up to the max number of joints (#9351)
# Objective

- Meshes with a higher number of joints than `MAX_JOINTS` are crashing
- Fixes partly #9021 (doesn't crash anymore, but the mesh is not
correctly displayed)

## Solution

- Only take up to `MAX_JOINTS` joints when extending the buffer
2023-08-28 16:58:45 +00:00
Sélène Amanita
f38549c68d
Reorganize Events and EventSequence code (#9306)
# Objective

Make code relating to event more readable.

Currently the `impl` block of `Events` is split in two, and the big part
of its implementations are put at the end of the file, far from the
definition of the `struct`.

## Solution

- Move and merge the `impl` blocks of `Events` next to its definition.
- Move the `EventSequence` definition and implementations before the
`Events`, because they're pretty trivial and help understand how
`Events` work, rather than being buried bellow `Events`.

I separated those two steps in two commits to not be too confusing. I
didn't modify any code of documentation. I want to do a second PR with
such modifications after this one is merged.
2023-08-28 16:56:22 +00:00
Hennadii Chernyshchyk
fb9a65fa0d
bevy_scene: Add ReflectBundle (#9165)
# Objective

Similar to #6344, but contains only `ReflectBundle` changes. Useful for
scripting. The implementation has also been updated to look exactly like
`ReflectComponent`.

---

## Changelog

### Added

- Reflection for bundles.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2023-08-28 16:50:43 +00:00
Sélène Amanita
44f677a38a
Improve documentation relating to Frustum and HalfSpace (#9136)
# Objective

This PR's first aim is to fix a mistake in `HalfSpace`'s documentation.

When defining a `Frustum` myself in bevy_basic_portals, I realised that
the "distance" of the `HalfSpace` is not, as the current doc defines,
the "distance from the origin along the normal", but actually the
opposite of that.

See the example I gave in this PR.

This means one of two things:
1. The documentation about `HalfSpace` is wrong (it is either way
because of the `n.p + d > 0` formula given later anyway, which is how it
behaves, but in that formula `d` is indeed the opposite of the "distance
from the origin along the normal", otherwise it should be `n.p > d`)
2. The distance is supposed to be the "distance from the origin along
the normal" but when used in a Frustum it's used as the opposite, and it
is a mistake
3. Same as 2, but it is somehow intended

Since I think `HalfSpace` is only used for `Frustum`, and it's easier to
fix documentation than code, I assumed for this PR we're in case number
1. If we're in case number 3, the documentation of `Frustum` needs to
change, and in case number 2, the code needs to be fixed.

While I was at it, I also :
- Tried to improve the documentation for `Frustum`, `Aabb`, and
`VisibilitySystems`, among others, since they're all related to
`Frustum`.
- Fixed documentation about frustum culling not applying to 2d objects,
which is not true since https://github.com/bevyengine/bevy/pull/7885

## Remarks and questions

- What about a `HalfSpace` with an infinite distance, is it allowed and
does it represents the whole space? If so it should probably be
mentioned.
- I referenced the `update_frusta` system in
`bevy_render::view::visibility` directly instead of referencing its
system set, should I reference the system set instead? It's a bit
annoying since it's in 3 sets.
- `visibility_propagate` is not public for some reason, I think it
probably should be, but for now I only documented its system set, should
I make it public? I don't think that would count as a breaking change?
- Why is `Aabb` inserted by a system, with `NoFrustumCulling` as an
opt-out, instead of having it inserted by default in `PbrBundle` for
example and then the system calculating it when it's added? Is it
because there is still no way to have an optional component inside a
bundle?

---------

Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-08-28 16:47:25 +00:00
Nicola Papale
afcb1fee90
Cleanup some bevy_text pipeline.rs (#9111)
## Objective

- `bevy_text/src/pipeline.rs` had some crufty code.

## Solution

Remove the cruft.

- `&mut self` argument was unused by
`TextPipeline::create_text_measure`, so we replace it with a constructor
`TextMeasureInfo::from_text`.
- We also pass a `&Text` to `from_text` since there is no reason to
split the struct before passing it as argument.
- from_text also checks beforehand that every Font exist in the
Assets<Font>. This allows rust to skip the drop code on the Vecs we
create in the method, since there is no early exit.
- We also remove the scaled_fonts field on `TextMeasureInfo`. This
avoids an additional allocation. We can re-use the font on `fonts`
instead in `compute_size`. Building a `ScaledFont` seems fairly cheap,
when looking at the ab_glyph internals.
- We also implement ToSectionText on TextMeasureSection, this let us
skip creating a whole new Vec each time we call compute_size.
- This let us remove compute_size_from_section_text, since its only
purpose was to not have to allocate the Vec we just made redundant.
- Make some immutabe `Vec<T>` into `Box<[T]>` and `String` into
`Box<str>`
- `{min,max}_width_content_size` fields of `TextMeasureInfo` have name
`width` in them, yet the contain information on both width and height.
- `TextMeasureInfo::linebreak_behaviour`  -> `linebreak_behavior`

## Migration Guide

- The `ResMut<TextPipeline>` argument to `measure_text_system` doesn't
exist anymore. If you were calling this system manually, you should
remove the argument.
- The `{min,max}_width_content_size` fields of `TextMeasureInfo` are
renamed to `min` and `max` respectively
- Other changes to `TextMeasureInfo` may also break your code if you
were manually building it. Please consider using the new
`TextMeasureInfo::from_text` to build one instead.
- `TextPipeline::create_text_measure` has been removed in favor of
`TextMeasureInfo::from_text`
2023-08-28 16:46:16 +00:00
DevinLeamy
db5f80b2be
API updates to the AnimationPlayer (#9002)
# Objective

Added `AnimationPlayer` API UX improvements. 

- Succestor to https://github.com/bevyengine/bevy/pull/5912
- Fixes https://github.com/bevyengine/bevy/issues/5848

_(Credits to @asafigan for filing #5848, creating the initial pull
request, and the discussion in #5912)_
## Solution

- Created `RepeatAnimation` enum to describe an animation repetition
behavior.
- Added `is_finished()`, `set_repeat()`, and `is_playback_reversed()`
methods to the animation player.
- ~~Made the animation clip optional as per the comment from #5912~~
> ~~My problem is that the default handle [used the initialize a
`PlayingAnimation`] could actually refer to an actual animation if an
AnimationClip is set for the default handle, which leads me to ask,
"Should animation_clip should be an Option?"~~
- Added an accessor for the animation clip `animation_clip()` to the
animation player.

To determine if an animation is finished, we use the number of times the
animation has completed and the repetition behavior. If the animation is
playing in reverse then `elapsed < 0.0` counts as a completion.
Otherwise, `elapsed > animation.duration` counts as a completion. This
is what I would expect, personally. If there's any ambiguity, perhaps we
could add some `AnimationCompletionBehavior`, to specify that kind of
completion behavior to use.

Update: Previously `PlayingAnimation::elapsed` was being used as the
seek time into the animation clip. This was misleading because if you
increased the speed of the animation it would also increase (or
decrease) the elapsed time. In other words, the elapsed time was not
actually the elapsed time. To solve this, we introduce
`PlayingAnimation::seek_time` to serve as the value we manipulate the
move between keyframes. Consequently, `elapsed()` now returns the actual
elapsed time, and is not effected by the animation speed. Because
`set_elapsed` was being used to manipulate the displayed keyframe, we
introduce `AnimationPlayer::seek_to` and `AnimationPlayer::replay` to
provide this functionality.

## Migration Guide

- Removed `set_elapsed`.
- Removed `stop_repeating` in favour of
`AnimationPlayer::set_repeat(RepeatAnimation::Never)`.
- Introduced `seek_to` to seek to a given timestamp inside of the
animation.
- Introduced `seek_time` accessor for the `PlayingAnimation::seek_to`.
- Introduced `AnimationPlayer::replay` to reset the `PlayingAnimation`
to a state where no time has elapsed.

---------

Co-authored-by: Hennadii Chernyshchyk <genaloner@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
2023-08-28 16:43:04 +00:00
Aceeri
3cf94e7c9d
Check cursor position for out of bounds of the window (#8855)
# Objective
Fixes #8840 

Make the cursor position more consistent, right now the cursor position
is *sometimes* outside of the window and returns the position and
*sometimes* `None`.

Even in the cases where someone might be using that position that is
outside of the window, it'll probably require some manual
transformations for it to actually be useful.

## Solution
Check the windows width and height for out of bounds positions.

---

## Changelog
- Cursor position is now always `None` when outside of the window.

---------

Co-authored-by: ickshonpe <david.curthoys@googlemail.com>
2023-08-28 16:37:44 +00:00
Joseph
474b55a29c
Add system.map(...) for transforming the output of a system (#8526)
# Objective

Any time we wish to transform the output of a system, we currently use
system piping to do so:

```rust
my_system.pipe(|In(x)| do_something(x))
```

Unfortunately, system piping is not a zero cost abstraction. Each call
to `.pipe` requires allocating two extra access sets: one for the second
system and one for the combined accesses of both systems. This also adds
extra work to each call to `update_archetype_component_access`, which
stacks as one adds multiple layers of system piping.

## Solution

Add the `AdapterSystem` abstraction: similar to `CombinatorSystem`, this
allows you to implement a trait to generically control how a system is
run and how its inputs and outputs are processed. Unlike
`CombinatorSystem`, this does not have any overhead when computing world
accesses which makes it ideal for simple operations such as inverting or
ignoring the output of a system.

Add the extension method `.map(...)`: this is similar to `.pipe(...)`,
only it accepts a closure as an argument instead of an `In<T>` system.

```rust
my_system.map(do_something)
```

This has the added benefit of making system names less messy: a system
that ignores its output will just be called `my_system`, instead of
`Pipe(my_system, ignore)`

---

## Changelog

TODO

## Migration Guide

The `system_adapter` functions have been deprecated: use `.map` instead,
which is a lightweight alternative to `.pipe`.

```rust
// Before:
my_system.pipe(system_adapter::ignore)
my_system.pipe(system_adapter::unwrap)
my_system.pipe(system_adapter::new(T::from))

// After:
my_system.map(std::mem::drop)
my_system.map(Result::unwrap)
my_system.map(T::from)

// Before:
my_system.pipe(system_adapter::info)
my_system.pipe(system_adapter::dbg)
my_system.pipe(system_adapter::warn)
my_system.pipe(system_adapter::error)

// After:
my_system.map(bevy_utils::info)
my_system.map(bevy_utils::dbg)
my_system.map(bevy_utils::warn)
my_system.map(bevy_utils::error)
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-08-28 16:36:46 +00:00
James O'Brien
aa489eced0
Swap TransparentUi to use a stable sort (#9598)
# Objective

- Fix the `borders`, `ui` and `text_wrap_debug` examples.

## Solution

- Swap `TransparentUi` to use a stable sort

---

This is the smallest change to fix the examples but ideally this is
fixed by setting better sort keys for the UI elements such that we can
swap back to an unstable sort.
2023-08-27 20:37:17 +00:00
Mike
7b6f8659f8
Refactor build_schedule and related errors (#9579)
# Objective

- break up large build_schedule system to make it easier to read
- Clean up related error messages.
- I have a follow up PR that adds the schedule name to the error
messages, but wanted to break this up from that.

## Changelog

- refactor `build_schedule` to be easier to read

## Sample Error Messages

Dependency Cycle
```text
thread 'main' panicked at 'System dependencies contain cycle(s).
schedule has 1 before/after cycle(s):
cycle 1: system set 'A' must run before itself
system set 'A'
 ... which must run before system set 'B'
 ... which must run before system set 'A'

', crates\bevy_ecs\src\schedule\schedule.rs:228:13
```
```text
thread 'main' panicked at 'System dependencies contain cycle(s).
schedule has 1 before/after cycle(s):
cycle 1: system 'foo' must run before itself
system 'foo'
 ... which must run before system 'bar'
 ... which must run before system 'foo'

', crates\bevy_ecs\src\schedule\schedule.rs:228:13
```
Hierarchy Cycle
```text
thread 'main' panicked at 'System set hierarchy contains cycle(s).
schedule has 1 in_set cycle(s):
cycle 1: set 'A' contains itself
set 'A'
 ... which contains set 'B'
 ... which contains set 'A'

', crates\bevy_ecs\src\schedule\schedule.rs:230:13
```

System Type Set
```text
thread 'main' panicked at 'Tried to order against `SystemTypeSet(fn foo())` in a schedule that has more than one `SystemTypeSet(fn foo())` instance. `SystemTypeSet(fn foo())` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.', crates\bevy_ecs\src\schedule\schedule.rs:230:13
```

Hierarchy Redundancy
```text
thread 'main' panicked at 'System set hierarchy contains redundant edges.
hierarchy contains redundant edge(s) -- system set 'X' cannot be child of set 'A', longer path exists
', crates\bevy_ecs\src\schedule\schedule.rs:230:13
```

Systems have ordering but interset
```text
thread 'main' panicked at '`A` and `C` have a `before`-`after` relationship (which may be transitive) but share systems.', crates\bevy_ecs\src\schedule\schedule.rs:227:51
```

Cross Dependency
```text
thread 'main' panicked at '`A` and `B` have both `in_set` and `before`-`after` relationships (these might be transitive). This combination is unsolvable as a system cannot run before or after a set it belongs to.', crates\bevy_ecs\src\schedule\schedule.rs:230:13
```

Ambiguity
```text
thread 'main' panicked at 'Systems with conflicting access have indeterminate run order.
1 pairs of systems with conflicting data access have indeterminate execution order. Consider adding `before`, `after`, or `ambiguous_with` relationships between these:
 -- res_mut and res_ref
    conflict on: ["bevymark::ambiguity::X"]
', crates\bevy_ecs\src\schedule\schedule.rs:230:13
```
2023-08-27 17:54:59 +00:00
st0rmbtw
9d804a231e
Make run_if_inner public and rename to run_if_dyn (#9576)
# Objective

Sometimes you want to create a plugin with a custom run condition. In a
function, you take the `Condition` trait and then make a
`BoxedCondition` from it to store it. And then you want to add that
condition to a system, but you can't, because there is only the `run_if`
function available which takes `impl Condition<M>` instead of
`BoxedCondition`. So you have to create a wrapper type for the
`BoxedCondition` and implement the `System` and `ReadOnlySystem` traits
for the wrapper (Like it's done in the picture below). It's very
inconvenient and boilerplate. But there is an easy solution for that:
make the `run_if_inner` system that takes a `BoxedCondition` public.
Also, it makes sense to make `in_set_inner` function public as well with
the same motivation.


![image](https://github.com/bevyengine/bevy/assets/61053971/a4455180-7e0c-4c2b-9372-cd8b4a9e682e)
A chunk of the source code of the `bevy-inspector-egui` crate.

## Solution

Make `run_if_inner` function public.
Rename `run_if_inner` to `run_if_dyn`.

Make `in_set_inner` function public.
Rename `in_set_inner` to `in_set_dyn`.

## Changelog

Changed visibility of `run_if_inner` from `pub(crate)` to `pub`.
Renamed `run_if_inner` to `run_if_dyn`.

Changed visibility of `in_set_inner` from `pub(crate)` to `pub`.
Renamed `in_set_inner` to `in_set_dyn`.

## Migration Guide

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
2023-08-27 17:53:37 +00:00
James O'Brien
4f1d9a6315
Reorder render sets, refactor bevy_sprite to take advantage (#9236)
This is a continuation of this PR: #8062 

# Objective

- Reorder render schedule sets to allow data preparation when phase item
order is known to support improved batching
- Part of the batching/instancing etc plan from here:
https://github.com/bevyengine/bevy/issues/89#issuecomment-1379249074
- The original idea came from @inodentry and proved to be a good one.
Thanks!
- Refactor `bevy_sprite` and `bevy_ui` to take advantage of the new
ordering

## Solution
- Move `Prepare` and `PrepareFlush` after `PhaseSortFlush` 
- Add a `PrepareAssets` set that runs in parallel with other systems and
sets in the render schedule.
  - Put prepare_assets systems in the `PrepareAssets` set
- If explicit dependencies are needed on Mesh or Material RenderAssets
then depend on the appropriate system.
- Add `ManageViews` and `ManageViewsFlush` sets between
`ExtractCommands` and Queue
- Move `queue_mesh*_bind_group` to the Prepare stage
  - Rename them to `prepare_`
- Put systems that prepare resources (buffers, textures, etc.) into a
`PrepareResources` set inside `Prepare`
- Put the `prepare_..._bind_group` systems into a `PrepareBindGroup` set
after `PrepareResources`
- Move `prepare_lights` to the `ManageViews` set
  - `prepare_lights` creates views and this must happen before `Queue`
  - This system needs refactoring to stop handling all responsibilities
- Gather lights, sort, and create shadow map views. Store sorted light
entities in a resource

- Remove `BatchedPhaseItem`
- Replace `batch_range` with `batch_size` representing how many items to
skip after rendering the item or to skip the item entirely if
`batch_size` is 0.
- `queue_sprites` has been split into `queue_sprites` for queueing phase
items and `prepare_sprites` for batching after the `PhaseSort`
  - `PhaseItem`s are still inserted in `queue_sprites`
- After sorting adjacent compatible sprite phase items are accumulated
into `SpriteBatch` components on the first entity of each batch,
containing a range of vertex indices. The associated `PhaseItem`'s
`batch_size` is updated appropriately.
- `SpriteBatch` items are then drawn skipping over the other items in
the batch based on the value in `batch_size`
- A very similar refactor was performed on `bevy_ui`
---

## Changelog

Changed:
- Reordered and reworked render app schedule sets. The main change is
that data is extracted, queued, sorted, and then prepared when the order
of data is known.
- Refactor `bevy_sprite` and `bevy_ui` to take advantage of the
reordering.

## Migration Guide
- Assets such as materials and meshes should now be created in
`PrepareAssets` e.g. `prepare_assets<Mesh>`
- Queueing entities to `RenderPhase`s continues to be done in `Queue`
e.g. `queue_sprites`
- Preparing resources (textures, buffers, etc.) should now be done in
`PrepareResources`, e.g. `prepare_prepass_textures`,
`prepare_mesh_uniforms`
- Prepare bind groups should now be done in `PrepareBindGroups` e.g.
`prepare_mesh_bind_group`
- Any batching or instancing can now be done in `Prepare` where the
order of the phase items is known e.g. `prepare_sprites`

 
## Next Steps
- Introduce some generic mechanism to ensure items that can be batched
are grouped in the phase item order, currently you could easily have
`[sprite at z 0, mesh at z 0, sprite at z 0]` preventing batching.
 - Investigate improved orderings for building the MeshUniform buffer
 - Implementing batching across the rest of bevy

---------

Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: robtfm <50659922+robtfm@users.noreply.github.com>
2023-08-27 14:33:49 +00:00
Joseph
e8b3892517
Improve various Debug implementations (#9588)
# Objective

* `Local` and `SystemName` implement `Debug` manually, but they could
derive it.
* `QueryState` and `dyn System` have unconventional debug formatting.
2023-08-26 21:27:41 +00:00
Emi
a6991c3a8c
change 'collapse_type_name' to retain enum types (#9587)
# Objective

Fixes #9509 

## Solution
We use the assumption, that enum types are uppercase in contrast to
module names.
[`collapse_type_name`](crates/bevy_util/src/short_names) is now
retaining the second last segment, if it starts with a uppercase
character.

---------

Co-authored-by: Emi <emanuel.boehm@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
2023-08-26 14:50:12 +00:00
Zachary Harrold
90b3ac7f3a
Added Val::ZERO Constant (#9566)
# Objective

- Fixes #9533

## Solution

* Added `Val::ZERO` as a constant which is defined as `Val::Px(0.)`.
* Added manual `PartialEq` implementation for `Val` which allows any
zero value to equal any other zero value. E.g., `Val::Px(0.) ==
Val::Percent(0.)` etc. This is technically a breaking change, as
`Val::Px(0.) == Val::Percent(0.)` now equals `true` instead of `false`
(as an example)
* Replaced instances of `Val::Px(0.)`, `Val::Percent(0.)`, etc. with
`Val::ZERO`
* Fixed `bevy_ui::layout::convert::tests::test_convert_from` test to
account for Taffy not equating `Points(0.)` and `Percent(0.)`. These
tests now use `assert_eq!(...)` instead of `assert!(matches!(...))`
which gives easier to diagnose error messages.
2023-08-26 14:00:53 +00:00
Christian Hughes
349dd8bd45
Relax In/Out bounds on impl Debug for dyn System (#9581)
# Objective

Resolves #9580

## Solution

Relaxed the bounds on the `Debug` impl for `dyn System`
2023-08-26 13:57:19 +00:00
Nicola Papale
365cf3114a
Make the reflect path parser utf-8-unaware (#9371)
# Objective

All delimiter symbols used by the path parser are ASCII, this means we
can entirely ignore UTF8 handling. This may improve performance.

## Solution

Instead of storing the path as an `&str` + the parser offset, and
reading the path using `&self.path[self.offset..]`, we store the parser
state in a `&[u8]`. This allows two optimizations:

1. Avoid UTF8 checking on `&self.path[self.offset..]`
2. Avoid any kind of bound checking, since the length of what is left to
read is stored in the `&[u8]`'s reference metadata, and is assumed valid
by the compiler.

This is a major improvement when comparing to the previous parser.

1. `access_following` and `next_token` now inline in `PathParser::next`
2. Benchmarking show a 20% performance increase (#9364)

Please note that while we ignore UTF-8 handling, **utf-8 is still
supported**. This is because we only handle "at the edges" what happens
exactly before and after a recognized `SYMBOL`. utf-8 is handled
transparently beyond that.
2023-08-25 23:12:25 +00:00
Nicola Papale
7083f0d593
Make it so ParsedPath can be passed to GetPath (#9373)
# Objective

- Unify the `ParsedPath` and `GetPath` APIs. They weirdly didn't play
well together.
- Make `ParsedPath` and `GetPath` API easier to use

## Solution

- Add the `ReflectPath` trait.
- `GetPath` methods now accept an `impl ReflectPath<'a>` instead of a
`&'a str`, this mean it also can accepts a `&ParsedPath`
- Make `GetPath: Reflect` and use default impl for `Reflect` types.
- Add `GetPath` and `ReflectPath` to the `bevy_reflect` prelude

---

## Changelog

- Add the `ReflectPath` trait.
- `GetPath` methods now accept an `impl ReflectPath<'a>` instead of a
`&'a str`, this mean it also can accept a `&ParsedPath`
- Make `GetPath: Reflect` and use default impl for `Reflect` types.
- Add `GetPath` and `ReflectPath` to the `bevy_reflect` prelude

## Migration Guide

`GetPath` now requires `Reflect`. This reduces a lot of boilerplate on
bevy's side. If you were implementing manually `GetPath` on your own
type, please get in touch!

`ParsedPath::element[_mut]` isn't an inherent method of `ParsedPath`,
you must now import `ReflectPath`. This is only relevant if you weren't
importing the bevy prelude.

```diff
-use bevy::reflect::ParsedPath;
+use bevy::reflect::{ParsedPath, ReflectPath};

 parsed_path.element(reflect_type).unwrap()
 parsed_path.element(reflect_type).unwrap()
2023-08-25 14:32:41 +00:00
Nicola Papale
7b0809b532
Add reflect path parsing benchmark (#9364)
# Objective

We want to measure performance on path reflection parsing.

## Solution

Benchmark path-based reflection:
- Add a benchmark for `ParsedPath::parse`

It's fairly noisy, this is why I added the 3% threshold.

Ideally we would fix the noisiness though. Supposedly I'm seeding the
RNG correctly, so there shouldn't be much observable variance. Maybe
someone can help spot the issue.
2023-08-25 14:30:26 +00:00
Rob Parrett
a788e31ad5
Fix CI for Rust 1.72 (#9562)
# Objective

[Rust 1.72.0](https://blog.rust-lang.org/2023/08/24/Rust-1.72.0.html) is
now stable.

# Notes

- `let-else` formatting has arrived!
- I chose to allow `explicit_iter_loop` due to
https://github.com/rust-lang/rust-clippy/issues/11074.
  
We didn't hit any of the false positives that prevent compilation, but
fixing this did produce a lot of the "symbol soup" mentioned, e.g. `for
image in &mut *image_events {`.
  
  Happy to undo this if there's consensus the other way.

---------

Co-authored-by: François <mockersf@gmail.com>
2023-08-25 12:34:24 +00:00
Robert Swain
b88ff154f2
ktx2: Fix Rgb8 -> Rgba8Unorm conversion (#9555)
# Objective

- Fixes #9552 

## Solution

- Only n_pixels bytes of data was being copied instead of 1 byte per
component, i.e. n_pixels * 4

---

## Changelog

- Fixed: loading of Rgb8 ktx2 files.
2023-08-24 00:35:52 +00:00
JMS55
228e7aa618
Add support for KHR_materials_emissive_strength (#9553)
# Objective

- Fix blender gltf imports with emissive materials
- Progress towards https://github.com/bevyengine/bevy/issues/5178

## Solution

- Upgrade to gltf-rs 1.3 supporiting
[KHR_materials_emissive_strength](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md)

---

## Changelog

- GLTF files using `emissiveStrength` (such as those exported by
blender) are now supported

## Migration Guide

- The GLTF asset loader will now factor in `emissiveStrength` when
converting to Bevy's `StandardMaterial::emissive`. Blender will export
emissive materials using this field. Remove the field from your GLTF
files or manually modify your materials post-asset-load to match how
Bevy would load these files in previous versions.
2023-08-24 00:17:44 +00:00
Tadeo Hepperle
f813831409
fix incorrect docs for JustifyItems and JustifySelf (#9539)
# Objective

Fixes incorrect docs in `bevy_ui` for `JustifyItems` and `JustifySelf`.

## Solution

`JustifyItems` and `JustifySelf` target the main axis and not the cross
axis.
2023-08-23 23:57:24 +00:00
ickshonpe
8edcd8285d
round_ties_up fix (#9548)
# Objective
`round_ties_up` checks the predicate:
```rust
0. <= value || value.fract() != 0.5
```
which is meant to determine if the value is negative with a fractional
part of `0.5`.

However given a negative value, `fract` returns a negative fraction so
the predicate is true for all numeric values and `ceil` is never called.

## Solution

Changed the predicate to `value.fract() != -0.5` and added a test.
Also improved the comments a bit.
2023-08-23 18:32:29 +00:00
ickshonpe
373f1eeb1e
UI examples clean up (#9479)
# Objective

Fix a few issues with some of the examples:

* Root UI nodes have an implicit parent with `FlexDirection::Row` and
`AlignItems::Stretch` set. Only a width constraint is needed to fill the
viewport. Specifying ```height: Val::Percent(100.)``` is unnecessary and
can cause confusing overflow behaviour.

* The default for position and size constraint properties is
`Val::Auto`. Setting `left: Val::Auto`, `max_height: Val::Auto`, etc
does nothing.


## Solution

Delete those lines. There should be no observable differences in the
behaviours of any of the examples.

Also changed a padding setting in the `flex_layout` example to use the
`axes` helper function.
2023-08-23 12:49:10 +00:00
Tristan Guichaoua
20c85b5fc3
Bevy Input Docs : the modules (#9467)
# Objective

Complete the documentation of `bevy_input` (#3492).

This PR is part of a triptych of PRs :
- https://github.com/bevyengine/bevy/pull/9468
- https://github.com/bevyengine/bevy/pull/9469

## Solution

Add documentation on modules in `bevy_input`.
2023-08-23 12:44:49 +00:00
Ame :]
427ba3074a
fix bevy imports. windows_settings.rs example (#9547)
# Objective

In #9355 was added an import using bevy_internal.
This change the import to use `bevy::window` instead of a
`bevy_internal` to run the example outside of the bevy repo.
2023-08-23 12:35:42 +00:00
Trent
ebdf5063df
Include note of common profiling issue (#9484)
- Includes a note about a common issue seen when profiling with span
based tracing tools
- Adds a table of contents to profile.md


[Rendered](https://github.com/tbillington/bevy/blob/profiling-doc-update/docs/profiling.md).


[Suggested](https://discord.com/channels/691052431525675048/866787577687310356/1141612079460139108)
by Jasmine on discord.

---------

Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
2023-08-22 14:45:54 +00:00
IceSentry
546f7fc194
Add some missing pub in ui_node (#9529)
# Objective

- A few of the `const DEFAULT` properties of the grid feature are not
marked as pub. This is an issue because it means you can't have a
`const` `Style` declaration anymore. Most of the existing properties are
already pub.

## Solution

- add the missing pub
2023-08-22 12:22:47 +00:00
IDEDARY
af0323a55e
[RAINBOW EFFECT] Added methods to get HSL components from Color (#9201)
# Changes
Added methods to Color enum to retrieve Hue, Saturation and Lightness
values.

## Why?
As you probably know, to create a color that iterates over the color
spectrum (rainbow effect that can be seen on LED keyboards, PC
components, etc..), you need to mix the color from Hue, Saturation and
Luminosity. Bevy already supports multiple color formats, but provides
only 4 methods of retrieving components for RGBA. Nothing like
".get_hue()", so I implemented them with all their variations that RGBA
has.

Now we can do true rainbow color blending (Example is a button hover
effect): [Discord
Showcase](https://discord.com/channels/691052431525675048/866787577687310356/1130960862232969400),
[Video
download](https://cdn.discordapp.com/attachments/866787577687310356/1130960861708697600/HSL_PR.mp4)


![image](https://github.com/bevyengine/bevy/assets/49441831/e8cf4905-2d09-45b3-8e5b-e6203da7fa9c)
2023-08-21 16:29:28 +00:00
François
8cd77e8cad
fix shader_material_glsl example (#9513)
# Objective

- Since #9416, example shader_material_glsl is broken
<img width="1280" alt="Screenshot 2023-08-20 at 21 08 41"
src="https://github.com/bevyengine/bevy/assets/8672791/16bc15ee-a58c-4ec6-87a8-c3799a6df74a">

## Solution

- Apply the same function as other examples, but in glsl
2023-08-21 07:58:21 +00:00