# Objective
There are a lot of doctests that are `ignore`d for no documented reason.
And that should be fixed.
## Solution
I searched the bevy repo with the regex ` ```[a-z,]*ignore ` in order to
find all `ignore`d doctests. For each one of the `ignore`d doctests, I
did the following steps:
1. Attempt to remove the `ignored` attribute while still passing the
test. I did this by adding hidden dummy structs and imports.
2. If step 1 doesn't work, attempt to replace the `ignored` attribute
with the `no_run` attribute while still passing the test.
3. If step 2 doesn't work, keep the `ignored` attribute but add
documentation for why the `ignored` attribute was added.
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Update winit dependency to 0.29
## Changelog
### KeyCode changes
- Removed `ScanCode`, as it was [replaced by
KeyCode](https://github.com/rust-windowing/winit/blob/master/CHANGELOG.md#0292).
- `ReceivedCharacter.char` is now a `SmolStr`, [relevant
doc](https://docs.rs/winit/latest/winit/event/struct.KeyEvent.html#structfield.text).
- Changed most `KeyCode` values, and added more.
KeyCode has changed meaning. With this PR, it refers to physical
position on keyboard rather than the printed letter on keyboard keys.
In practice this means:
- On QWERTY keyboard layouts, nothing changes
- On any other keyboard layout, `KeyCode` no longer reflects the label
on key.
- This is "good". In bevy 0.12, when you used WASD for movement, users
with non-QWERTY keyboards couldn't play your game! This was especially
bad for non-latin keyboards. Now, WASD represents the physical keys. A
French player will press the ZQSD keys, which are near each other,
Kyrgyz players will use "Цфыв".
- This is "bad" as well. You can't know in advance what the label of the
key for input is. Your UI says "press WASD to move", even if in reality,
they should be pressing "ZQSD" or "Цфыв". You also no longer can use
`KeyCode` for text inputs. In any case, it was a pretty bad API for text
input. You should use `ReceivedCharacter` now instead.
### Other changes
- Use `web-time` rather than `instant` crate.
(https://github.com/rust-windowing/winit/pull/2836)
- winit did split `run_return` in `run_onDemand` and `pump_events`, I
did the same change in bevy_winit and used `pump_events`.
- Removed `return_from_run` from `WinitSettings` as `winit::run` now
returns on supported platforms.
- I left the example "return_after_run" as I think it's still useful.
- This winit change is done partly to allow to create a new window after
quitting all windows: https://github.com/emilk/egui/issues/1918 ; this
PR doesn't address.
- added `width` and `height` properties in the `canvas` from wasm
example
(https://github.com/bevyengine/bevy/pull/10702#discussion_r1420567168)
## Known regressions (important follow ups?)
- Provide an API for reacting when a specific key from current layout
was released.
- possible solutions: use winit::Key from winit::KeyEvent ; mapping
between KeyCode and Key ; or .
- We don't receive characters through alt+numpad (e.g. alt + 151 = "ù")
anymore ; reproduced on winit example "ime". maybe related to
https://github.com/rust-windowing/winit/issues/2945
- (windows) Window content doesn't refresh at all when resizing. By
reading https://github.com/rust-windowing/winit/issues/2900 ; I suspect
we should just fire a `window.request_redraw();` from `AboutToWait`, and
handle actual redrawing within `RedrawRequested`. I'm not sure how to
move all that code so I'd appreciate it to be a follow up.
- (windows) unreleased winit fix for using set_control_flow in
AboutToWait https://github.com/rust-windowing/winit/issues/3215 ; ⚠️ I'm
not sure what the implications are, but that feels bad 🤔
## Follow up
I'd like to avoid bloating this PR, here are a few follow up tasks
worthy of a separate PR, or new issue to track them once this PR is
closed, as they would either complicate reviews, or at risk of being
controversial:
- remove CanvasParentResizePlugin
(https://github.com/bevyengine/bevy/pull/10702#discussion_r1417068856)
- avoid mentionning explicitly winit in docs from bevy_window ?
- NamedKey integration on bevy_input:
https://github.com/rust-windowing/winit/pull/3143 introduced a new
NamedKey variant. I implemented it only on the converters but we'd
benefit making the same changes to bevy_input.
- Add more info in KeyboardInput
https://github.com/bevyengine/bevy/pull/10702#pullrequestreview-1748336313
- https://github.com/bevyengine/bevy/pull/9905 added a workaround on a
bug allegedly fixed by winit 0.29. We should check if it's still
necessary.
- update to raw_window_handle 0.6
- blocked by wgpu
- Rename `KeyCode` to `PhysicalKeyCode`
https://github.com/bevyengine/bevy/pull/10702#discussion_r1404595015
- remove `instant` dependency, [replaced
by](https://github.com/rust-windowing/winit/pull/2836) `web_time`), we'd
need to update to :
- fastrand >= 2.0
- [`async-executor`](https://github.com/smol-rs/async-executor) >= 1.7
- [`futures-lite`](https://github.com/smol-rs/futures-lite) >= 2.0
- Verify license, see
[discussion](https://github.com/bevyengine/bevy/pull/8745#discussion_r1402439800)
- we might be missing a short notice or description of changes made
- Consider using https://github.com/rust-windowing/cursor-icon directly
rather than vendoring it in bevy.
- investigate [this
unwrap](https://github.com/bevyengine/bevy/pull/8745#discussion_r1387044986)
(`winit_window.canvas().unwrap();`)
- Use more good things about winit's update
- https://github.com/bevyengine/bevy/pull/10689#issuecomment-1823560428
## Migration Guide
This PR should have one.
# Objective
- Provide way to check whether multiple inputs are pressed.
## Solution
- Add `all_pressed` method that checks if all inputs are currently being
pressed.
# Objective
- Resolves#10853
## Solution
- ~~Changed the name of `Input` struct to `PressableInput`.~~
- Changed the name of `Input` struct to `ButtonInput`.
## Migration Guide
- Breaking Change: Users need to rename `Input` to `ButtonInput` in
their projects.
# Objective
- Shorten paths by removing unnecessary prefixes
## Solution
- Remove the prefixes from many paths which do not need them. Finding
the paths was done automatically using built-in refactoring tools in
Jetbrains RustRover.
# Objective
- Fix adding `#![allow(clippy::type_complexity)]` everywhere. like #9796
## Solution
- Use the new [lints] table that will land in 1.74
(https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#lints)
- inherit lint to the workspace, crates and examples.
```
[lints]
workspace = true
```
## Changelog
- Bump rust version to 1.74
- Enable lints table for the workspace
```toml
[workspace.lints.clippy]
type_complexity = "allow"
```
- Allow type complexity for all crates and examples
```toml
[lints]
workspace = true
```
---------
Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
# Objective
- Fixes#10532
## Solution
I've updated the various `Event` send methods to return the sent
`EventId`(s). Since these methods previously returned nothing, and this
information is cheap to copy, there should be minimal negative
consequences to providing this additional information. In the case of
`send_batch`, an iterator is returned built from `Range` and `Map`,
which only consumes 16 bytes on the stack with no heap allocations for
all batch sizes. As such, the cost of this information is negligible.
These changes are reflected for `EventWriter` and `World`. For `World`,
the return types are optional to account for the possible lack of an
`Events` resource. Again, these methods previously returned no
information, so its inclusion should only be a benefit.
## Usage
Now when sending events, the IDs of those events is available for
immediate use:
```rust
// Example of a request-response system where the requester can track handled requests.
/// A system which can make and track requests
fn requester(
mut requests: EventWriter<Request>,
mut handled: EventReader<Handled>,
mut pending: Local<HashSet<EventId<Request>>>,
) {
// Check status of previous requests
for Handled(id) in handled.read() {
pending.remove(&id);
}
if !pending.is_empty() {
error!("Not all my requests were handled on the previous frame!");
pending.clear();
}
// Send a new request and remember its ID for later
let request_id = requests.send(Request::MyRequest { /* ... */ });
pending.insert(request_id);
}
/// A system which handles requests
fn responder(
mut requests: EventReader<Request>,
mut handled: EventWriter<Handled>,
) {
for (request, id) in requests.read_with_id() {
if handle(request).is_ok() {
handled.send(Handled(id));
}
}
}
```
In the above example, a `requester` system can send request events, and
keep track of which ones are currently pending by `EventId`. Then, a
`responder` system can act on that event, providing the ID as a
reference that the `requester` can use. Before this PR, it was not
trivial for a system sending events to keep track of events by ID. This
is unfortunate, since for a system reading events, it is trivial to
access the ID of a event.
---
## Changelog
- Updated `Events`:
- Added `send_batch`
- Modified `send` to return the sent `EventId`
- Modified `send_default` to return the sent `EventId`
- Updated `EventWriter`
- Modified `send_batch` to return all sent `EventId`s
- Modified `send` to return the sent `EventId`
- Modified `send_default` to return the sent `EventId`
- Updated `World`
- Modified `send_event` to return the sent `EventId` if sent, otherwise
`None`.
- Modified `send_event_default` to return the sent `EventId` if sent,
otherwise `None`.
- Modified `send_event_batch` to return all sent `EventId`s if sent,
otherwise `None`.
- Added unit test `test_send_events_ids` to ensure returned `EventId`s
match the sent `Event`s
- Updated uses of modified methods.
## Migration Guide
### `send` / `send_default` / `send_batch`
For the following methods:
- `Events::send`
- `Events::send_default`
- `Events::send_batch`
- `EventWriter::send`
- `EventWriter::send_default`
- `EventWriter::send_batch`
- `World::send_event`
- `World::send_event_default`
- `World::send_event_batch`
Ensure calls to these methods either handle the returned value, or
suppress the result with `;`.
```rust
// Now fails to compile due to mismatched return type
fn send_my_event(mut events: EventWriter<MyEvent>) {
events.send_default()
}
// Fix
fn send_my_event(mut events: EventWriter<MyEvent>) {
events.send_default();
}
```
This will most likely be noticed within `match` statements:
```rust
// Before
match is_pressed {
true => events.send(PlayerAction::Fire),
// ^--^ No longer returns ()
false => {}
}
// After
match is_pressed {
true => {
events.send(PlayerAction::Fire);
},
false => {}
}
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
In gamepad.rs, `ButtonSettings` `is_pressed` and `is_released` are both
private, but their implementations use publicly available values.
Keeping them private forces consumers to unnecessarily re-implement this
logic, so just make them public.
# Objective
While using joysticks for player aiming, I noticed that there was as
`0.05` value snap on the axis. After searching through Bevy's code, I
saw it was the default livezone being at `0.95`. This causes any value
higher to snap to `1.0`. I think `1.0` and `-1.0` would be a better
default, as it gives all values to the joystick arc.
This default livezone stumped me for a bit as I thought either something
was broken or I was doing something wrong.
## Solution
Change the livezone defaults to ` livezone_upperbound: 1.0` and
`livezone_lowerbound: -1.0`.
---
## Migration Guide
If the default 0.05 was relied on, the default or gamepad `AxisSettings`
on the resource `GamepadSettings` will have to be changed.
# Objective
- Updates for rust 1.73
## Solution
- new doc check for `redundant_explicit_links`
- updated to text for compile fail tests
---
## Changelog
- updates for rust 1.73
# Objective
- The current `EventReader::iter` has been determined to cause confusion
among new Bevy users. It was suggested by @JoJoJet to rename the method
to better clarify its usage.
- Solves #9624
## Solution
- Rename `EventReader::iter` to `EventReader::read`.
- Rename `EventReader::iter_with_id` to `EventReader::read_with_id`.
- Rename `ManualEventReader::iter` to `ManualEventReader::read`.
- Rename `ManualEventReader::iter_with_id` to
`ManualEventReader::read_with_id`.
---
## Changelog
- `EventReader::iter` has been renamed to `EventReader::read`.
- `EventReader::iter_with_id` has been renamed to
`EventReader::read_with_id`.
- `ManualEventReader::iter` has been renamed to
`ManualEventReader::read`.
- `ManualEventReader::iter_with_id` has been renamed to
`ManualEventReader::read_with_id`.
- Deprecated `EventReader::iter`
- Deprecated `EventReader::iter_with_id`
- Deprecated `ManualEventReader::iter`
- Deprecated `ManualEventReader::iter_with_id`
## Migration Guide
- Existing usages of `EventReader::iter` and `EventReader::iter_with_id`
will have to be changed to `EventReader::read` and
`EventReader::read_with_id` respectively.
- Existing usages of `ManualEventReader::iter` and
`ManualEventReader::iter_with_id` will have to be changed to
`ManualEventReader::read` and `ManualEventReader::read_with_id`
respectively.
# Objective
Add `GamepadButtonInput` event
Resolves#8988
## Solution
- Add `GamepadButtonInput` type
- Emit `GamepadButtonInput` events whenever `Input<GamepadButton>` is
written to
- Update example
---------
Co-authored-by: François <mockersf@gmail.com>
# Objective
- Currently, (AFAIC, accidentally) after registering an event for a
Gilrs button event, we ignore all subsequent events for the same button
in the same frame, because we don't update our filter. This is rare, but
I noticed it while adding gamepad support to a terminal app rendering at
15fps.
- Related to #4664, but does not quite fix it.
## Solution
- Move the edit to the `Axis<GamepadButton>` resource to when we read
the events from Gilrs.
# Objective
**This implementation is based on
https://github.com/bevyengine/rfcs/pull/59.**
---
Resolves#4597
Full details and motivation can be found in the RFC, but here's a brief
summary.
`FromReflect` is a very powerful and important trait within the
reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to
be formed into Real ones (e.g., `Vec<i32>`, etc.).
This mainly comes into play concerning deserialization, where the
reflection deserializers both return a `Box<dyn Reflect>` that almost
always contain one of these Dynamic representations of a Real type. To
convert this to our Real type, we need to use `FromReflect`.
It also sneaks up in other ways. For example, it's a required bound for
`T` in `Vec<T>` so that `Vec<T>` as a whole can be made `FromReflect`.
It's also required by all fields of an enum as it's used as part of the
`Reflect::apply` implementation.
So in other words, much like `GetTypeRegistration` and `Typed`, it is
very much a core reflection trait.
The problem is that it is not currently treated like a core trait and is
not automatically derived alongside `Reflect`. This makes using it a bit
cumbersome and easy to forget.
## Solution
Automatically derive `FromReflect` when deriving `Reflect`.
Users can then choose to opt-out if needed using the
`#[reflect(from_reflect = false)]` attribute.
```rust
#[derive(Reflect)]
struct Foo;
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Bar;
fn test<T: FromReflect>(value: T) {}
test(Foo); // <-- OK
test(Bar); // <-- Panic! Bar does not implement trait `FromReflect`
```
#### `ReflectFromReflect`
This PR also automatically adds the `ReflectFromReflect` (introduced in
#6245) registration to the derived `GetTypeRegistration` impl— if the
type hasn't opted out of `FromReflect` of course.
<details>
<summary><h4>Improved Deserialization</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
And since we can do all the above, we might as well improve
deserialization. We can now choose to deserialize into a Dynamic type or
automatically convert it using `FromReflect` under the hood.
`[Un]TypedReflectDeserializer::new` will now perform the conversion and
return the `Box`'d Real type.
`[Un]TypedReflectDeserializer::new_dynamic` will work like what we have
now and simply return the `Box`'d Dynamic type.
```rust
// Returns the Real type
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
// Returns the Dynamic type
let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
```
</details>
---
## Changelog
* `FromReflect` is now automatically derived within the `Reflect` derive
macro
* This includes auto-registering `ReflectFromReflect` in the derived
`GetTypeRegistration` impl
* ~~Renamed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped**
* ~~Changed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to automatically convert the
deserialized output using `FromReflect`~~ **Descoped**
## Migration Guide
* `FromReflect` is now automatically derived within the `Reflect` derive
macro. Items with both derives will need to remove the `FromReflect`
one.
```rust
// OLD
#[derive(Reflect, FromReflect)]
struct Foo;
// NEW
#[derive(Reflect)]
struct Foo;
```
If using a manual implementation of `FromReflect` and the `Reflect`
derive, users will need to opt-out of the automatic implementation.
```rust
// OLD
#[derive(Reflect)]
struct Foo;
impl FromReflect for Foo {/* ... */}
// NEW
#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Foo;
impl FromReflect for Foo {/* ... */}
```
<details>
<summary><h4>Removed Migrations</h4></summary>
> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.
* The reflect deserializers now perform a `FromReflect` conversion
internally. The expected output of `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` is no longer a Dynamic (e.g.,
`DynamicList`), but its Real counterpart (e.g., `Vec<i32>`).
```rust
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
// OLD
let output: DynamicStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
// NEW
let output: SomeStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
```
Alternatively, if this behavior isn't desired, use the
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic` methods instead:
```rust
// OLD
let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
// NEW
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(®istry);
```
</details>
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Add a get_unclamped method to
[Axis](https://docs.rs/bevy/0.10.1/bevy/input/struct.Axis.html) to allow
it to be used in cases where being able to get a precise relative
movement is important. For example, camera zoom with the mouse wheel.
This would make it possible for libraries like leafwing input manager to
leverage `Axis` for mouse motion and mouse wheel axis mapping. I tried
to use it my PR here
https://github.com/Leafwing-Studios/leafwing-input-manager/pull/346 but
will likely have to revert that and read the mouse wheel events for now
which is what prompted this PR.
## Solution
Instead of clamping the axis value when it is set, it now stores the raw
value and clamps it in the `get` method. This allows a simple
get_unclamped method that just returns the raw value.
## Changelog
- Added a get_unclamped method to Axis that can return values outside of
-1.0 to 1.0
# Objective
Discovered that PointLight did not implement FromReflect. Adding
FromReflect where Reflect is used. I overreached and applied this rule
everywhere there was a Reflect without a FromReflect, except from where
the compiler wouldn't allow me.
Based from question: https://github.com/bevyengine/bevy/discussions/8774
## Solution
- Adding FromReflect where Reflect was already derived
## Notes
First PR I do in this ecosystem, so not sure if this is the usual
approach, that is, to touch many files at once.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
The goal of this PR is to receive touchpad magnification and rotation
events.
## Solution
Implement pendants for winit's `TouchpadMagnify` and `TouchpadRotate`
events.
Adjust the `mouse_input_events.rs` example to debug magnify and rotate
events.
Since winit only reports these events on macOS, the Bevy events for
touchpad magnification and rotation are currently only fired on macOS.
# Objective
Be consistent with `Resource`s and `Components` and have `Event` types
be more self-documenting.
Although not susceptible to accidentally using a function instead of a
value due to `Event`s only being initialized by their type, much of the
same reasoning for removing the blanket impl on `Resource` also applies
here.
* Not immediately obvious if a type is intended to be an event
* Prevent invisible conflicts if the same third-party or primitive types
are used as events
* Allows for further extensions (e.g. opt-in warning for missed events)
## Solution
Remove the blanket impl for the `Event` trait. Add a derive macro for
it.
---
## Changelog
- `Event` is no longer implemented for all applicable types. Add the
`#[derive(Event)]` macro for events.
## Migration Guide
* Add the `#[derive(Event)]` macro for events. Third-party types used as
events should be wrapped in a newtype.
# Objective
- Introduce a stable alternative to
[`std::any::type_name`](https://doc.rust-lang.org/std/any/fn.type_name.html).
- Rewrite of #5805 with heavy inspiration in design.
- On the path to #5830.
- Part of solving #3327.
## Solution
- Add a `TypePath` trait for static stable type path/name information.
- Add a `TypePath` derive macro.
- Add a `impl_type_path` macro for implementing internal and foreign
types in `bevy_reflect`.
---
## Changelog
- Added `TypePath` trait.
- Added `DynamicTypePath` trait and `get_type_path` method to `Reflect`.
- Added a `TypePath` derive macro.
- Added a `bevy_reflect::impl_type_path` for implementing `TypePath` on
internal and foreign types in `bevy_reflect`.
- Changed `bevy_reflect::utility::(Non)GenericTypeInfoCell` to
`(Non)GenericTypedCell<T>` which allows us to be generic over both
`TypeInfo` and `TypePath`.
- `TypePath` is now a supertrait of `Asset`, `Material` and
`Material2d`.
- `impl_reflect_struct` needs a `#[type_path = "..."]` attribute to be
specified.
- `impl_reflect_value` needs to either specify path starting with a
double colon (`::core::option::Option`) or an `in my_crate::foo`
declaration.
- Added `bevy_reflect_derive::ReflectTypePath`.
- Most uses of `Ident` in `bevy_reflect_derive` changed to use
`ReflectTypePath`.
## Migration Guide
- Implementors of `Asset`, `Material` and `Material2d` now also need to
derive `TypePath`.
- Manual implementors of `Reflect` will need to implement the new
`get_type_path` method.
## Open Questions
- [x] ~This PR currently does not migrate any usages of
`std::any::type_name` to use `bevy_reflect::TypePath` to ease the review
process. Should it?~ Migration will be left to a follow-up PR.
- [ ] This PR adds a lot of `#[derive(TypePath)]` and `T: TypePath` to
satisfy new bounds, mostly when deriving `TypeUuid`. Should we make
`TypePath` a supertrait of `TypeUuid`? [Should we remove `TypeUuid` in
favour of
`TypePath`?](2afbd85532 (r961067892))
# Objective
there were typos in AxisSettings livezone/deadzone get/set function doc
comments.
## Solution
I changed the comments to be (hopefully) correct this time. I could be
wrong though.
# Objective
there was a typo in AxisSettings. It said "Values that are higher than
`livezone_upperbound` will be rounded up to -1.0." which I'm pretty
confident should be "1.0".
## Solution
I removed the '-'
# Objective
Provide the ability to trigger controller rumbling (force-feedback) with
a cross-platform API.
## Solution
This adds the `GamepadRumbleRequest` event to `bevy_input` and adds a
system in `bevy_gilrs` to read them and rumble controllers accordingly.
It's a relatively primitive API with a `duration` in seconds and
`GamepadRumbleIntensity` with values for the weak and strong gamepad
motors. It's is an almost 1-to-1 mapping to platform APIs. Some
platforms refer to these motors as left and right, and low frequency and
high frequency, but by convention, they're usually the same.
I used #3868 as a starting point, updated to main, removed the low-level
gilrs effect API, and moved the requests to `bevy_input` and exposed the
strong and weak intensities.
I intend this to hopefully be a non-controversial cross-platform
starting point we can build upon to eventually support more fine-grained
control (closer to the gilrs effect API)
---
## Changelog
### Added
- Gamepads can now be rumbled by sending the `GamepadRumbleRequest`
event.
---------
Co-authored-by: Nicola Papale <nico@nicopap.ch>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
Co-authored-by: Bruce Reif (Buswolley) <bruce.reif@dynata.com>
Links in the api docs are nice. I noticed that there were several places
where structs / functions and other things were referenced in the docs,
but weren't linked. I added the links where possible / logical.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: François <mockersf@gmail.com>
Fixes issue mentioned in PR #8285.
_Note: By mistake, this is currently dependent on #8285_
# Objective
Ensure consistency in the spelling of the documentation.
Exceptions:
`crates/bevy_mikktspace/src/generated.rs` - Has not been changed from
licence to license as it is part of a licensing agreement.
Maybe for further consistency,
https://github.com/bevyengine/bevy-website should also be given a look.
## Solution
### Changed the spelling of the current words (UK/CN/AU -> US) :
cancelled -> canceled (Breaking API changes in #8285)
behaviour -> behavior (Breaking API changes in #8285)
neighbour -> neighbor
grey -> gray
recognise -> recognize
centre -> center
metres -> meters
colour -> color
### ~~Update [`engine_style_guide.md`]~~ Moved to #8324
---
## Changelog
Changed UK spellings in documentation to US
## Migration Guide
Non-breaking changes*
\* If merged after #8285
# Objective
The clippy lint `type_complexity` is known not to play well with bevy.
It frequently triggers when writing complex queries, and taking the
lint's advice of using a type alias almost always just obfuscates the
code with no benefit. Because of this, this lint is currently ignored in
CI, but unfortunately it still shows up when viewing bevy code in an
IDE.
As someone who's made a fair amount of pull requests to this repo, I
will say that this issue has been a consistent thorn in my side. Since
bevy code is filled with spurious, ignorable warnings, it can be very
difficult to spot the *real* warnings that must be fixed -- most of the
time I just ignore all warnings, only to later find out that one of them
was real after I'm done when CI runs.
## Solution
Suppress this lint in all bevy crates. This was previously attempted in
#7050, but the review process ended up making it more complicated than
it needs to be and landed on a subpar solution.
The discussion in https://github.com/rust-lang/rust-clippy/pull/10571
explores some better long-term solutions to this problem. Since there is
no timeline on when these solutions may land, we should resolve this
issue in the meantime by locally suppressing these lints.
### Unresolved issues
Currently, these lints are not suppressed in our examples, since that
would require suppressing the lint in every single source file. They are
still ignored in CI.
# Objective
In the
[`Text`](3442a13d2c/crates/bevy_text/src/text.rs (L18))
struct the field is named: `linebreak_behaviour`, the British spelling
of _behavior_.
**Update**, also found:
- `FileDragAndDrop::HoveredFileCancelled`
- `TouchPhase::Cancelled`
- `Touches.just_cancelled`
The majority of all spelling is in the US but when you have a lot of
contributors across the world, sometimes
spelling differences can pop up in APIs such as in this case.
For consistency, I think it would be worth a while to ensure that the
API is persistent.
Some examples:
`from_reflect.rs` has `DefaultBehavior`
TextStyle has `color` and uses the `Color` struct.
In `bevy_input/src/Touch.rs` `TouchPhase::Cancelled` and _canceled_ are
used interchangeably in the documentation
I've found that there is also the same type of discrepancies in the
documentation, though this is a low priority but is worth checking.
**Update**: I've now checked the documentation (See #8291)
## Solution
I've only renamed the inconsistencies that have breaking changes and
documentation pertaining to them. The rest of the documentation will be
changed via #8291.
Do note that the winit API is written with UK spelling, thus this may be
a cause for confusion:
`winit::event::TouchPhase::Cancelled => TouchPhase::Canceled`
`winit::event::WindowEvent::HoveredFileCancelled` -> Related to
`FileDragAndDrop::HoveredFileCanceled`
But I'm hoping to maybe outline other spelling inconsistencies in the
API, and maybe an addition to the contribution guide.
---
## Changelog
- `Text` field `linebreak_behaviour` has been renamed to
`linebreak_behavior`.
- Event `FileDragAndDrop::HoveredFileCancelled` has been renamed to
`HoveredFileCanceled`
- Function `Touches.just_cancelled` has been renamed to
`Touches.just_canceled`
- Event `TouchPhase::Cancelled` has been renamed to
`TouchPhase::Canceled`
## Migration Guide
Update where `linebreak_behaviour` is used to `linebreak_behavior`
Updated the event `FileDragAndDrop::HoveredFileCancelled` where used to
`HoveredFileCanceled`
Update `Touches.just_cancelled` where used as `Touches.just_canceled`
The event `TouchPhase::Cancelled` is now called `TouchPhase::Canceled`
# Objective
Common run conditions can be very useful for quick and ergonomic changes to when a system runs.
Specifically what I'd like to be able to do is
```rust
use bevy::prelude::*;
use bevy::input::common_conditions::input_toggle_active;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(
bevy_inspector_egui::quick::WorldInspectorPlugin::default()
.run_if(input_toggle_active(true, KeyCode::Escape)
)
.run();
}
```
## Solution
- add `bevy_input::common_conditions` module with `input_toggle_active`, `input_pressed`, `input_just_pressed`, `input_just_released`
## Changelog
- added common run conditions for `bevy_input`
- you can now use `.add_system(jump.run_if(input_just_pressed(KeyCode::Space)))`
# Objective
NOTE: This depends on #7267 and should not be merged until #7267 is merged. If you are reviewing this before that is merged, I highly recommend viewing the Base Sets commit instead of trying to find my changes amongst those from #7267.
"Default sets" as described by the [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45) have some [unfortunate consequences](https://github.com/bevyengine/bevy/discussions/7365).
## Solution
This adds "base sets" as a variant of `SystemSet`:
A set is a "base set" if `SystemSet::is_base` returns `true`. Typically this will be opted-in to using the `SystemSet` derive:
```rust
#[derive(SystemSet, Clone, Hash, Debug, PartialEq, Eq)]
#[system_set(base)]
enum MyBaseSet {
A,
B,
}
```
**Base sets are exclusive**: a system can belong to at most one "base set". Adding a system to more than one will result in an error. When possible we fail immediately during system-config-time with a nice file + line number. For the more nested graph-ey cases, this will fail at the final schedule build.
**Base sets cannot belong to other sets**: this is where the word "base" comes from
Systems and Sets can only be added to base sets using `in_base_set`. Calling `in_set` with a base set will fail. As will calling `in_base_set` with a normal set.
```rust
app.add_system(foo.in_base_set(MyBaseSet::A))
// X must be a normal set ... base sets cannot be added to base sets
.configure_set(X.in_base_set(MyBaseSet::A))
```
Base sets can still be configured like normal sets:
```rust
app.add_system(MyBaseSet::B.after(MyBaseSet::Ap))
```
The primary use case for base sets is enabling a "default base set":
```rust
schedule.set_default_base_set(CoreSet::Update)
// this will belong to CoreSet::Update by default
.add_system(foo)
// this will override the default base set with PostUpdate
.add_system(bar.in_base_set(CoreSet::PostUpdate))
```
This allows us to build apis that work by default in the standard Bevy style. This is a rough analog to the "default stage" model, but it use the new "stageless sets" model instead, with all of the ordering flexibility (including exclusive systems) that it provides.
---
## Changelog
- Added "base sets" and ported CoreSet to use them.
## Migration Guide
TODO
Huge thanks to @maniwani, @devil-ira, @hymm, @cart, @superdump and @jakobhellermann for the help with this PR.
# Objective
- Followup #6587.
- Minimal integration for the Stageless Scheduling RFC: https://github.com/bevyengine/rfcs/pull/45
## Solution
- [x] Remove old scheduling module
- [x] Migrate new methods to no longer use extension methods
- [x] Fix compiler errors
- [x] Fix benchmarks
- [x] Fix examples
- [x] Fix docs
- [x] Fix tests
## Changelog
### Added
- a large number of methods on `App` to work with schedules ergonomically
- the `CoreSchedule` enum
- `App::add_extract_system` via the `RenderingAppExtension` trait extension method
- the private `prepare_view_uniforms` system now has a public system set for scheduling purposes, called `ViewSet::PrepareUniforms`
### Removed
- stages, and all code that mentions stages
- states have been dramatically simplified, and no longer use a stack
- `RunCriteriaLabel`
- `AsSystemLabel` trait
- `on_hierarchy_reports_enabled` run criteria (now just uses an ad hoc resource checking run condition)
- systems in `RenderSet/Stage::Extract` no longer warn when they do not read data from the main world
- `RunCriteriaLabel`
- `transform_propagate_system_set`: this was a nonstandard pattern that didn't actually provide enough control. The systems are already `pub`: the docs have been updated to ensure that the third-party usage is clear.
### Changed
- `System::default_labels` is now `System::default_system_sets`.
- `App::add_default_labels` is now `App::add_default_sets`
- `CoreStage` and `StartupStage` enums are now `CoreSet` and `StartupSet`
- `App::add_system_set` was renamed to `App::add_systems`
- The `StartupSchedule` label is now defined as part of the `CoreSchedules` enum
- `.label(SystemLabel)` is now referred to as `.in_set(SystemSet)`
- `SystemLabel` trait was replaced by `SystemSet`
- `SystemTypeIdLabel<T>` was replaced by `SystemSetType<T>`
- The `ReportHierarchyIssue` resource now has a public constructor (`new`), and implements `PartialEq`
- Fixed time steps now use a schedule (`CoreSchedule::FixedTimeStep`) rather than a run criteria.
- Adding rendering extraction systems now panics rather than silently failing if no subapp with the `RenderApp` label is found.
- the `calculate_bounds` system, with the `CalculateBounds` label, is now in `CoreSet::Update`, rather than in `CoreSet::PostUpdate` before commands are applied.
- `SceneSpawnerSystem` now runs under `CoreSet::Update`, rather than `CoreStage::PreUpdate.at_end()`.
- `bevy_pbr::add_clusters` is no longer an exclusive system
- the top level `bevy_ecs::schedule` module was replaced with `bevy_ecs::scheduling`
- `tick_global_task_pools_on_main_thread` is no longer run as an exclusive system. Instead, it has been replaced by `tick_global_task_pools`, which uses a `NonSend` resource to force running on the main thread.
## Migration Guide
- Calls to `.label(MyLabel)` should be replaced with `.in_set(MySet)`
- Stages have been removed. Replace these with system sets, and then add command flushes using the `apply_system_buffers` exclusive system where needed.
- The `CoreStage`, `StartupStage, `RenderStage` and `AssetStage` enums have been replaced with `CoreSet`, `StartupSet, `RenderSet` and `AssetSet`. The same scheduling guarantees have been preserved.
- Systems are no longer added to `CoreSet::Update` by default. Add systems manually if this behavior is needed, although you should consider adding your game logic systems to `CoreSchedule::FixedTimestep` instead for more reliable framerate-independent behavior.
- Similarly, startup systems are no longer part of `StartupSet::Startup` by default. In most cases, this won't matter to you.
- For example, `add_system_to_stage(CoreStage::PostUpdate, my_system)` should be replaced with
- `add_system(my_system.in_set(CoreSet::PostUpdate)`
- When testing systems or otherwise running them in a headless fashion, simply construct and run a schedule using `Schedule::new()` and `World::run_schedule` rather than constructing stages
- Run criteria have been renamed to run conditions. These can now be combined with each other and with states.
- Looping run criteria and state stacks have been removed. Use an exclusive system that runs a schedule if you need this level of control over system control flow.
- For app-level control flow over which schedules get run when (such as for rollback networking), create your own schedule and insert it under the `CoreSchedule::Outer` label.
- Fixed timesteps are now evaluated in a schedule, rather than controlled via run criteria. The `run_fixed_timestep` system runs this schedule between `CoreSet::First` and `CoreSet::PreUpdate` by default.
- Command flush points introduced by `AssetStage` have been removed. If you were relying on these, add them back manually.
- Adding extract systems is now typically done directly on the main app. Make sure the `RenderingAppExtension` trait is in scope, then call `app.add_extract_system(my_system)`.
- the `calculate_bounds` system, with the `CalculateBounds` label, is now in `CoreSet::Update`, rather than in `CoreSet::PostUpdate` before commands are applied. You may need to order your movement systems to occur before this system in order to avoid system order ambiguities in culling behavior.
- the `RenderLabel` `AppLabel` was renamed to `RenderApp` for clarity
- `App::add_state` now takes 0 arguments: the starting state is set based on the `Default` impl.
- Instead of creating `SystemSet` containers for systems that run in stages, simply use `.on_enter::<State::Variant>()` or its `on_exit` or `on_update` siblings.
- `SystemLabel` derives should be replaced with `SystemSet`. You will also need to add the `Debug`, `PartialEq`, `Eq`, and `Hash` traits to satisfy the new trait bounds.
- `with_run_criteria` has been renamed to `run_if`. Run criteria have been renamed to run conditions for clarity, and should now simply return a bool.
- States have been dramatically simplified: there is no longer a "state stack". To queue a transition to the next state, call `NextState::set`
## TODO
- [x] remove dead methods on App and World
- [x] add `App::add_system_to_schedule` and `App::add_systems_to_schedule`
- [x] avoid adding the default system set at inappropriate times
- [x] remove any accidental cycles in the default plugins schedule
- [x] migrate benchmarks
- [x] expose explicit labels for the built-in command flush points
- [x] migrate engine code
- [x] remove all mentions of stages from the docs
- [x] verify docs for States
- [x] fix uses of exclusive systems that use .end / .at_start / .before_commands
- [x] migrate RenderStage and AssetStage
- [x] migrate examples
- [x] ensure that transform propagation is exported in a sufficiently public way (the systems are already pub)
- [x] ensure that on_enter schedules are run at least once before the main app
- [x] re-enable opt-in to execution order ambiguities
- [x] revert change to `update_bounds` to ensure it runs in `PostUpdate`
- [x] test all examples
- [x] unbreak directional lights
- [x] unbreak shadows (see 3d_scene, 3d_shape, lighting, transparaency_3d examples)
- [x] game menu example shows loading screen and menu simultaneously
- [x] display settings menu is a blank screen
- [x] `without_winit` example panics
- [x] ensure all tests pass
- [x] SubApp doc test fails
- [x] runs_spawn_local tasks fails
- [x] [Fix panic_when_hierachy_cycle test hanging](https://github.com/alice-i-cecile/bevy/pull/120)
## Points of Difficulty and Controversy
**Reviewers, please give feedback on these and look closely**
1. Default sets, from the RFC, have been removed. These added a tremendous amount of implicit complexity and result in hard to debug scheduling errors. They're going to be tackled in the form of "base sets" by @cart in a followup.
2. The outer schedule controls which schedule is run when `App::update` is called.
3. I implemented `Label for `Box<dyn Label>` for our label types. This enables us to store schedule labels in concrete form, and then later run them. I ran into the same set of problems when working with one-shot systems. We've previously investigated this pattern in depth, and it does not appear to lead to extra indirection with nested boxes.
4. `SubApp::update` simply runs the default schedule once. This sucks, but this whole API is incomplete and this was the minimal changeset.
5. `time_system` and `tick_global_task_pools_on_main_thread` no longer use exclusive systems to attempt to force scheduling order
6. Implemetnation strategy for fixed timesteps
7. `AssetStage` was migrated to `AssetSet` without reintroducing command flush points. These did not appear to be used, and it's nice to remove these bottlenecks.
8. Migration of `bevy_render/lib.rs` and pipelined rendering. The logic here is unusually tricky, as we have complex scheduling requirements.
## Future Work (ideally before 0.10)
- Rename schedule_v3 module to schedule or scheduling
- Add a derive macro to states, and likely a `EnumIter` trait of some form
- Figure out what exactly to do with the "systems added should basically work by default" problem
- Improve ergonomics for working with fixed timesteps and states
- Polish FixedTime API to match Time
- Rebase and merge #7415
- Resolve all internal ambiguities (blocked on better tools, especially #7442)
- Add "base sets" to replace the removed default sets.
# Objective
- Bevy should not have any "internal" execution order ambiguities. These clutter the output of user-facing error reporting, and can result in nasty, nondetermistic, very difficult to solve bugs.
- Verifying this currently involves repeated non-trivial manual work.
## Solution
- [x] add an example to quickly check this
- ~~[ ] ensure that this example panics if there are any unresolved ambiguities~~
- ~~[ ] run the example in CI 😈~~
There's one tricky ambiguity left, between UI and animation. I don't have the tools to fix this without system set configuration, so the remaining work is going to be left to #7267 or another PR after that.
```
2023-01-27T18:38:42.989405Z INFO bevy_ecs::schedule::ambiguity_detection: Execution order ambiguities detected, you might want to add an explicit dependency relation between some of these systems:
* Parallel systems:
-- "bevy_animation::animation_player" and "bevy_ui::flex::flex_node_system"
conflicts: ["bevy_transform::components::transform::Transform"]
```
## Changelog
Resolved internal execution order ambiguities for:
1. Transform propagation (ignored, we need smarter filter checking).
2. Gamepad processing (fixed).
3. bevy_winit's window handling (fixed).
4. Cascaded shadow maps and perspectives (fixed).
Also fixed a desynchronized state bug that could occur when the `Window` component is removed and then added to the same entity in a single frame.
# Objective
I found several words in code and docs are incorrect. This should be fixed.
## Solution
- Fix several minor typos
Co-authored-by: Chris Ohk <utilforever@gmail.com>
# Objective
- Fixes a bug where `just_pressed` and `just_released` in `Input<GamepadButton>` might behave incorrectly due calling `clear` 3 times in a single frame through these three different systems: `gamepad_button_event_system`, `gamepad_axis_event_system` and `gamepad_connection_system` in any order
## Solution
- Call `clear` only once and before all the above three systems, i.e. in `gamepad_event_system`
## Additional Info
- Discussion in Discord: https://discord.com/channels/691052431525675048/768253008416342076/1064621963693273279
# Objective
Currently, the `AxisSettings::new` function is unusable due to
an implementation quirk. It only allows `AxisSettings` where
the bounds that are supposed to be positive are negative!
## Solution
- We fix the bound check
- We add a test to make sure the method is usable
Seems like the error slipped through because of the relatively
verbose code style. With all those `if/else`, very long names,
range syntax, the bound check is actually hard to spot. I first
refactored a lot of code, but I left out the refactor because the
fix should be integrated independently.
---
## Changelog
- Fix `AxisSettings::new` only accepting invalid bounds
# Objective
- Fixes#7066
## Solution
- Split the ChangeDetection trait into ChangeDetection and ChangeDetectionMut
- Added Ref as equivalent to &T with change detection
---
## Changelog
- Support for Ref which allow inspecting change detection flags in an immutable way
## Migration Guide
- While bevy prelude includes both ChangeDetection and ChangeDetectionMut any code explicitly referencing ChangeDetection might need to be updated to ChangeDetectionMut or both. Specifically any reading logic requires ChangeDetection while writes requires ChangeDetectionMut.
use bevy_ecs::change_detection::DetectChanges -> use bevy_ecs::change_detection::{DetectChanges, DetectChangesMut}
- Previously Res had methods to access change detection `is_changed` and `is_added` those methods have been moved to the `DetectChanges` trait. If you are including bevy prelude you will have access to these types otherwise you will need to `use bevy_ecs::change_detection::DetectChanges` to continue using them.
# Objective
- Remove redundant gamepad events
- Simplify consuming gamepad events.
- Refactor: Separate handling of gamepad events into multiple systems.
## Solution
- Removed `GamepadEventRaw`, and `GamepadEventType`.
- Added bespoke `GamepadConnectionEvent`, `GamepadAxisChangedEvent`, and `GamepadButtonChangedEvent`.
- Refactored `gamepad_event_system`.
- Added `gamepad_button_event_system`, `gamepad_axis_event_system`, and `gamepad_connection_system`, which update the `Input` and `Axis` resources using their corresponding event type.
Gamepad events are now handled in their own systems and have their own types.
This allows for querying for gamepad events without having to match on `GamepadEventType` and makes creating handlers for specific gamepad event types, like a `GamepadConnectionEvent` or `GamepadButtonChangedEvent` possible.
We remove `GamepadEventRaw` by filtering the gamepad events, using `GamepadSettings`, _at the source_, in `bevy_gilrs`. This way we can create `GamepadEvent`s directly and avoid creating `GamepadEventRaw` which do not pass the user defined filters.
We expose ordered `GamepadEvent`s and we can respond to individual gamepad event types.
## Migration Guide
- Replace `GamepadEvent` and `GamepadEventRaw` types with their specific gamepad event type.
(github made me type out a message for the commit which looked like it was for the pr, sorry)
# Objective
- Add a way to get all of the input devices of an `Axis`, primarily useful for looping through them
## Solution
- Adds `Axis<T>::devices()` which returns a `FixedSizeIterator<Item = &T>`
- Adds a (probably unneeded) `test_axis_devices` test because tests are cool.
---
## Changelog
- Added `Axis<T>::devices()` method
## Migration Guide
Not a breaking change.
# Objective
The [documentation for `ButtonSettingsError`](https://docs.rs/bevy/0.9.0/bevy/input/gamepad/enum.ButtonSettingsError.html) incorrectly describes the valid range of values as `0.0..=2.0`, probably because it was copied from `AxisSettingsError`. The actual range, as seen in the functions that return it and in its own `thiserror` description, is `0.0..=1.0`.
## Solution
Update the doc comments to reflect the correct range.
Co-authored-by: Sol Toder <ajaxgb@gmail.com>
This reverts commit 53d387f340.
# Objective
Reverts #6448. This didn't have the intended effect: we're now getting bevy::prelude shown in the docs again.
Co-authored-by: Alejandro Pascual <alejandro.pascual.pozo@gmail.com>
# Objective
- Right now re-exports are completely hidden in prelude docs.
- Fixes#6433
## Solution
- We could show the re-exports without inlining their documentation.
# Objective
Adds support for reflecting many more of the input types. This allows those types to be used via scripting, `bevy-inspector-egui`, etc. These types are registered by the `InputPlugin` so that they're automatically available to anyone who wants to use them
Closes#6223
## Solution
Many types now have `#[derive(Reflect, FromReflect)]` added to them in `bevy_input`. Additionally, `#[reflect(traits...)]` has been added for applicable traits to the types.
This PR does not add reflection support for types which have private fields. Notably, `Touch` and `Touches` don't implement `Reflect`/`FromReflect`.
This adds the "glam" feature to the `bevy_reflect` dependency for package `bevy_input`. Since `bevy_input` transitively depends on `glam` already, all this brings in are the reflection `impl`s.
## Migration Guide
- `Input<T>` now implements `Reflect` via `#[reflect]` instead of `#[reflect_value]`. This means it now exposes its private fields via the `Reflect` trait rather than being treated as a value type. For code that relies on the `Input<T>` struct being treated as a value type by reflection, it is still possible to wrap the `Input<T>` type with a wrapper struct and apply `#[reflect_value]` to it.
- As a reminder, private fields exposed via reflection are not subject to any stability guarantees.
---
## Changelog
Added
- Implemented `Reflect` + `FromReflect` for many input-related types. These types are automatically registered when adding the `InputPlugin`.
# Objective
Fixes#6339.
## Solution
This PR adds a new type, `GamepadInfo`, which holds metadata associated with a particular `Gamepad`. The `Gamepads` resource now holds a `HashMap<Gamepad, GamepadInfo>`. The `GamepadInfo` is created when the gamepad backend (by default `bevy_gilrs`) emits a "gamepad connected" event.
The `gamepad_viewer` example has been updated to showcase the new functionality.
Before:
![bevy-gamepad-old](https://user-images.githubusercontent.com/86984145/197359427-2130a3c0-bd8a-4683-ae24-2a9eaa98b586.png)
After:
![bevy-gamepad-new](https://user-images.githubusercontent.com/86984145/197359429-f7963163-df26-4906-af7f-6186fe3bd338.png)
---
## Changelog
### Added
- Added `GamepadInfo`.
- Added `Gamepads::name()`, which returns the name of the specified gamepad if it exists.
### Changed
- `GamepadEventType::Connected` is now a tuple variant with a single field of type `GamepadInfo`.
- Since `GamepadInfo` is not `Copy`, `GamepadEventType` is no longer `Copy`. The same is true of `GamepadEvent` and `GamepadEventRaw`.
## Migration Guide
- Pattern matches on `GamepadEventType::Connected` will need to be updated, as the form of the variant has changed.
- Code that requires `GamepadEvent`, `GamepadEventRaw` or `GamepadEventType` to be `Copy` will need to be updated.
# Objective
Fixes https://github.com/bevyengine/bevy/issues/3418
## Solution
Originally a rebase of https://github.com/bevyengine/bevy/pull/3446. Work was originally done by mfdorst, who should receive considerable credit. Then the error types were extensively reworked by targrub.
## Migration Guide
`AxisSettings` now has a `new()`, which may return an `AxisSettingsError`.
`AxisSettings` fields made private; now must be accessed through getters and setters. There's a dead zone, from `.deadzone_upperbound()` to `.deadzone_lowerbound()`, and a live zone, from `.deadzone_upperbound()` to `.livezone_upperbound()` and from `.deadzone_lowerbound()` to `.livezone_lowerbound()`.
`AxisSettings` setters no longer panic.
`ButtonSettings` fields made private; now must be accessed through getters and setters.
`ButtonSettings` now has a `new()`, which may return a `ButtonSettingsError`.
Co-authored-by: targrub <62773321+targrub@users.noreply.github.com>
# Objective
- `process_touch_event` in `bevy_input` don't update position info. `TouchPhase::Ended` and `TouchPhase::Cancelled` should use the position info from `pressed`. Otherwise, it'll not update. The position info is updated from `TouchPhase::Moved`.
## Solution
- Use updated touch info.
---
## Changelog
> This section is optional. If this was a trivial fix, or has no externally-visible impact, feel free to skip this section.
- Fixed: bevy_input, fix process touch event, update touch info
# Objective
The [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45) involves allowing exclusive systems to be referenced and ordered relative to parallel systems. We've agreed that unifying systems under `System` is the right move.
This is an alternative to #4166 (see rationale in the comments I left there). Note that this builds on the learnings established there (and borrows some patterns).
## Solution
This unifies parallel and exclusive systems under the shared `System` trait, removing the old `ExclusiveSystem` trait / impls. This is accomplished by adding a new `ExclusiveFunctionSystem` impl similar to `FunctionSystem`. It is backed by `ExclusiveSystemParam`, which is similar to `SystemParam`. There is a new flattened out SystemContainer api (which cuts out a lot of trait and type complexity).
This means you can remove all cases of `exclusive_system()`:
```rust
// before
commands.add_system(some_system.exclusive_system());
// after
commands.add_system(some_system);
```
I've also implemented `ExclusiveSystemParam` for `&mut QueryState` and `&mut SystemState`, which makes this possible in exclusive systems:
```rust
fn some_exclusive_system(
world: &mut World,
transforms: &mut QueryState<&Transform>,
state: &mut SystemState<(Res<Time>, Query<&Player>)>,
) {
for transform in transforms.iter(world) {
println!("{transform:?}");
}
let (time, players) = state.get(world);
for player in players.iter() {
println!("{player:?}");
}
}
```
Note that "exclusive function systems" assume `&mut World` is present (and the first param). I think this is a fair assumption, given that the presence of `&mut World` is what defines the need for an exclusive system.
I added some targeted SystemParam `static` constraints, which removed the need for this:
``` rust
fn some_exclusive_system(state: &mut SystemState<(Res<'static, Time>, Query<&'static Player>)>) {}
```
## Related
- #2923
- #3001
- #3946
## Changelog
- `ExclusiveSystem` trait (and implementations) has been removed in favor of sharing the `System` trait.
- `ExclusiveFunctionSystem` and `ExclusiveSystemParam` were added, enabling flexible exclusive function systems
- `&mut SystemState` and `&mut QueryState` now implement `ExclusiveSystemParam`
- Exclusive and parallel System configuration is now done via a unified `SystemDescriptor`, `IntoSystemDescriptor`, and `SystemContainer` api.
## Migration Guide
Calling `.exclusive_system()` is no longer required (or supported) for converting exclusive system functions to exclusive systems:
```rust
// Old (0.8)
app.add_system(some_exclusive_system.exclusive_system());
// New (0.9)
app.add_system(some_exclusive_system);
```
Converting "normal" parallel systems to exclusive systems is done by calling the exclusive ordering apis:
```rust
// Old (0.8)
app.add_system(some_system.exclusive_system().at_end());
// New (0.9)
app.add_system(some_system.at_end());
```
Query state in exclusive systems can now be cached via ExclusiveSystemParams, which should be preferred for clarity and performance reasons:
```rust
// Old (0.8)
fn some_system(world: &mut World) {
let mut transforms = world.query::<&Transform>();
for transform in transforms.iter(world) {
}
}
// New (0.9)
fn some_system(world: &mut World, transforms: &mut QueryState<&Transform>) {
for transform in transforms.iter(world) {
}
}
```
# Objective
Add traits to events in `bevy_input` and `bevy_windows`: `Copy`, `Serialize`/`Deserialize`, `PartialEq`, and `Eq`, as requested in https://github.com/bevyengine/bevy/issues/6022, https://github.com/bevyengine/bevy/issues/6023, https://github.com/bevyengine/bevy/issues/6024.
## Solution
Added the traits to events in `bevy_input` and `bevy_windows`. Added dependency of `serde` in `Cargo.toml` of `bevy_input`.
## Migration Guide
If one has been `.clone()`'ing `bevy_input` events, Clippy will now complain about that. Just remove `.clone()` to solve.
## Other Notes
Some events in `bevy_input` had `f32` fields, so `Eq` trait was not derived for them.
Some events in `bevy_windows` had `String` fields, so `Copy` trait was not derived for them.
Co-authored-by: targrub <62773321+targrub@users.noreply.github.com>
# Objective
- I'm currently working on being able to call methods on reflect types (https://github.com/jakobhellermann/bevy_reflect_fns)
- for that, I'd like to add methods to the `Input<KeyCode>` resource (which I'm doing by registering type data)
- implementing `Reflect` is currently a requirement for having type data in the `TypeRegistry`
## Solution
- derive `Reflect` for `KeyCode` and `Input`
- uses `#[reflect_value]` for `Input`, since it's fields aren't supposed to be observable
- using reflect_value would need `Clone` bounds on `T`, but since all the methods (`.pressed` etc) already require `T: Copy`, I unified everything to requiring `Copy`
- add `Send + Sync + 'static` bounds, also required by reflect derive
## Unrelated improvements
I can extract into a separate PR if needed.
- the `Reflect` derive would previously ignore `#[reflect_value]` and only accept `#[reflect_value()]` which was a bit confusing
- the generated code used `val.clone()` on a reference, which is fine if `val` impls `Clone`, but otherwise also compiles with a worse error message. Change to `std::clone::Clone::clone(val)` instead which gives a neat `T does not implement Clone` error
# Objective
- The `Gamepad` type is a tiny value-containing type that implements `Copy`.
- By convention, references to `Copy` types should be avoided, as they can introduce overhead and muddle the semantics of what's going on.
- This allows us to reduce boilerplate reference manipulation and lifetimes in user facing code.
## Solution
- Make assorted methods on `Gamepads` take / return a raw `Gamepad`, rather than `&Gamepad`.
## Migration Guide
- `Gamepads::iter` now returns an iterator of `Gamepad`. rather than an iterator of `&Gamepad`.
- `Gamepads::contains` now accepts a `Gamepad`, rather than a `&Gamepad`.
# Objective
Extend the scope of Gamepad to accommodate devices that have more inputs than a typical controller.
## Solution
Add additional enum variants to both _GamepadButtonType_ and _GamepadAxisType_ that supports up to 255 more non-standard buttons/axis respectively.
## Personal motivation
I have been writing an alternative to the GILRS crate, and with this simple change to the source code, It will be a trivial thing to direct new devices through the bevy systems, even when they do not always behave exactly like your typical controller.
*This PR description is an edited copy of #5007, written by @alice-i-cecile.*
# Objective
Follow-up to https://github.com/bevyengine/bevy/pull/2254. The `Resource` trait currently has a blanket implementation for all types that meet its bounds.
While ergonomic, this results in several drawbacks:
* it is possible to make confusing, silent mistakes such as inserting a function pointer (Foo) rather than a value (Foo::Bar) as a resource
* it is challenging to discover if a type is intended to be used as a resource
* we cannot later add customization options (see the [RFC](https://github.com/bevyengine/rfcs/blob/main/rfcs/27-derive-component.md) for the equivalent choice for Component).
* dependencies can use the same Rust type as a resource in invisibly conflicting ways
* raw Rust types used as resources cannot preserve privacy appropriately, as anyone able to access that type can read and write to internal values
* we cannot capture a definitive list of possible resources to display to users in an editor
## Notes to reviewers
* Review this commit-by-commit; there's effectively no back-tracking and there's a lot of churn in some of these commits.
*ira: My commits are not as well organized :')*
* I've relaxed the bound on Local to Send + Sync + 'static: I don't think these concerns apply there, so this can keep things simple. Storing e.g. a u32 in a Local is fine, because there's a variable name attached explaining what it does.
* I think this is a bad place for the Resource trait to live, but I've left it in place to make reviewing easier. IMO that's best tackled with https://github.com/bevyengine/bevy/issues/4981.
## Changelog
`Resource` is no longer automatically implemented for all matching types. Instead, use the new `#[derive(Resource)]` macro.
## Migration Guide
Add `#[derive(Resource)]` to all types you are using as a resource.
If you are using a third party type as a resource, wrap it in a tuple struct to bypass orphan rules. Consider deriving `Deref` and `DerefMut` to improve ergonomics.
`ClearColor` no longer implements `Component`. Using `ClearColor` as a component in 0.8 did nothing.
Use the `ClearColorConfig` in the `Camera3d` and `Camera2d` components instead.
Co-authored-by: Alice <alice.i.cecile@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: devil-ira <justthecooldude@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
- I wanted to have controls independent from keyboard layout and found that bevy doesn't have a proper implementation for that
## Solution
- I created a `ScanCode` enum with two hundreds scan codes and updated `keyboard_input_system` to include and update `ResMut<Input<ScanCode>>`
- closes both https://github.com/bevyengine/bevy/issues/2052 and https://github.com/bevyengine/bevy/issues/862
Co-authored-by: Bleb1k <91003089+Bleb1k@users.noreply.github.com>
# Objective
- Fixes#5544
- Part of the splitting process of #3692.
## Solution
- Document everything in the `gamepad.rs` file.
- Add a doc example for mocking gamepad input.
---
## Changelog
- Added and updated the documentation inside of the `gamepad.rs` file.
Generally a good idea.
I ran into this because I wanted to store `Gamepads` in a wrapper struct in https://github.com/Leafwing-Studios/leafwing-input-manager/pull/168.
This PR allows the `Debug` derive used there to continue working. I could workaround this with a custom impl, but a PR upstream seemed like the right fix.
# Objective
- Enable the `axis_dpad_to_button` gilrs filter to map hats to dpad buttons on supported remotes.
- Fixes https://github.com/Leafwing-Studios/leafwing-input-manager/issues/149
- Might have fixed the confusion related to https://github.com/bevyengine/bevy/issues/3229
## Solution
- Enables the `axis_dpad_to_button` filter in `gilrs` which will use it's remote mapping information to see if there are hats mapped to dpads for that remote model. I don't really understand the logic it uses exactly, but it is usually enabled by default in gilrs and I believe it probably leads to more intuitive mapping compared to the current situation of dpad buttons being mapped to an axis.
- Removes the `GamepadAxisType::DPadX` and `GamepadAxisType::DPadY` enum variants to avoid user confusion. Those variants should never be emitted anyway, for all supported remotes.
---
## Changelog
### Changed
- Removed `GamepadAxisType::DPadX` and `GamepadAxisType::DPadY` in favor of using `GamepadButtonType::DPad[Up/Down/Left/Right]` instead.
## Migration Guide
If your game reads gamepad events or queries the axis state of `GamePadAxisType::DPadX` or `GamePadAxisType::DPadY`, then you must migrate your code to check whether or not the `GamepadButtonType::DPadUp`, `GamepadButtonType::DPadDown`, etc. buttons were pressed instead.
Removed `const_vec2`/`const_vec3`
and replaced with equivalent `.from_array`.
# Objective
Fixes#5112
## Solution
- `encase` needs to update to `glam` as well. See teoxoy/encase#4 on progress on that.
- `hexasphere` also needs to be updated, see OptimisticPeach/hexasphere#12.
# Objective
- Fixes#5083
## Solution
I looked at the implementation of those events. I noticed that they both are adaptations of `winit`'s `DeviceEvent`/`WindowEvent` enum variants. Therefore I based the description of the items on the documentation provided by the upstream crate. I also added a link to `CursorMoved`, just like `MouseMotion` already has.
## Observations
- Looking at the implementation of `MouseMotion`, I noticed the `DeviceId` field of the `winit` event is discarded by `bevy_input`. This means that in the case a machine has multiple pointing devices, it is impossible to distinguish to which one the event is referring to. **EDIT:** just tested, `MouseMotion` events are emitted for movement of both mice.
# Objective
`bevy_ui` doesn't support correctly touch inputs because of two problems in the focus system:
- It attempts to retrieve touch input with a specific `0` id
- It doesn't retrieve touch positions and bases its focus solely on mouse position, absent from mobile devices
## Solution
I added a few methods to the `Touches` resource, allowing to check if **any** touch input was pressed, released or cancelled and to retrieve the *position* of the first pressed touch input and adapted the focus system.
I added a test button to the *iOS* example and it works correclty on emulator. I did not test on a real touch device as:
- Android is not working (https://github.com/bevyengine/bevy/issues/3249)
- I don't have an iOS device
# Objective
- Part of the splitting process of #3692.
## Solution
- Document `keyboard.rs` inside of `bevy_input`.
Co-authored-by: KDecay <KDecayMusic@protonmail.com>
# Objective
Fixes#3180, builds from https://github.com/bevyengine/bevy/pull/2898
## Solution
Support requesting a window to be closed and closing a window in `bevy_window`, and handle this in `bevy_winit`.
This is a stopgap until we move to windows as entites, which I'm sure I'll get around to eventually.
## Changelog
### Added
- `Window::close` to allow closing windows.
- `WindowClosed` to allow reacting to windows being closed.
### Changed
Replaced `bevy::system::exit_on_esc_system` with `bevy:🪟:close_on_esc`.
## Fixed
The app no longer exits when any window is closed. This difference is only observable when there are multiple windows.
## Migration Guide
`bevy::input::system::exit_on_esc_system` has been removed. Use `bevy:🪟:close_on_esc` instead.
`CloseWindow` has been removed. Use `Window::close` instead.
The `Close` variant has been added to `WindowCommand`. Handle this by closing the relevant window.
# Objective
- Part of the splitting process of #3692.
## Solution
- Remove / change the tuple structs inside of `gamepad.rs` of `bevy_input` to normal structs.
## Reasons
- It made the `gamepad_connection_system` cleaner.
- It made the `gamepad_input_events.rs` example cleaner (which is probably the most notable change for the user facing API).
- Tuple structs are not descriptive (`.0`, `.1`).
- Using tuple structs for more than 1 field is a bad idea (This means that the `Gamepad` type might be fine as a tuple struct, but I still prefer normal structs over tuple structs).
Feel free to discuss this change as this is more or less just a matter of taste.
## Changelog
### Changed
- The `Gamepad`, `GamepadButton`, `GamepadAxis`, `GamepadEvent` and `GamepadEventRaw` types are now normal structs instead of tuple structs and have a `new()` function.
## Migration Guide
- The `Gamepad`, `GamepadButton`, `GamepadAxis`, `GamepadEvent` and `GamepadEventRaw` types are now normal structs instead of tuple structs and have a `new()` function. To migrate change every instantiation to use the `new()` function instead and use the appropriate field names instead of `.0` and `.1`.
# Objective
- Part of the splitting process of #3692.
## Solution
- Document `mouse.rs` inside of `bevy_input`.
Co-authored-by: KDecay <KDecayMusic@protonmail.com>
# Objective
- Part of the splitting process of #3692.
## Solution
- Add more tests to `input.rs` inside of `bevy_input`.
## Note
- The tests would now catch a change like #4410 and fail accordingly.
# Objective
- Part of the splitting process of #3692.
## Solution
- Rename `ElementState` to `ButtonState`
## Reasons
- The old name was too generic.
- If something can be pressed it is automatically button-like (thanks to @alice-i-cecile for bringing it up in #3692).
- The reason it is called `ElementState` is because that's how `winit` calls it.
- It is used to define if a keyboard or mouse **button** is pressed or not.
- Discussion in #3692.
## Changelog
### Changed
- The `ElementState` type received a rename and is now called `ButtonState`.
## Migration Guide
- The `ElementState` type received a rename and is now called `ButtonState`. To migrate you just have to change every occurrence of `ElementState` to `ButtonState`.
Co-authored-by: KDecay <KDecayMusic@protonmail.com>
# Objective
- Revert #4410
- `Input<T>.clear()` is the method call at the end of each frame for inputs. Clearing `pressed` in it mean that checking if a key is pressed will always return false
# Objective
- Part of the splitting process of #3692.
## Solution
- Change the `gamepad_connection_system` to run after the `InputSystem` label.
## Reasons
I changed the `gamepad_connection_system` to run after the `InputSystem` instead of in parallel, because this system checks the `GamepadEvent`s which get send inside of the `gamepad_event_system`. This means that the `gamepad_connection_system` could respond to the events one frame later, instead of instantly resulting in one frame lag.
Old possible case:
1. `gamepad_connection_system` (reacts to the `GamepadEvent`s too early)
2. `gamepad_event_system` (sends the `GamepadEvent`s)
New fixed ordering:
1. `gamepad_event_system` (sends the `GamepadEvent`s)
2. `gamepad_connection_system` (reacts to the `GamepadEvent`s)
# Objective
We are currently inserting an `input` into `pressed` even if it is already pressed. This also applies to releasing an input. This is not a big deal, but since we are already checking if the `input` is pressed or not we might as well remove the cost of the value update caused by the `pressed.insert` method.
Related to #4209
## Solution
Only insert or remove input if needed.
# Objective
- Fixes#4208
## Solution
- Adds a check before inserting into an `Input`'s `just_released` set, in the same way that one exists for adding into the `just_pressed` set.
For some keys, it is too expensive to hash them on every lookup. Historically in Bevy, we have regrettably done the "wrong" thing in these cases (pre-computing hashes, then re-hashing them) because Rust's built in hashed collections don't give us the tools we need to do otherwise. Doing this is "wrong" because two different values can result in the same hash. Hashed collections generally get around this by falling back to equality checks on hash collisions. You can't do that if the key _is_ the hash. Additionally, re-hashing a hash increase the odds of collision!
#3959 needs pre-hashing to be viable, so I decided to finally properly solve the problem. The solution involves two different changes:
1. A new generalized "pre-hashing" solution in bevy_utils: `Hashed<T>` types, which store a value alongside a pre-computed hash. And `PreHashMap<K, V>` (which uses `Hashed<T>` internally) . `PreHashMap` is just an alias for a normal HashMap that uses `Hashed<T>` as the key and a new `PassHash` implementation as the Hasher.
2. Replacing the `std::collections` re-exports in `bevy_utils` with equivalent `hashbrown` impls. Avoiding re-hashes requires the `raw_entry_mut` api, which isn't stabilized yet (and may never be ... `entry_ref` has favor now, but also isn't available yet). If std's HashMap ever provides the tools we need, we can move back to that. The latest version of `hashbrown` adds support for the `entity_ref` api, so we can move to that in preparation for an std migration, if thats the direction they seem to be going in. Note that adding hashbrown doesn't increase our dependency count because it was already in our tree.
In addition to providing these core tools, I also ported the "table identity hashing" in `bevy_ecs` to `raw_entry_mut`, which was a particularly egregious case.
The biggest outstanding case is `AssetPathId`, which stores a pre-hash. We need AssetPathId to be cheaply clone-able (and ideally Copy), but `Hashed<AssetPath>` requires ownership of the AssetPath, which makes cloning ids way more expensive. We could consider doing `Hashed<Arc<AssetPath>>`, but cloning an arc is still a non-trivial expensive that needs to be considered. I would like to handle this in a separate PR. And given that we will be re-evaluating the Bevy Assets implementation in the very near future, I'd prefer to hold off until after that conversation is concluded.
What is says on the tin.
This has got more to do with making `clippy` slightly more *quiet* than it does with changing anything that might greatly impact readability or performance.
that said, deriving `Default` for a couple of structs is a nice easy win
# Objective
- As part of exploring input event suppression in bevy_egui here: 53c1773583
- I found that the only way to suppress events properly, is to allow to clone the relevant Input<Whatever>, and update with events manually from within the system. This cloned Input then is discarded, the Events<*> structs are cleared, and bevy_input's normal update of Input proceeds, without the events that have been suppressed.
## Solution
- This enables Input to be cloned, allowing it to be manually updated with events.
# Objective
When using empty events, it can feel redundant to have to specify the type of the event when sending it.
## Solution
Add a new `fire()` function that sends the default value of the event. This requires that the event derives Default.
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
#3457 adds the `doc_markdown` clippy lint, which checks doc comments to make sure code identifiers are escaped with backticks. This causes a lot of lint errors, so this is one of a number of PR's that will fix those lint errors one crate at a time.
This PR fixes lints in the `bevy_input` crate.
# Objective
- There are a few warnings when building Bevy docs for dead links
- CI seems to not catch those warnings when it should
## Solution
- Enable doc CI on all Bevy workspace
- Fix warnings
- Also noticed plugin GilrsPlugin was not added anymore when feature was enabled
First commit to check that CI would actually fail with it: https://github.com/bevyengine/bevy/runs/4532652688?check_suite_focus=true
Co-authored-by: François <8672791+mockersf@users.noreply.github.com>