# Objective
Prevents duplicate implementation between IntoSystemConfigs and
IntoSystemSetConfigs using a generic, adds a NodeType trait for more
config flexibility (opening the door to implement
https://github.com/bevyengine/bevy/issues/14195?).
## Solution
Followed writeup by @ItsDoot:
https://hackmd.io/@doot/rJeefFHc1x
Removes IntoSystemConfigs and IntoSystemSetConfigs, instead using
IntoNodeConfigs with generics.
## Testing
Pending
---
## Showcase
N/A
## Migration Guide
SystemSetConfigs -> NodeConfigs<InternedSystemSet>
SystemConfigs -> NodeConfigs<ScheduleSystem>
IntoSystemSetConfigs -> IntoNodeConfigs<InternedSystemSet, M>
IntoSystemConfigs -> IntoNodeConfigs<ScheduleSystem, M>
---------
Co-authored-by: Christian Hughes <9044780+ItsDoot@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Prevent usage of `println!`, `eprintln!` and the like because they
require `std`
- Fixes#17446
## Solution
- Enable the `print_stdout` and `print_stderr` clippy lints
- Replace all `println!` and `eprintln!` occurrences with `log::*` where
applicable or alternatively ignore the warnings
## Testing
- Run `cargo clippy --workspace` to ensure that there are no warnings
relating to printing to `stdout` or `stderr`
# Objective
- Contributes to #15460
- Supersedes #8520
- Fixes#4906
## Solution
- Added a new `web` feature to `bevy`, and several of its crates.
- Enabled new `web` feature automatically within crates without `no_std`
support.
## Testing
- `cargo build --no-default-features --target wasm32v1-none`
---
## Migration Guide
When using Bevy crates which _don't_ automatically enable the `web`
feature, please enable it when building for the browser.
## Notes
- I added [`cfg_if`](https://crates.io/crates/cfg-if) to help manage
some of the feature gate gore that this extra feature introduces. It's
still pretty ugly, but I think much easier to read.
- Certain `wasm` targets (e.g.,
[wasm32-wasip1](https://doc.rust-lang.org/nightly/rustc/platform-support/wasm32-wasip1.html#wasm32-wasip1))
provide an incomplete implementation for `std`. I have not tested these
platforms, but I suspect Bevy's liberal use of usually unsupported
features (e.g., threading) will cause these targets to fail. As such,
consider `wasm32-unknown-unknown` as the only `wasm` platform with
support from Bevy for `std`. All others likely will need to be treated
as `no_std` platforms.
# Objective
- Today, enabling asset processing can generate many meta files. This
makes it a painful transition for users as they get a "mega commit"
containing tons of meta files.
## Solution
- Stop automatically generating meta files! Users can just leave the
meta files defaulted.
- Add a function `AssetServer::write_default_meta_file_for_path`
## Testing
- Tested this manually on the asset_processing example (by removing the
meta files for the assets that had default meta files).
- I did not add a unit test for the `write_default_meta_file_for_path`
since we don't have an in-memory asset writer. Writing one could be
useful in the future.
---
## Showcase
Asset processing no longer automatically generates meta files! This
makes it much easier to transition to using asset processing since you
don't suddenly get many meta files when turning it on.
You can still manually generate meta files using the new
`AssetServer::write_default_meta_file_for_path` function.
# Objective
Fixes#18022
## Solution
Canonicalize asset paths
## Testing
I ran the examples `sprite`, `desk_toy` and `game_menu` with the feature
`file_watcher` enabled. All correctly updated an asset when the source
file was altered.
Co-authored-by: Threadzless <threadzless@gmail.com>
# Objective
- Makes #18010 more easily debuggable. This doesn't solve that issue,
but protects us from it in the future.
## Solution
- Make `LoadContext::add_labeled_asset` and friends return an error if
it finds a duplicate asset.
## Testing
- Added a test - it fails before the fix.
---
## Migration Guide
- `AssetLoader`s must now handle the case of a duplicate subasset label
when using `LoadContext::add_labeled_asset` and its variants. If you
know your subasset labels are unique by construction (e.g., they include
an index number), you can simply unwrap this result.
# Objective
- Fixes#17960
## Solution
- Followed the [edition upgrade
guide](https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html)
## Testing
- CI
---
## Summary of Changes
### Documentation Indentation
When using lists in documentation, proper indentation is now linted for.
This means subsequent lines within the same list item must start at the
same indentation level as the item.
```rust
/* Valid */
/// - Item 1
/// Run-on sentence.
/// - Item 2
struct Foo;
/* Invalid */
/// - Item 1
/// Run-on sentence.
/// - Item 2
struct Foo;
```
### Implicit `!` to `()` Conversion
`!` (the never return type, returned by `panic!`, etc.) no longer
implicitly converts to `()`. This is particularly painful for systems
with `todo!` or `panic!` statements, as they will no longer be functions
returning `()` (or `Result<()>`), making them invalid systems for
functions like `add_systems`. The ideal fix would be to accept functions
returning `!` (or rather, _not_ returning), but this is blocked on the
[stabilisation of the `!` type
itself](https://doc.rust-lang.org/std/primitive.never.html), which is
not done.
The "simple" fix would be to add an explicit `-> ()` to system
signatures (e.g., `|| { todo!() }` becomes `|| -> () { todo!() }`).
However, this is _also_ banned, as there is an existing lint which (IMO,
incorrectly) marks this as an unnecessary annotation.
So, the "fix" (read: workaround) is to put these kinds of `|| -> ! { ...
}` closuers into variables and give the variable an explicit type (e.g.,
`fn()`).
```rust
// Valid
let system: fn() = || todo!("Not implemented yet!");
app.add_systems(..., system);
// Invalid
app.add_systems(..., || todo!("Not implemented yet!"));
```
### Temporary Variable Lifetimes
The order in which temporary variables are dropped has changed. The
simple fix here is _usually_ to just assign temporaries to a named
variable before use.
### `gen` is a keyword
We can no longer use the name `gen` as it is reserved for a future
generator syntax. This involved replacing uses of the name `gen` with
`r#gen` (the raw-identifier syntax).
### Formatting has changed
Use statements have had the order of imports changed, causing a
substantial +/-3,000 diff when applied. For now, I have opted-out of
this change by amending `rustfmt.toml`
```toml
style_edition = "2021"
```
This preserves the original formatting for now, reducing the size of
this PR. It would be a simple followup to update this to 2024 and run
`cargo fmt`.
### New `use<>` Opt-Out Syntax
Lifetimes are now implicitly included in RPIT types. There was a handful
of instances where it needed to be added to satisfy the borrow checker,
but there may be more cases where it _should_ be added to avoid
breakages in user code.
### `MyUnitStruct { .. }` is an invalid pattern
Previously, you could match against unit structs (and unit enum
variants) with a `{ .. }` destructuring. This is no longer valid.
### Pretty much every use of `ref` and `mut` are gone
Pattern binding has changed to the point where these terms are largely
unused now. They still serve a purpose, but it is far more niche now.
### `iter::repeat(...).take(...)` is bad
New lint recommends using the more explicit `iter::repeat_n(..., ...)`
instead.
## Migration Guide
The lifetimes of functions using return-position impl-trait (RPIT) are
likely _more_ conservative than they had been previously. If you
encounter lifetime issues with such a function, please create an issue
to investigate the addition of `+ use<...>`.
## Notes
- Check the individual commits for a clearer breakdown for what
_actually_ changed.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
Fixes#17856.
## Migration Guide
- `EventWriter::send` has been renamed to `EventWriter::write`.
- `EventWriter::send_batch` has been renamed to
`EventWriter::write_batch`.
- `EventWriter::send_default` has been renamed to
`EventWriter::write_default`.
---------
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
`bevy_assets` has long been unapproachable for contributors and users.
More and better documentation would help that.
We're gradually moving towards globally denying missing docs (#3492)!
However, writing all of the hundreds of missing doc strings in a single
go will be miserable to review.
## Solution
Remove the allow for missing docs temporarily, and then pick some easy
missing doc warnings largely at random to tackle.
Stop when the change set is starting to feel intimidating.
# Objective
While surveying the state of documentation for bevy_assets, I noticed a
few minor issues.
## Solution
Revise the docs to focus on clear explanations of core ideas and
cross-linking related objects.
# Objective
Fixes#15417.
## Solution
- Remove the `labeled_assets` fields from `LoadedAsset` and
`ErasedLoadedAsset`.
- Created new structs `CompleteLoadedAsset` and
`CompleteErasedLoadedAsset` to hold the `labeled_subassets`.
- When a subasset is `LoadContext::finish`ed, it produces a
`CompleteLoadedAsset`.
- When a `CompleteLoadedAsset` is added to a `LoadContext` (as a
subasset), their `labeled_assets` are merged, reporting any overlaps.
One important detail to note: nested subassets with overlapping names
could in theory have been used in the past for the purposes of asset
preprocessing. Even though there was no way to access these "shadowed"
nested subassets, asset preprocessing does get access to these nested
subassets. This does not seem like a case we should support though. It
is confusing at best.
## Testing
- This is just a refactor.
---
## Migration Guide
- Most uses of `LoadedAsset` and `ErasedLoadedAsset` should be replaced
with `CompleteLoadedAsset` and `CompleteErasedLoadedAsset` respectively.
This pr uses the `extern crate self as` trick to make proc macros behave
the same way inside and outside bevy.
# Objective
- Removes noise introduced by `crate as` in the whole bevy repo.
- Fixes#17004.
- Hardens proc macro path resolution.
## TODO
- [x] `BevyManifest` needs cleanup.
- [x] Cleanup remaining `crate as`.
- [x] Add proper integration tests to the ci.
## Notes
- `cargo-manifest-proc-macros` is written by me and based/inspired by
the old `BevyManifest` implementation and
[`bkchr/proc-macro-crate`](https://github.com/bkchr/proc-macro-crate).
- What do you think about the new integration test machinery I added to
the `ci`?
More and better integration tests can be added at a later stage.
The goal of these integration tests is to simulate an actual separate
crate that uses bevy. Ideally they would lightly touch all bevy crates.
## Testing
- Needs RA test
- Needs testing from other users
- Others need to run at least `cargo run -p ci integration-test` and
verify that they work.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Fix#16477.
## Solution
- Remove temporary silence introduced in #16763
- bump version of `notify-debouncer-full` to remove transitive
dependency on `instant` crate.
# Objective
- publish script copy the license files to all subcrates, meaning that
all publish are dirty. this breaks git verification of crates
- the order and list of crates to publish is manually maintained,
leading to error. cargo 1.84 is more strict and the list is currently
wrong
## Solution
- duplicate all the licenses to all crates and remove the
`--allow-dirty` flag
- instead of a manual list of crates, get it from `cargo package
--workspace`
- remove the `--no-verify` flag to... verify more things?
# Objective
- Make use of the new `weak_handle!` macro added in
https://github.com/bevyengine/bevy/pull/17384
## Solution
- Migrate bevy from `Handle::weak_from_u128` to the new `weak_handle!`
macro that takes a random UUID
- Deprecate `Handle::weak_from_u128`, since there are no remaining use
cases that can't also be addressed by constructing the type manually
## Testing
- `cargo run -p ci -- test`
---
## Migration Guide
Replace `Handle::weak_from_u128` with `weak_handle!` and a random UUID.
# Objective
- A common bevy pattern is to pre-allocate a weak `Handle` with a
static, random ID and fill it during `Plugin::build` via
`load_internal_asset!`
- This requires generating a random 128-bit number that is interpreted
as a UUID. This is much less convenient than generating a UUID directly,
and also, strictly speaking, error prone, since it often results in an
invalid UUIDv4 – they have to follow the pattern
`xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx`, where `x` is a random nibble (in
practice this doesn't matter, since the UUID is just interpreted as a
bag of bytes).
## Solution
- Add a `weak_handle!` macro that internally calls
[`uuid::uuid!`](https://docs.rs/uuid/1.12.0/uuid/macro.uuid.html) to
parse a UUID from a string literal.
- Now any random UUID generation tool can be used to generate an asset
ID, such as `uuidgen` or entering "uuid" in DuckDuckGo.
Previously:
```rust
const SHADER: Handle<Shader> = Handle::weak_from_u128(314685653797097581405914117016993910609);
```
After this PR:
```rust
const SHADER: Handle<Shader> = weak_handle!("1347c9b7-c46a-48e7-b7b8-023a354b7cac");
```
Note that I did not yet migrate any of the existing uses. I can do that
if desired, but want to have some feedback first to avoid wasted effort.
## Testing
Tested via the included doctest.
# Objective
Fixes#17662
## Solution
Moved `Item` and `fetch` from `WorldQuery` to `QueryData`, and adjusted
their implementations accordingly.
Currently, documentation related to `fetch` is written under
`WorldQuery`. It would be more appropriate to move it to the `QueryData`
documentation for clarity.
I am not very experienced with making contributions. If there are any
mistakes or areas for improvement, I would appreciate any suggestions
you may have.
## Migration Guide
The `WorldQuery::Item` type and `WorldQuery::fetch` method have been
moved to `QueryData`, as they were not useful for `QueryFilter` types.
---------
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
# Cold Specialization
## Objective
An ongoing part of our quest to retain everything in the render world,
cold-specialization aims to cache pipeline specialization so that
pipeline IDs can be recomputed only when necessary, rather than every
frame. This approach reduces redundant work in stable scenes, while
still accommodating scenarios in which materials, views, or visibility
might change, as well as unlocking future optimization work like
retaining render bins.
## Solution
Queue systems are split into a specialization system and queue system,
the former of which only runs when necessary to compute a new pipeline
id. Pipelines are invalidated using a combination of change detection
and ECS ticks.
### The difficulty with change detection
Detecting “what changed” can be tricky because pipeline specialization
depends not only on the entity’s components (e.g., mesh, material, etc.)
but also on which view (camera) it is rendering in. In other words, the
cache key for a given pipeline id is a view entity/render entity pair.
As such, it's not sufficient simply to react to change detection in
order to specialize -- an entity could currently be out of view or could
be rendered in the future in camera that is currently disabled or hasn't
spawned yet.
### Why ticks?
Ticks allow us to ensure correctness by allowing us to compare the last
time a view or entity was updated compared to the cached pipeline id.
This ensures that even if an entity was out of view or has never been
seen in a given camera before we can still correctly determine whether
it needs to be re-specialized or not.
## Testing
TODO: Tested a bunch of different examples, need to test more.
## Migration Guide
TODO
- `AssetEvents` has been moved into the `PostUpdate` schedule.
---------
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
# Objective
- Fixes CI failure due to `uuid` 1.13 using the new version of
`getrandom` which requires using a new API to work on Wasm.
## Solution
- Based on [`uuid` 1.13 release
notes](https://github.com/uuid-rs/uuid/releases/tag/1.13.0) I've enabled
the `js` feature on `wasm32`. This will need to be revisited once #17499
is up for review
- Updated minimum `uuid` version to 1.13.1, which fixes a separate issue
with `target_feature = atomics` on `wasm`.
## Testing
- `cargo check --target wasm32-unknown-unknown`
# Objective
- Contributes to #16877
## Solution
- Moved `hashbrown`, `foldhash`, and related types out of `bevy_utils`
and into `bevy_platform_support`
- Refactored the above to match the layout of these types in `std`.
- Updated crates as required.
## Testing
- CI
---
## Migration Guide
- The following items were moved out of `bevy_utils` and into
`bevy_platform_support::hash`:
- `FixedState`
- `DefaultHasher`
- `RandomState`
- `FixedHasher`
- `Hashed`
- `PassHash`
- `PassHasher`
- `NoOpHash`
- The following items were moved out of `bevy_utils` and into
`bevy_platform_support::collections`:
- `HashMap`
- `HashSet`
- `bevy_utils::hashbrown` has been removed. Instead, import from
`bevy_platform_support::collections` _or_ take a dependency on
`hashbrown` directly.
- `bevy_utils::Entry` has been removed. Instead, import from
`bevy_platform_support::collections::hash_map` or
`bevy_platform_support::collections::hash_set` as appropriate.
- All of the above equally apply to `bevy::utils` and
`bevy::platform_support`.
## Notes
- I left `PreHashMap`, `PreHashMapExt`, and `TypeIdMap` in `bevy_utils`
as they might be candidates for micro-crating. They can always be moved
into `bevy_platform_support` at a later date if desired.
# Objective
Dependabot tried up update this earlier, but it was noticed that this
broke wasm builds. A new release has happened since then which includes
a fix for that.
Here's the
[changelog](https://github.com/smol-rs/async-broadcast/blob/master/CHANGELOG.md).
Closes#11830
## Solution
Use `async-broadcast` `0.7.2`.
## Testing
I ran a few some examples involving assets on macos / wasm.
# Objective
`bevy_ecs`'s `system` module is something of a grab bag, and *very*
large. This is particularly true for the `system_param` module, which is
more than 2k lines long!
While it could be defensible to put `Res` and `ResMut` there (lol no
they're in change_detection.rs, obviously), it doesn't make any sense to
put the `Resource` trait there. This is confusing to navigate (and
painful to work on and review).
## Solution
- Create a root level `bevy_ecs/resource.rs` module to mirror
`bevy_ecs/component.rs`
- move the `Resource` trait to that module
- move the `Resource` derive macro to that module as well (Rust really
likes when you pun on the names of the derive macro and trait and put
them in the same path)
- fix all of the imports
## Notes to reviewers
- We could probably move more stuff into here, but I wanted to keep this
PR as small as possible given the absurd level of import changes.
- This PR is ground work for my upcoming attempts to store resource data
on components (resources-as-entities). Splitting this code out will make
the work and review a bit easier, and is the sort of overdue refactor
that's good to do as part of more meaningful work.
## Testing
cargo build works!
## Migration Guide
`bevy_ecs::system::Resource` has been moved to
`bevy_ecs::resource::Resource`.
Makes use of `std` explicit, simplifying a possible `no_std` port.
# Objective
- Contributes to #15460
- Simplify future `no_std` work on `bevy_asset`
## Solution
- Add `#![no_std]` to switch to `core::prelude` instead of
`std::prelude`
## Testing
- CI
---
## Notes
This is entirely a change around the names of imports and has no impact
on functionality. This just reduces the quantity of changes involved in
the (likely more controversial) `no_std`-ification of `bevy_asset`.
# Objective
Fixes https://github.com/bevyengine/bevy/issues/17111
## Solution
Move `#![warn(clippy::allow_attributes,
clippy::allow_attributes_without_reason)]` to the workspace `Cargo.toml`
## Testing
Lots of CI testing, and local testing too.
---------
Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
# Objective
I realized that setting these to `deny` may have been a little
aggressive - especially since we upgrade warnings to denies in CI.
## Solution
Downgrades these lints to `warn`, so that compiles can work locally. CI
will still treat these as denies.
# Objective
Stumbled upon a `from <-> form` transposition while reviewing a PR,
thought it was interesting, and went down a bit of a rabbit hole.
## Solution
Fix em
# Objective
Many instances of `clippy::too_many_arguments` linting happen to be on
systems - functions which we don't call manually, and thus there's not
much reason to worry about the argument count.
## Solution
Allow `clippy::too_many_arguments` globally, and remove all lint
attributes related to it.
# Objective & Solution
- Update `downcast-rs` to the latest version, 2.
- Disable (new) `sync` feature to improve compatibility with atomically
challenged platforms.
- Remove stub `downcast-rs` alternative code from `bevy_app`
## Testing
- CI
## Notes
The only change from version 1 to version 2 is the addition of a new
`sync` feature, which allows disabling the `DowncastSync` parts of
`downcast-rs`, which require access to `alloc::sync::Arc`, which is not
available on atomically challenged platforms. Since Bevy makes no use of
the functionality provided by the `sync` feature, I've disabled it in
all crates. Further details can be found
[here](https://github.com/marcianx/downcast-rs/pull/22).
# Objective
- https://github.com/bevyengine/bevy/issues/17111
## Solution
Set the `clippy::allow_attributes` and
`clippy::allow_attributes_without_reason` lints to `deny`, and bring
`bevy_asset` in line with the new restrictions.
No code changes have been made - except if a lint that was previously
`allow(...)`'d could be removed via small code changes. For example,
`unused_variables` can be handled by adding a `_` to the beginning of a
field's name.
## Testing
`cargo clippy` and `cargo test --package bevy_asset --features
multi_threaded` were run, and no errors were encountered.
Related to https://github.com/bevyengine/bevy/pull/16843
Since `WorldQuery::Fetch` is `Clone`, it can't store mutable references
to resources, so it doesn't make sense to mutably access resources. In
that sense, it is hard to find usecases of mutably accessing resources
and to clearly define, what mutably accessing resources would mean, so
it's been decided to disallow write resource access.
Also changed documentation of safety requirements of
`WorldQuery::init_fetch` and `WorldQuery::fetch` to clearly state to the
caller, what safety invariants they need to uphold.
# Objective
The original fix (bevyengine/bevy#11870) did not actually implement the
described logic. It checked if there were independently multiple loaders
for a given asset type and multiple loaders for a given extension.
However, this did not handle the case where those loaders were not the
same. For example, there could be a loader for type `Foo` and extension
`.foo`. Anther loader could exist for type `Bar` but extension `.bar`.
If a third loader was added for type `Foo` but extension `.bar`, the
warning would have been incorrectly logged.
## Solution
Instead of independently checking to see if there are preexisting
loaders for both the extension and type, look up the indices of the
loaders for the type in question. Then check to see if the loaders
registered for the extensions has any overlap. Only log if there are
loaders that fit this criteria.
## Testing
Ran CI tests. Locally tested the situation describe in the objective
section for the normal `App::init_asset_loader` flow. I think testing
could be done on the pre-registration flow for loaders still. I tested
on Windows, but the changes should not be affected by platform.
Bump version after release
This PR has been auto-generated
---------
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
- Contributes to #11478
## Solution
- Made `bevy_utils::tracing` `doc(hidden)`
- Re-exported `tracing` from `bevy_log` for end-users
- Added `tracing` directly to crates that need it.
## Testing
- CI
---
## Migration Guide
If you were importing `tracing` via `bevy::utils::tracing`, instead use
`bevy::log::tracing`. Note that many items within `tracing` are also
directly re-exported from `bevy::log` as well, so you may only need
`bevy::log` for the most common items (e.g., `warn!`, `trace!`, etc.).
This also applies to the `log_once!` family of macros.
## Notes
- While this doesn't reduce the line-count in `bevy_utils`, it further
decouples the internal crates from `bevy_utils`, making its eventual
removal more feasible in the future.
- I have just imported `tracing` as we do for all dependencies. However,
a workspace dependency may be more appropriate for version management.
# Objective
- Contributes to #11478
- Contributes to #16877
## Solution
- Removed everything except `Instant` from `bevy_utils::time`
## Testing
- CI
---
## Migration Guide
If you relied on any of the following from `bevy_utils::time`:
- `Duration`
- `TryFromFloatSecsError`
Import these directly from `core::time` regardless of platform target
(WASM, mobile, etc.)
If you relied on any of the following from `bevy_utils::time`:
- `SystemTime`
- `SystemTimeError`
Instead import these directly from either `std::time` or `web_time` as
appropriate for your target platform.
## Notes
`Duration` and `TryFromFloatSecsError` are both re-exports from
`core::time` regardless of whether they are used from `web_time` or
`std::time`, so there is no value gained from re-exporting them from
`bevy_utils::time` as well. As for `SystemTime` and `SystemTimeError`,
no Bevy internal crates or examples rely on these types. Since Bevy
doesn't have a `Time<Wall>` resource for interacting with wall-time (and
likely shouldn't need one), I think removing these from `bevy_utils`
entirely and waiting for a use-case to justify inclusion is a reasonable
path forward.
# Objective
Resolves#17064
## Solution
- Bevy no longer converts asset file extensions to lowercase before
trying to resolve an asset loader
## Testing
- I adapted the `custom_asset` example (see comment in #17064)
- The changes were tested on Linux
As far as I know, Windows has a case-insensitive file system by default,
so case-sensitive asset file extensions are probably bad practice in a
game. But we should be case-sensitive everywhere or handle asset paths
completely case-insensitive.
Before this PR:
* asset loader extensions are case-sensitive
* asset file names are case-sensitive
* asset file extensions are converted to lowercase ⚡
Now everything should be case-sensitive
# Objective
Fixes#16879
## Solution
Moved the construction of the root path of the assets folder out of
`FileWatcher::new()` and into `source.rs`, as the path is checked there
with `path.exists()` and fails in certain configurations eg., virtual
workspaces.
## Testing
Applied fix to a private fork and tested against both standard project
setups and virtual workspaces. Works without issue on both. Have tested
under macOS and Arch Linux.
---------
Co-authored-by: JP Stringham <jp@bloomdigital.to>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
- Related to https://github.com/bevyengine/bevy/issues/11478
## Solution
- Moved `futures.rs`, `ConditionalSend` `ConditionalSendFuture` and
`BoxedFuture` from `bevy_utils` to `bevy_tasks`.
## Testing
- CI checks
## Migration Guide
- Several modules were moved from `bevy_utils` into `bevy_tasks`:
- Replace `bevy_utils::futures` imports with `bevy_tasks::futures`.
- Replace `bevy_utils::ConditionalSend` with
`bevy_tasks::ConditionalSend`.
- Replace `bevy_utils::ConditionalSendFuture` with
`bevy_tasks::ConditionalSendFuture`.
- Replace `bevy_utils::BoxedFuture` with `bevy_tasks::BoxedFuture`.
# Objective
Fixes#16104
## Solution
I removed all instances of `:?` and put them back one by one where it
caused an error.
I removed some bevy_utils helper functions that were only used in 2
places and don't add value. See: #11478
## Testing
CI should catch the mistakes
## Migration Guide
`bevy::utils::{dbg,info,warn,error}` were removed. Use
`bevy::utils::tracing::{debug,info,warn,error}` instead.
---------
Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
# Objective
- Fixes#16892
## Solution
- Removed `TypeRegistryPlugin` (`Name` is now automatically registered
with a default `App`)
- Moved `TaskPoolPlugin` to `bevy_app`
- Moved `FrameCountPlugin` to `bevy_diagnostic`
- Deleted now-empty `bevy_core`
## Testing
- CI
## Migration Guide
- `TypeRegistryPlugin` no longer exists. If you can't use a default
`App` but still need `Name` registered, do so manually with
`app.register_type::<Name>()`.
- References to `TaskPoolPlugin` and associated types will need to
import it from `bevy_app` instead of `bevy_core`
- References to `FrameCountPlugin` and associated types will need to
import it from `bevy_diagnostic` instead of `bevy_core`
## Notes
This strategy was agreed upon by Cart and several other members in
[Discord](https://discord.com/channels/691052431525675048/692572690833473578/1319137218312278077).
# Objective
Implement a new `AssetChanged` query filter that allows users to query
for entities whose related assets may have changed.
- Closes https://github.com/bevyengine/bevy/issues/5069
- Unblocks #16420. Currently, `cold-specialization`, a key rendering
optimization for unlocking ancillary benefits of the retained render
world, is blocked on being unable detect all scenarios in which an
entity's mesh/material changes using events and observers. An
`AssetChanged` filter will drastically simplify our implementation and
be more robust to future changes.
Originally implemented by @nicopap in #5080.
## Solution
- Adds a new `AssetChanged` query filter that initializes a
`AssetChanges<A>` resource that tracks changed assets and ticks in
`asset_events`.
- ~Reverts #13343 and changes the api of `get_state` to accept `impl
Into<UnsafeWorldCell<'w>>` to allow accessing the `AssetChanges<A>`
resource.~
- Adds a `AsAssetId` trait used for newtype handle wrappers (e.g.
`Mesh3d`) that allows associating a component with the underlying
`Asset` it represents.
## Testing
- Tests are added for `AssetChanged`.
- TBD on performance. We are going to add this `Mesh3d` and
`MeshMaterial3d` (etc) in the renderer. Long term wins in render
performance this unblocks should swamp tracking overhead for any
realistic workload.
## Migration Guide
- The `asset_events` system is no longer public. Users should order
their systems relative to the `AssetEvents` system set.
---------
Co-authored-by: Nicola Papale <nico@nicopap.ch>
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
# Objective
We were waiting for 1.83 to address most of these, due to a bug with
`missing_docs` and `expect`. Relates to, but does not entirely complete,
#15059.
## Solution
- Upgrade to 1.83
- Switch `allow(missing_docs)` to `expect(missing_docs)`
- Remove a few now-unused `allow`s along the way, or convert to `expect`
# Objective
- Minor consistency improvement in proc macro code.
- Remove `get_path_direct` since it was only used once anyways and
doesn't add much.
## Solution
- Possibly a minor performance improvement since the `Cargo.toml` wont
be parsed as often.
## Testing
- I don't think it breaks anything.
- This is my first time working on bevy itself. Is there a script to do
a quick verify of my pr?
## Other PR
Similar to #7536 but has no extra dependencies.
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
Fixes#15485.
## Solution
Deletes the field! The `meta` field had no way to access or mutate it.
## Testing
- It builds!
---
## Migration Guide
- `ErasedAssetLoader` now takes a borrow to `AssetMetaDyn` instead of a
`Box`.
- `LoadedAsset::new_with_dependencies` no longer requires a `meta`
argument.
- `LoadContext::finish` no longer requires a `meta` argument.
Updating dependencies; adopted version of #15696. (Supercedes #15696.)
Long answer: hashbrown is no longer using ahash by default, meaning that
we can't use the default-hasher methods with ahasher. So, we have to use
the longer-winded versions instead. This takes the opportunity to also
switch our default hasher as well, but without actually enabling the
default-hasher feature for hashbrown, meaning that we'll be able to
change our hasher more easily at the cost of all of these method calls
being obnoxious forever.
One large change from 0.15 is that `insert_unique_unchecked` is now
`unsafe`, and for cases where unsafe code was denied at the crate level,
I replaced it with `insert`.
## Migration Guide
`bevy_utils` has updated its version of `hashbrown` to 0.15 and now
defaults to `foldhash` instead of `ahash`. This means that if you've
hard-coded your hasher to `bevy_utils::AHasher` or separately used the
`ahash` crate in your code, you may need to switch to `foldhash` to
ensure that everything works like it does in Bevy.
# Objective
Fixes typos in bevy project, following suggestion in
https://github.com/bevyengine/bevy-website/pull/1912#pullrequestreview-2483499337
## Solution
I used https://github.com/crate-ci/typos to find them.
I included only the ones that feel undebatable too me, but I am not in
game engine so maybe some terms are expected.
I left out the following typos:
- `reparametrize` => `reparameterize`: There are a lot of occurences, I
believe this was expected
- `semicircles` => `hemicircles`: 2 occurences, may mean something
specific in geometry
- `invertation` => `inversion`: may mean something specific
- `unparented` => `parentless`: may mean something specific
- `metalness` => `metallicity`: may mean something specific
## Testing
- Did you test these changes? If so, how? I did not test the changes,
most changes are related to raw text. I expect the others to be tested
by the CI.
- Are there any parts that need more testing? I do not think
- How can other people (reviewers) test your changes? Is there anything
specific they need to know? To me there is nothing to test
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
---
## Migration Guide
> This section is optional. If there are no breaking changes, you can
delete this section.
(kept in case I include the `reparameterize` change here)
- If this PR is a breaking change (relative to the last release of
Bevy), describe how a user might need to migrate their code to support
these changes
- Simply adding new functionality is not a breaking change.
- Fixing behavior that was definitely a bug, rather than a questionable
design choice is not a breaking change.
## Questions
- [x] Should I include the above typos? No
(https://github.com/bevyengine/bevy/pull/16702#issuecomment-2525271152)
- [ ] Should I add `typos` to the CI? (I will check how to configure it
properly)
This project looks awesome, I really enjoy reading the progress made,
thanks to everyone involved.
# Objective
- Remove `derive_more`'s error derivation and replace it with
`thiserror`
## Solution
- Added `derive_more`'s `error` feature to `deny.toml` to prevent it
sneaking back in.
- Reverted to `thiserror` error derivation
## Notes
Merge conflicts were too numerous to revert the individual changes, so
this reversion was done manually. Please scrutinise carefully during
review.
# Objective
Exposes a means to create an asset directory (and its parent
directories). Wasn't sure whether we also wanted the variant to create
directories without the parent (i.e. `mkdir` instead of `mkdir -p`)?
Fixes https://github.com/bevyengine/bevy_editor_prototypes/issues/144
# Objective
This PR introduces an `AsyncSeekForwardExt` trait, which I forgot in my
previous PR #14194.
This new trait is analogous to `AsyncSeekExt` and allows all
implementors of `AsyncSeekForward` to directly use the `seek_forward`
function in async contexts.
## Solution
- Implement a new `AsyncSeekForwardExt` trait
- Automatically implement this trait for all types that implement
`AsyncSeekForward`
## Showcase
This new trait allows a similar API to the previous Bevy version:
```rust
#[derive(Default)]
struct UniverseLoader;
#[derive(Asset, TypePath, Debug)]
struct JustALilAsteroid([u8; 128]);
impl AssetLoader for UniverseLoader {
type Asset = JustALilAsteroid;
type Settings = ();
type Error = std::io::Error;
async fn load<'a>(
&'a self,
reader: &'a mut Reader<'a>,
_settings: &'a Self::Settings,
_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
// read the asteroids entry table
let entry_offset: u64 = /* ... */;
let current_offset: u64 = reader.seek_forward(0).await?;
// jump to the entry
reader.seek_forward(entry_offset - current_offset).await?;
let mut asteroid_buf = [0; 128];
reader.read_exact(&mut asteroid_buf).await?;
Ok(JustALilAsteroid(asteroid_buf))
}
fn extensions(&self) -> &[&str] {
&["celestial"]
}
}
```
# Objective
Bevy seems to want to standardize on "American English" spellings. Not
sure if this is laid out anywhere in writing, but see also #15947.
While perusing the docs for `typos`, I noticed that it has a `locale`
config option and tried it out.
## Solution
Switch to `en-us` locale in the `typos` config and run `typos -w`
## Migration Guide
The following methods or fields have been renamed from `*dependants*` to
`*dependents*`.
- `ProcessorAssetInfo::dependants`
- `ProcessorAssetInfos::add_dependant`
- `ProcessorAssetInfos::non_existent_dependants`
- `AssetInfo::dependants_waiting_on_load`
- `AssetInfo::dependants_waiting_on_recursive_dep_load`
- `AssetInfos::loader_dependants`
- `AssetInfos::remove_dependants_and_labels`
# Objective
Built-in observers & events should be `Reflect` so that components that
interact with them can be serialized in scenes. This is a similar pr to
#14259.
# Objective
Currently, is is very painful to wait for an asset to load from the
context of an `async` task. While bevy's `AssetServer` is asynchronous
at its core, the public API is mainly focused on being used from
synchronous contexts such as bevy systems. Currently, the best way of
waiting for an asset handle to finish loading is to have a system that
runs every frame, and either listens for `AssetEvents` or manually polls
the asset server. While this is an acceptable interface for bevy
systems, it is extremely awkward to do this in a way that integrates
well with the `async` task system. At my work we had to create our own
(inefficient) abstraction that encapsulated the boilerplate of checking
an asset's load status and waking up a task when it's done.
## Solution
Add the method `AssetServer::wait_for_asset`, which returns a future
that suspends until the asset associated with a given `Handle` either
finishes loading or fails to load.
## Testing
- CI
## Notes
This is an adoption of #14431, the above description is directly from
that original PR.
---------
Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
Co-authored-by: andriyDev <andriydzikh@gmail.com>
# Objective
Another clippy-lint fix: the goal is so that `ci lints` actually
displays the problems that a contributor caused, and not a bunch of
existing stuff in the repo. (when run on nightly)
## Solution
This fixes all but the `clippy::needless_lifetimes` lint, which will
result in substantially more fixes and be in other PR(s). I also
explicitly allow `non_local_definitions` since it is [not working
correctly, but will be
fixed](https://github.com/rust-lang/rust/issues/131643).
A few things were manually fixed: for example, some places had an
explicitly defined `div_ceil` function that was used, which is no longer
needed since this function is stable on unsigned integers. Also, empty
lines in doc comments were handled individually.
## Testing
I ran `cargo clippy --workspace --all-targets --all-features --fix
--allow-staged` with the `clippy::needless_lifetimes` lint marked as
`allow` in `Cargo.toml` to avoid fixing that too. It now passes with all
but the listed lint.
# Objective
The type `AssetLoadError` has `PartialEq` and `Eq` impls, which is
problematic due to the fact that the `AssetLoaderError` and
`AddAsyncError` variants lie in their impls: they will return `true` for
any `Box<dyn Error>` with the same `TypeId`, even if the actual value is
different. This can lead to subtle bugs if a user relies on the equality
comparison to ensure that two values are equal.
The same is true for `DependencyLoadState`,
`RecursiveDependencyLoadState`.
More generally, it is an anti-pattern for large error types involving
dynamic dispatch, such as `AssetLoadError`, to have equality
comparisons. Directly comparing two errors for equality is usually not
desired -- if some logic needs to branch based on the value of an error,
it is usually more correct to check for specific variants and inspect
their fields.
As far as I can tell, the only reason these errors have equality
comparisons is because the `LoadState` enum wraps `AssetLoadError` for
its `Failed` variant. This equality comparison is only used to check for
`== LoadState::Loaded`, which we can easily replace with an `is_loaded`
method.
## Solution
Remove the `{Partial}Eq` impls from `LoadState`, which also allows us to
remove it from the error types.
## Migration Guide
The types `bevy_asset::AssetLoadError` and `bevy_asset::LoadState` no
longer support equality comparisons. If you need to check for an asset's
load state, consider checking for a specific variant using
`LoadState::is_loaded` or the `matches!` macro. Similarly, consider
using the `matches!` macro to check for specific variants of the
`AssetLoadError` type if you need to inspect the value of an asset load
error in your code.
`DependencyLoadState` and `RecursiveDependencyLoadState` are not
released yet, so no migration needed,
---------
Co-authored-by: Joseph <21144246+JoJoJet@users.noreply.github.com>
# Objective
- Closes#15716
- Closes#15718
## Solution
- Replace `Handle<MeshletMesh>` with a new `MeshletMesh3d` component
- As expected there were some random things that needed fixing:
- A couple tests were storing handles just to prevent them from being
dropped I believe, which seems to have been unnecessary in some.
- The `SpriteBundle` still had a `Handle<Image>` field. I've removed
this.
- Tests in `bevy_sprite` incorrectly added a `Handle<Image>` field
outside of the `Sprite` component.
- A few examples were still inserting `Handle`s, switched those to their
corresponding wrappers.
- 2 examples that were still querying for `Handle<Image>` were changed
to query `Sprite`
## Testing
- I've verified that the changed example work now
## Migration Guide
`Handle` can no longer be used as a `Component`. All existing Bevy types
using this pattern have been wrapped in their own semantically
meaningful type. You should do the same for any custom `Handle`
components your project needs.
The `Handle<MeshletMesh>` component is now `MeshletMesh3d`.
The `WithMeshletMesh` type alias has been removed. Use
`With<MeshletMesh3d>` instead.
# Objective
If a `Resource` implements `FromWorld` or `Default`, it's nicer to be
able to write:
```rust
let foo = world.get_resource_or_init::<Foo>();
```
Rather than:
```rust
let foo = world.get_resource_or_insert_with(Foo::default);
```
The latter is also not possible if a type implements `FromWorld` only,
and not `Default`.
## Solution
Added:
```rust
impl World {
pub fn get_resource_or_init<R: Resource + FromWorld>(&mut self) -> Mut<'_, R>;
}
```
Turns out all current in-engine uses of `get_resource_or_insert_with`
are exactly the above, so they've also been replaced.
## Testing
- Added a doc-test.
- Also added a doc-test for `World::get_resource_or_insert_with`.
# Objective
I noticed a weird break in a doc comment, I assume it must be a typo.
## Solution
Put the missing doc comment in there.
## Testing
It looks better in my IDE now
# Objective
- Remove dependency in bevy_asset to bevy_winit
- First step for #15565
## Solution
- the static `ANDROID_APP` and the `android_activity` reexport are now
in `bevy_window`
## Migration Guide
If you use the `android_activity` reexport from
`bevy::winit::android_activity`, it is now in
`bevy:🪟:android_activity`. Same for the `ANDROID_APP` static
# Objective
The `NestedLoader` API as it stands right now is somewhat lacking:
- It consists of several types `NestedLoader`, `UntypedNestedLoader`,
`DirectNestedLoader`, and `UntypedDirectNestedLoader`, where a typestate
pattern on `NestedLoader` would be make it more obvious what it does,
and allow centralising the documentation
- The term "untyped" in the asset loader code is overloaded. It can mean
either:
- we have literally no idea what the type of this asset will be when we
load it (I dub this "unknown type")
- we know what type of asset it will be, but we don't know it statically
- we only have a TypeId (I dub this "dynamic type" / "erased")
- There is no way to get an `UntypedHandle` (erased) given a `TypeId`
## Solution
Changes `NestedLoader` into a type-state pattern, adding two type
params:
- `T` determines the typing
- `StaticTyped`, the default, where you pass in `A` statically into `fn
load<A>() -> ..`
- `DynamicTyped`, where you give a `TypeId`, giving you a
`UntypedHandle`
- `UnknownTyped`, where you have literally no idea what type of asset
you're loading, giving you a `Handle<LoadedUntypedAsset>`
- `M` determines the "mode" (bikeshedding TBD, I couldn't come up with a
better name)
- `Deferred`, the default, won't load the asset when you call `load`,
but it does give you a `Handle` to it (this is nice since it can be a
sync fn)
- `Immediate` will load the asset as soon as you call it, and give you
access to it, but you must be in an async context to call it
Changes some naming of internals in `AssetServer` to fit the new
definitions of "dynamic type" and "unknown type". Note that I didn't do
a full pass over this code to keep the diff small. That can probably be
done in a new PR - I think the definiton I laid out of unknown type vs.
erased makes it pretty clear where each one applies.
<details>
<summary>Old issue</summary>
The only real problem I have with this PR is the requirement to pass in
`type_name` (from `core::any::type_name`) into Erased. Users might not
have that type name, only the ID, and it just seems sort of weird to
*have* to give an asset type name. However, the reason we need it is
because of this:
```rs
pub(crate) fn get_or_create_path_handle_erased(
&mut self,
path: AssetPath<'static>,
type_id: TypeId,
type_name: &str,
loading_mode: HandleLoadingMode,
meta_transform: Option<MetaTransform>,
) -> (UntypedHandle, bool) {
let result = self.get_or_create_path_handle_internal(
path,
Some(type_id),
loading_mode,
meta_transform,
);
// it is ok to unwrap because TypeId was specified above
unwrap_with_context(result, type_name).unwrap()
}
pub(crate) fn unwrap_with_context<T>(
result: Result<T, GetOrCreateHandleInternalError>,
type_name: &str,
) -> Option<T> {
match result {
Ok(value) => Some(value),
Err(GetOrCreateHandleInternalError::HandleMissingButTypeIdNotSpecified) => None,
Err(GetOrCreateHandleInternalError::MissingHandleProviderError(_)) => {
panic!("Cannot allocate an Asset Handle of type '{type_name}' because the asset type has not been initialized. \
Make sure you have called app.init_asset::<{type_name}>()")
}
}
}
```
This `unwrap_with_context` is literally the only reason we need the
`type_name`. Potentially, this can be turned into an `impl
Into<Option<&str>>`, and output a different error message if the type
name is missing. Since if we are loading an asset where we only know the
type ID, by definition we can't output that error message, since we
don't have the type name. I'm open to suggestions on this.
</details>
## Testing
Not sure how to test this, since I kept most of the actual NestedLoader
logic the same. The only new API is loading an `UntypedHandle` when in
the `DynamicTyped, Immediate` state.
## Migration Guide
Code which uses `bevy_asset`'s `LoadContext::loader` / `NestedLoader`
will see some naming changes:
- `untyped` is replaced by `with_unknown_type`
- `with_asset_type` is replaced by `with_static_type`
- `with_asset_type_id` is replaced by `with_dynamic_type`
- `direct` is replaced by `immediate` (the opposite of "immediate" is
"deferred")
# Objective
- Fixes#9968
## Solution
- Uses
[open_dir](https://docs.rs/ndk/latest/ndk/asset/struct.AssetManager.html#method.open_dir)
to read directories and collects child list, since it can't be shared
across threads.
- For `is_directory`, uses result of
[open](https://docs.rs/ndk/latest/ndk/asset/struct.AssetManager.html#method.open),
which will fail for directories. I tried using the result of `open_dir`
for this, but it was successful for files too, which made loading
folders return empty lists, since `open_dir` was successful and treated
all files as empty directories.
- Ignoring `meta` files was copied from filesystem implementation
---
## Changelog
- Fixed: Android's AssetReader implementation now supports
read_directory and is_directory.
## Notes
I noticed late that there was the #9968 issue (I only noticed #9591), so
I have also missed that a PR was already open (#9969). Feel free to copy
over the fixes from this one over there.
The only difference I notice between these 2, is that I have used `open`
instead of `open_dir` for `is_directory` implementation. I have tried
with `open_dir` too, but unfortunately that didn't work. I tested this
on an actual device, using the mobile example, by making some minor
changes:
```rust
#[derive(Resource)]
struct FolderAssets(Handle<LoadedFolder>);
// the `bevy_main` proc_macro generates the required boilerplate for iOS and Android
#[bevy_main]
fn main() {
// ...
.add_systems(Startup, (setup_scene, load_music_files))
.add_systems(
Update,
// Removed the handle_lifetime since AudioBundle is added later
(touch_camera, button_handler, setup_music),
);
// ...
}
fn load_music_files(asset_server: Res<AssetServer>, mut commands: Commands) {
let sounds = asset_server.load_folder("sounds");
commands.insert_resource(FolderAssets(sounds));
}
fn setup_music(
mut commands: Commands,
folders: Res<Assets<LoadedFolder>>,
mut loaded_event: EventReader<AssetEvent<LoadedFolder>>,
) {
for event in loaded_event.read() {
if let AssetEvent::LoadedWithDependencies { id } = event {
if let Some(folder) = folders.get(*id) {
warn!("Folder items: {:?}", folder.handles);
if let Some(source) = folder.handles.first() {
commands.spawn(AudioBundle {
source: source.clone().typed::<AudioSource>(),
settings: PlaybackSettings::LOOP,
});
}
}
}
}
}
```
---------
Co-authored-by: Kanabenki <lucien.menassol@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
The primary motivation behind this PR is to (partially?) address the
limitations imposed by the recently added `AsyncSeek` trait bound
discussed in issue #12880. While the `AsyncSeek` trait add some
flexibility to the reader, it inadvertently restricts the ability to
write asset readers that can truly stream bytes, particularly in
scenarios like HTTP requests where backward seeking is not supported. It
is also challenging in contexts where assets are stored in compressed
formats or require other kinds of transformations.
The logic behind this change is that currently, with `AsyncSeek`, an
asset Reader based on streamed data will either 1) fail silently, 2)
return an error, or 3) use a buffer to satisfy the trait constraint. I
believe that being able to advance in the file without having to "read"
it is a good thing. The only issue here is the ability to seek backward.
It is highly likely that in this context, we only need to seek forward
in the file because we would have already read an entry table upstream
and just want to access one or more resources further in the file. I
understand that in some cases, this may not be applicable, but I think
it is more beneficial not to constrain `Reader`s that want to stream
than to allow "Assets" to read files in a completely arbitrary order.
## Solution
Replace the current `AsyncSeek` trait with `AsyncSeekForward` on asset
`Reader`
## Changelog
- Introduced a new custom trait, `AsyncSeekForward`, for the asset
Reader.
- Replaced the current `AsyncSeek` trait with `AsyncSeekForward` for all
asset `Reader` implementations.
## Migration Guide
Replace all instances of `AsyncSeek` with `AsyncSeekForward` in your
asset reader implementations.
# Objective
Fixes#15541
A bunch of lifetimes were added during the Assets V2 rework, but after
moving to async traits in #12550 they can be elided. That PR mentions
that this might be the case, but apparently it wasn't followed up on at
the time.
~~I ended up grepping for `<'a` and finding a similar case in
`bevy_reflect` which I also fixed.~~ (edit: that one was needed
apparently)
Note that elided lifetimes are unstable in `impl Trait`. If that gets
stabilized then we can elide even more.
## Solution
Remove the extra lifetimes.
## Testing
Everything still compiles. If I have messed something up there is a
small risk that some user code stops compiling, but all the examples
still work at least.
---
## Migration Guide
The traits `AssetLoader`, `AssetSaver` and `Process` traits from
`bevy_asset` now use elided lifetimes. If you implement these then
remove the named lifetime.
# Objective
- Fixes#6370
- Closes#6581
## Solution
- Added the following lints to the workspace:
- `std_instead_of_core`
- `std_instead_of_alloc`
- `alloc_instead_of_core`
- Used `cargo +nightly fmt` with [item level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Item%5C%3A)
to split all `use` statements into single items.
- Used `cargo clippy --workspace --all-targets --all-features --fix
--allow-dirty` to _attempt_ to resolve the new linting issues, and
intervened where the lint was unable to resolve the issue automatically
(usually due to needing an `extern crate alloc;` statement in a crate
root).
- Manually removed certain uses of `std` where negative feature gating
prevented `--all-features` from finding the offending uses.
- Used `cargo +nightly fmt` with [crate level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Crate%5C%3A)
to re-merge all `use` statements matching Bevy's previous styling.
- Manually fixed cases where the `fmt` tool could not re-merge `use`
statements due to conditional compilation attributes.
## Testing
- Ran CI locally
## Migration Guide
The MSRV is now 1.81. Please update to this version or higher.
## Notes
- This is a _massive_ change to try and push through, which is why I've
outlined the semi-automatic steps I used to create this PR, in case this
fails and someone else tries again in the future.
- Making this change has no impact on user code, but does mean Bevy
contributors will be warned to use `core` and `alloc` instead of `std`
where possible.
- This lint is a critical first step towards investigating `no_std`
options for Bevy.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
The logic in PR #14808 broke `bevy_asset_loader`, because calling
`AssetServer::load_untyped()` initiates a load of an asset of type
`LoadedUntypedAsset`, which doesn't match any asset loaders and
therefore fails. I reverted the lines that were causing the problem. The
resulting code seems to work, but I'm not sure if this was the correct
fix.
# Objective
Currently, the term "value" in the context of reflection is a bit
overloaded.
For one, it can be used synonymously with "data" or "variable". An
example sentence would be "this function takes a reflected value".
However, it is also used to refer to reflected types which are
`ReflectKind::Value`. These types are usually either primitives, opaque
types, or types that don't fall into any other `ReflectKind` (or perhaps
could, but don't due to some limitation/difficulty). An example sentence
would be "this function takes a reflected value type".
This makes it difficult to write good documentation or other learning
material without causing some amount of confusion to readers. Ideally,
we'd be able to move away from the `ReflectKind::Value` usage and come
up with a better term.
## Solution
This PR replaces the terminology of "value" with "opaque" across
`bevy_reflect`. This includes in documentation, type names, variant
names, and macros.
The term "opaque" was chosen because that's essentially how the type is
treated within the reflection API. In other words, its internal
structure is hidden. All we can do is work with the type itself.
### Primitives
While primitives are not technically opaque types, I think it's still
clearer to refer to them as "opaque" rather than keep the confusing
"value" terminology.
We could consider adding another concept for primitives (e.g.
`ReflectKind::Primitive`), but I'm not sure that provides a lot of
benefit right now. In most circumstances, they'll be treated just like
an opaque type. They would also likely use the same macro (or two copies
of the same macro but with different names).
## Testing
You can test locally by running:
```
cargo test --package bevy_reflect --all-features
```
---
## Migration Guide
The reflection concept of "value type" has been replaced with a clearer
"opaque type". The following renames have been made to account for this:
- `ReflectKind::Value` → `ReflectKind::Opaque`
- `ReflectRef::Value` → `ReflectRef::Opaque`
- `ReflectMut::Value` → `ReflectMut::Opaque`
- `ReflectOwned::Value` → `ReflectOwned::Opaque`
- `TypeInfo::Value` → `TypeInfo::Opaque`
- `ValueInfo` → `OpaqueInfo`
- `impl_reflect_value!` → `impl_reflect_opaque!`
- `impl_from_reflect_value!` → `impl_from_reflect_opaque!`
Additionally, declaring your own opaque types no longer uses
`#[reflect_value]`. This attribute has been replaced by
`#[reflect(opaque)]`:
```rust
// BEFORE
#[derive(Reflect)]
#[reflect_value(Default)]
struct MyOpaqueType(u32);
// AFTER
#[derive(Reflect)]
#[reflect(opaque)]
#[reflect(Default)]
struct MyOpaqueType(u32);
```
Note that the order in which `#[reflect(opaque)]` appears does not
matter.
# Objective
Fixes#15351
## Solution
- Created new external crate and ported over the code
## Testing
- CI
## Migration guide
Replace references to `bevy_utils::ShortName` with
`disqualified::ShortName`.
# Objective
#13320 added convenience methods for casting a `TypeInfo` into its
respective variant:
```rust
let info: &TypeInfo = <Vec<i32> as Typed>::type_info();
// We know `info` contains a `ListInfo`, so we can simply cast it:
let list_info: &ListInfo = info.as_list().unwrap();
```
This is especially helpful when you have already verified a type is a
certain kind via `ReflectRef`, `ReflectMut`, `ReflectOwned`, or
`ReflectKind`.
As mentioned in that PR, though, it would be useful to add similar
convenience methods to those types as well.
## Solution
Added convenience casting methods to `ReflectRef`, `ReflectMut`, and
`ReflectOwned`.
With these methods, I was able to reduce our nesting in certain places
throughout the crate.
Additionally, I took this opportunity to move these types (and
`ReflectKind`) to their own module to help clean up the `reflect`
module.
## Testing
You can test locally by running:
```
cargo test --package bevy_reflect --all-features
```
---
## Showcase
Convenience methods for casting `ReflectRef`, `ReflectMut`, and
`ReflectOwned` into their respective variants has been added! This
allows you to write cleaner code if you already know the kind of your
reflected data:
```rust
// BEFORE
let ReflectRef::List(list) = list.reflect_ref() else {
panic!("expected list");
};
// AFTER
let list = list.reflect_ref().as_list().unwrap();
```
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Pablo Reinhardt <126117294+pablo-lua@users.noreply.github.com>
# Objective
- Goal is to minimize bevy_utils #11478
## Solution
- Move the file short_name wholesale into bevy_reflect
## Testing
- Unit tests
- CI
## Migration Guide
- References to `bevy_utils::ShortName` should instead now be
`bevy_reflect::ShortName`.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
> Rust 1.81 released the #[expect(...)] attribute, which works like
#[allow(...)] but throws a warning if the lint isn't raised. This is
preferred to #[allow(...)] because it tells us when it can be removed.
- Adopts the parts of #15118 that are complete, and updates the branch
so it can be merged.
- There were a few conflicts, let me know if I misjudged any of 'em.
Alice's
[recommendation](https://github.com/bevyengine/bevy/issues/15059#issuecomment-2349263900)
seems well-taken, let's do this crate by crate now that @BD103 has done
the lion's share of this!
(Relates to, but doesn't yet completely finish #15059.)
Crates this _doesn't_ cover:
- bevy_input
- bevy_gilrs
- bevy_window
- bevy_winit
- bevy_state
- bevy_render
- bevy_picking
- bevy_core_pipeline
- bevy_sprite
- bevy_text
- bevy_pbr
- bevy_ui
- bevy_gltf
- bevy_gizmos
- bevy_dev_tools
- bevy_internal
- bevy_dylib
---------
Co-authored-by: BD103 <59022059+BD103@users.noreply.github.com>
Co-authored-by: Ben Frankel <ben.frankel7@gmail.com>
Co-authored-by: Antony <antony.m.3012@gmail.com>
`ShortName` is lazily evaluated and does not allocate, instead providing
`Display` and `Debug` implementations which write directly to a
formatter using the original algorithm. When using `ShortName` in format
strings (`panic`, `dbg`, `format`, etc.) you can directly use the
`ShortName` type. If you require a `String`, simply call
`ShortName(...).to_string()`.
# Objective
- Remove the requirement for allocation when using `get_short_name`
## Solution
- Added new type `ShortName` which wraps a name and provides its own
`Debug` and `Display` implementations, using the original
`get_short_name` algorithm without the need for allocating.
- Removed `get_short_name`, as `ShortName(...)` is more performant and
ergonomic.
- Added `ShortName::of::<T>` method to streamline the common use-case
for name shortening.
## Testing
- CI
## Migration Guide
### For `format!`, `dbg!`, `panic!`, etc.
```rust
// Before
panic!("{} is too short!", get_short_name(name));
// After
panic!("{} is too short!", ShortName(name));
```
### Need a `String` Value
```rust
// Before
let short: String = get_short_name(name);
// After
let short: String = ShortName(name).to_string();
```
## Notes
`ShortName` lazily evaluates, and directly writes to a formatter via
`Debug` and `Display`, which removes the need to allocate a `String`
when printing a shortened type name. Because the implementation has been
moved into the `fmt` method, repeated printing of the `ShortName` type
may be less performant than converting it into a `String`. However, no
instances of this are present in Bevy, and the user can get the original
behaviour by calling `.to_string()` at no extra cost.
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
Asset processing (added as part of #8624) is a powerful, high-impact
feature, but has been widely underused (and underdeveloped) due to poor
developer understanding.
## Solution
In this PR, I've documented what asset processing is, why it's useful,
and pointed users to the two primary entry points.
While I would like substantially more involved practical examples for
how to perform common asset-processing tasks, I've split them out from
this PR for ease of review (and actually submitting this for review
before the weekend).
We should add bread crumbs from the module docs to these docs, but
whether we add that here or in #15056 depends on which gets merged
first.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
# Objective
Bevy's asset system is powerful and generally well-designed but very
opaque.
Beginners struggle to discover how to do simple tasks and grok the
fundamental data models, while more advanced users trip over the
assorted traits and their relation to each other.
Reverts #15054 ;)
## Solution
This PR adds module documentation to `bevy_assets`, tweaking the
associated documentation on the items as needed to provide further
details and bread crumbs.
If you have ideas for other important, hard-to-discover patterns or
functionality in this crate, please let me know.
That said, I've left out a section on asset preprocessing which *should*
eventually go here. That is substantially more uncertain, and requires
both more time to investigate and more expertise to review.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: TrialDragon <31419708+TrialDragon@users.noreply.github.com>
Co-authored-by: NotAFile <notafile@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
Co-authored-by: JMS55 <47158642+JMS55@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
# Objective
- Fixes#15060
## Solution
- Added `IdentityAssetTransformer<A>` which is an `AssetTransformer`
which infallibly returns the input `Asset` unmodified.
- Replaced `LoadAndSave` and `LoadAndSaveSettings` with type definitions
linking back to `LoadTransformAndSave` and
`LoadTransformAndSaveSettings` respectively.
- Marked `LoadAndSave` and `LoadAndSaveSettings` as depreciated with a
migration guide included, hinting to the user to use the underlying type
instead.
## Testing
- Ran CI locally
---
## Migration Guide
- Replace `LoadAndSave<L, S>` with `LoadTransformAndSave<L,
IdentityAssetTransformer<<L as AssetLoader>::Asset>, S>`
- Replace `LoadAndSaveSettings<L, S>` with
`LoadTransformAndSaveSettings<L, (), S>`
# Objective
We should attempt to document the entirety of bevy_assets. `AssetMode`
is missing docs explaining what it is, how it's used and why it exists.
## Solution
Add docs, focusing on the context in
https://github.com/bevyengine/bevy/issues/10157.
# Objective
- Crate-level prelude modules, such as `bevy_ecs::prelude`, are plagued
with inconsistency! Let's fix it!
## Solution
Format all preludes based on the following rules:
1. All preludes should have brief documentation in the format of:
> The _name_ prelude.
>
> This includes the most common types in this crate, re-exported for
your convenience.
2. All documentation should be outer, not inner. (`///` instead of
`//!`.)
3. No prelude modules should be annotated with `#[doc(hidden)]`. (Items
within them may, though I'm not sure why this was done.)
## Testing
- I manually searched for the term `mod prelude` and updated all
occurrences by hand. 🫠
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>