Commit graph

410 commits

Author SHA1 Message Date
Vitaliy Sapronenko
4da4493449
Error info has been added to LoadState::Failed (#12709)
# Objective

Fixes #12667.

## Solution

- Stored
[AssetLoadError](https://docs.rs/bevy/latest/bevy/asset/enum.AssetLoadError.html)
inside of
[LoadState::Failed](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html)
as a Box<AssetLoadError> to avoid bloating the size of all variants of
LoadState.
- Fixed dependent code

## Migration guide

Added
[AssetLoadError](https://docs.rs/bevy/latest/bevy/asset/enum.AssetLoadError.html)
to
[LoadState::Failed](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html)
option
Removed `Copy`, `Ord` and `PartialOrd` implementations for
[LoadState](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html)
enum
Added `Eq` and `PartialEq` implementations for
[MissingAssetSourceError](https://docs.rs/bevy/latest/bevy/asset/io/struct.MissingAssetSourceError.html),
[MissingProcessedAssetReaderError](https://docs.rs/bevy/latest/bevy/asset/io/struct.MissingProcessedAssetReaderError.html),
[DeserializeMetaError](https://docs.rs/bevy/latest/bevy/asset/enum.DeserializeMetaError.html),
[LoadState](https://docs.rs/bevy/latest/bevy/asset/enum.LoadState.html),
[AssetLoadError](https://docs.rs/bevy/latest/bevy/asset/enum.AssetLoadError.html),
[MissingAssetLoaderForTypeNameError](https://docs.rs/bevy/latest/bevy/asset/struct.MissingAssetLoaderForTypeNameError.html)
and
[MissingAssetLoaderForTypeIdError](https://docs.rs/bevy/latest/bevy/asset/struct.MissingAssetLoaderForTypeIdError.html)
2024-04-04 14:04:27 +00:00
Kristoffer Søholm
3928d01841
Ignore query parameters in AssetPaths when determining the extension (#12828)
# Objective

A help thread on discord asked how to use signed URLs for assets. This
currently fails because the query parameters are included in the
extension, which causes no suitable loader to be found:

```
Failed to load asset 'http://localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject' with asset loader 'bevy_render::texture::image_loader::ImageLoader': 
Could not load texture file: Error reading image file localhost:4566/dev/1711921849174.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject: invalid image extension: jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=%2F20240331%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240331T230145Z&X-Amz-Expires=900&X-Amz-Signature=64855e731c279fa01063568e37095562ef74e09387c881bd3e3604181d0cc108&X-Amz-SignedHeaders=host&x-id=GetObject, this is an error in `bevy_render`.
```

## Solution

Make `get_full_extension` remove everything after the first `?`
character.

If this is accepted then it should also be documented in `AssetPath`
that extensions cannot include question marks.

An alternative is to special case this handling only for wasm, but that
would be annoying for the
[bevy_web_asset](https://github.com/johanhelsing/bevy_web_asset) plugin,
and in my opinion also just more confusing overall.
2024-04-03 18:57:03 +00:00
Cameron
01649f13e2
Refactor App and SubApp internals for better separation (#9202)
# Objective

This is a necessary precursor to #9122 (this was split from that PR to
reduce the amount of code to review all at once).

Moving `!Send` resource ownership to `App` will make it unambiguously
`!Send`. `SubApp` must be `Send`, so it can't wrap `App`.

## Solution

Refactor `App` and `SubApp` to not have a recursive relationship. Since
`SubApp` no longer wraps `App`, once `!Send` resources are moved out of
`World` and into `App`, `SubApp` will become unambiguously `Send`.

There could be less code duplication between `App` and `SubApp`, but
that would break `App` method chaining.

## Changelog

- `SubApp` no longer wraps `App`.
- `App` fields are no longer publicly accessible.
- `App` can no longer be converted into a `SubApp`.
- Various methods now return references to a `SubApp` instead of an
`App`.
## Migration Guide

- To construct a sub-app, use `SubApp::new()`. `App` can no longer
convert into `SubApp`.
- If you implemented a trait for `App`, you may want to implement it for
`SubApp` as well.
- If you're accessing `app.world` directly, you now have to use
`app.world()` and `app.world_mut()`.
- `App::sub_app` now returns `&SubApp`.
- `App::sub_app_mut`  now returns `&mut SubApp`.
- `App::get_sub_app` now returns `Option<&SubApp>.`
- `App::get_sub_app_mut` now returns `Option<&mut SubApp>.`
2024-03-31 03:16:10 +00:00
BeastLe9enD
eb44db4437
Add AsyncSeek trait to Reader to be able to seek inside asset loaders (#12547)
# Objective

For some asset loaders, it can be useful not to read the entire asset
file and just read a specific region of a file. For this, we need a way
to seek at a specific position inside the file

## Solution

I added support for `AsyncSeek` to `Reader`. In my case, I want to only
read a part of a file, and for that I need to seek to a specific point.

## Migration Guide

Every custom reader (which previously only needed the `AsyncRead` trait
implemented) now also needs to implement the `AsyncSeek` trait to add
the seek capability.
2024-03-30 22:26:30 +00:00
andriyDev
77de9a5beb
Allow converting mutable handle borrows to AssetId. (#12759)
## Problem

- A mutable borrow of a handle cannot be directly turned into an AssetId
with `.into()`. You must do a reborrow `&*my_handle`.

## Solution

- Add an impl for From<&mut Handle> to AssetId and UntypedAssetId.
2024-03-28 15:53:26 +00:00
James Liu
56bcbb0975
Forbid unsafe in most crates in the engine (#12684)
# Objective
Resolves #3824. `unsafe` code should be the exception, not the norm in
Rust. It's obviously needed for various use cases as it's interfacing
with platforms and essentially running the borrow checker at runtime in
the ECS, but the touted benefits of Bevy is that we are able to heavily
leverage Rust's safety, and we should be holding ourselves accountable
to that by minimizing our unsafe footprint.

## Solution
Deny `unsafe_code` workspace wide. Add explicit exceptions for the
following crates, and forbid it in almost all of the others.

* bevy_ecs - Obvious given how much unsafe is needed to achieve
performant results
* bevy_ptr - Works with raw pointers, even more low level than bevy_ecs.
 * bevy_render - due to needing to integrate with wgpu
 * bevy_window - due to needing to integrate with raw_window_handle
* bevy_utils - Several unsafe utilities used by bevy_ecs. Ideally moved
into bevy_ecs instead of made publicly usable.
 * bevy_reflect - Required for the unsafe type casting it's doing.
 * bevy_transform - for the parallel transform propagation
 * bevy_gizmos  - For the SystemParam impls it has.
* bevy_assets - To support reflection. Might not be required, not 100%
sure yet.
* bevy_mikktspace - due to being a conversion from a C library. Pending
safe rewrite.
* bevy_dynamic_plugin - Inherently unsafe due to the dynamic loading
nature.

Several uses of unsafe were rewritten, as they did not need to be using
them:

* bevy_text - a case of `Option::unchecked` could be rewritten as a
normal for loop and match instead of an iterator.
* bevy_color - the Pod/Zeroable implementations were replaceable with
bytemuck's derive macros.
2024-03-27 03:30:08 +00:00
Michael Allwright
320033150e
Fix fetching assets in Web Workers (#12134)
# Objective

This PR fixes #12125

## Solution

The logic in this PR was borrowed from gloo-net and essentially probes
the global Javascript context to see if we are in a window or a worker
before calling `fetch_with_str`.

---------

Co-authored-by: Zachary Harrold <zac@harrold.com.au>
2024-03-25 19:09:30 +00:00
James Liu
f096ad4155
Set the logo and favicon for all of Bevy's published crates (#12696)
# Objective
Currently the built docs only shows the logo and favicon for the top
level `bevy` crate. This makes views like
https://docs.rs/bevy_ecs/latest/bevy_ecs/ look potentially unrelated to
the project at first glance.

## Solution
Reproduce the docs attributes for every crate that Bevy publishes.

Ideally this would be done with some workspace level Cargo.toml control,
but AFAICT, such support does not exist.
2024-03-25 18:52:50 +00:00
Arthur Brussee
34c8778bf0
Fix get_asset_paths not properly deleting empty folders (& recursive async functions) (#12638)
# Objective

get_asset_paths tries to check whether a folder is empty, and if so
delete it. However rather than checking whether any subfolder contains
files it checks whether _all_ subfolders have files.

Also cleanup various BoxedFutures in async recursive functions like
these, rust 1.77 now allows recursive async functions (albeit still by
boxing), hurray! This is a followup to #12550 (sorta). More BoxedFuture
stuff can be removed now that rust 1.77 is out, which can use async
recursive functions! This is mainly just cleaner code wise - the
recursion still boxes the future so not much to win there.

PR is mainly whitespace changes so do disable whitespace diffs for
easier review.
2024-03-23 03:35:51 +00:00
Ame
72c51cdab9
Make feature(doc_auto_cfg) work (#12642)
# Objective

- In #12366 `![cfg_attr(docsrs, feature(doc_auto_cfg))] `was added. But
to apply it it needs `--cfg=docsrs` in rustdoc-args.


## Solution

- Apply `--cfg=docsrs` to all crates and CI.

I also added `[package.metadata.docs.rs]` to all crates to avoid adding
code behind a feature and forget adding the metadata.

Before:

![Screenshot 2024-03-22 at 00 51
57](https://github.com/bevyengine/bevy/assets/104745335/6a9dfdaa-8710-4784-852b-5f9b74e3522c)

After:
![Screenshot 2024-03-22 at 00 51
32](https://github.com/bevyengine/bevy/assets/104745335/c5bd6d8e-8ddb-45b3-b844-5ecf9f88961c)
2024-03-23 02:22:52 +00:00
Jacques Schutte
fdf2ea7cc5
reflect: remove manual Reflect impls which could be handled by macros (#12596)
# Objective

* Adopted #12025 to fix merge conflicts
* In some cases we used manual impls for certain types, though they are
(at least, now) unnecessary.

## Solution

* Use macros and reflecting-by-value to avoid this clutter.
* Though there were linker issues with Reflect and the CowArc in
AssetPath (see https://github.com/bevyengine/bevy/issues/9747), I
checked these are resolved by using #[reflect_value].

---------

Co-authored-by: soqb <cb.setho@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
2024-03-23 01:45:00 +00:00
Vitaliy Sapronenko
67cc605e9f
Removed Into<AssedId<T>> for Handle<T> as mentioned in #12600 (#12655)
Fixes #12600 

## Solution

Removed Into<AssetId<T>> for Handle<T> as proposed in Issue
conversation, fixed dependent code

## Migration guide

If you use passing Handle by value as AssetId, you should pass reference
or call .id() method on it
Before (0.13):
`assets.insert(handle, value);`
After (0.14):
`assets.insert(&handle, value);`
or
`assets.insert(handle.id(), value);`
2024-03-22 20:26:12 +00:00
BeastLe9enD
fcf01a7925
Add path function to ProcessContext (#12636)
# Objective

- It can be useful to have access to the path of the current asset being
processed, for example if you want to need a second file that is
relative to the current file being processed.

## Solution

- I added a `path()` function to the `ProcessContext`
2024-03-21 23:58:54 +00:00
BeastLe9enD
cc3144926b
Make AssetAction::Ignore not copy assets to imported_assets (#12605)
# Objective

Lets say I have the following `.meta` file:
```RON
(
    meta_format_version: "1.0",
    asset: Ignore,
)
```
When a file is inside the `assets` directory and processing is enabled,
the processor will copy the file into `imported_assets` although it
should be ignored and therefore not copied.

## Solution

- I added a simple check that does not copy the assets if the
AssetAction is `Ignore`.


## Migration Guide

- The public `ProcessResult` enum now has a `ProcessResult::Ignore`
variant that must be handled.
2024-03-21 18:13:18 +00:00
Brezak
69e78bd03e
Fix Ci failing over dead code in tests (#12623)
# Objective

Fix Pr CI failing over dead code in tests and main branch CI failing
over a missing semicolon. Fixes #12620.

## Solution

Add dead_code annotations and a semicolon.
2024-03-21 18:08:47 +00:00
Arthur Brussee
ac49dce4ca
Use async-fn in traits rather than BoxedFuture (#12550)
# Objective

Simplify implementing some asset traits without Box::pin(async move{})
shenanigans.
Fixes (in part) https://github.com/bevyengine/bevy/issues/11308

## Solution
Use async-fn in traits when possible in all traits. Traits with return
position impl trait are not object safe however, and as AssetReader and
AssetWriter are both used with dynamic dispatch, you need a Boxed
version of these futures anyway.

In the future, Rust is [adding
](https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html)proc
macros to generate these traits automatically, and at some point in the
future dyn traits should 'just work'. Until then.... this seemed liked
the right approach given more ErasedXXX already exist, but, no clue if
there's plans here! Especially since these are public now, it's a bit of
an unfortunate API, and means this is a breaking change.

In theory this saves some performance when these traits are used with
static dispatch, but, seems like most code paths go through dynamic
dispatch, which boxes anyway.

I also suspect a bunch of the lifetime annotations on these function
could be simplified now as the BoxedFuture was often the only thing
returned which needed a lifetime annotation, but I'm not touching that
for now as traits + lifetimes can be so tricky.

This is a revival of
[pull/11362](https://github.com/bevyengine/bevy/pull/11362) after a
spectacular merge f*ckup, with updates to the latest Bevy. Just to recap
some discussion:
- Overall this seems like a win for code quality, especially when
implementing these traits, but a loss for having to deal with ErasedXXX
variants.
- `ConditionalSend` was the preferred name for the trait that might be
Send, to deal with wasm platforms.
- When reviewing be sure to disable whitespace difference, as that's 95%
of the PR.


## Changelog
- AssetReader, AssetWriter, AssetLoader, AssetSaver and Process now use
async-fn in traits rather than boxed futures.

## Migration Guide
- Custom implementations of AssetReader, AssetWriter, AssetLoader,
AssetSaver and Process should switch to async fn rather than returning a
bevy_utils::BoxedFuture.
- Simultaniously, to use dynamic dispatch on these traits you should
instead use dyn ErasedXXX.
2024-03-18 17:56:57 +00:00
robtfm
36cfb2170f
send Unused event when asset is actually unused (#12459)
# Objective

fix #12344

## Solution

use existing machinery in track_assets to determine if the asset is
unused before firing Asset::Unused event

~~most extract functions use `AssetEvent::Removed` to schedule deletion
of render world resources. `RenderAssetPlugin` was using
`AssetEvent::Unused` instead.
`Unused` fires when the last strong handle is dropped, even if a new one
is created. `Removed` only fires when a new one is not created.
as far as i can see, `Unused` is the same as `Removed` except for this
"feature", and that it also fires early if all handles for a loading
asset are dropped (`Removed` fires after the loading completes). note
that in that case, processing based on `Loaded` won't have been done
anyway.
i think we should get rid of `Unused` completely, it is not currently
used anywhere (except here, previously) and i think using it is probably
always a mistake.
i also am not sure why we keep loading assets that have been dropped
while loading, we should probably drop the loader task as well and
remove immediately.~~
2024-03-17 21:37:34 +00:00
davier
bc1073ee48
Fix doc comment on AssetActionMinimal (#11105)
# Objective

The doc comment on `AssetActionMinimal` links to itself instead of
`AssetAction`

Co-authored-by: François Mockers <mockersf@gmail.com>
2024-03-11 18:59:27 +00:00
Mike
8a08825348
Move AssetEvents to Last (#12389)
# Objective

- Fixes https://github.com/bevyengine/bevy/issues/12380

## Solution

- Before #11986 AssetEvents were scheduled after PostUpdate. That pr
moved these into First. This PR moves them into Last which is closer to
how they were scheduled before.
2024-03-09 21:15:02 +00:00
Al M
52e3f2007b
Add "all-features = true" to docs.rs metadata for most crates (#12366)
# Objective

Fix missing `TextBundle` (and many others) which are present in the main
crate as default features but optional in the sub-crate. See:

- https://docs.rs/bevy/0.13.0/bevy/ui/node_bundles/index.html
- https://docs.rs/bevy_ui/0.13.0/bevy_ui/node_bundles/index.html

~~There are probably other instances in other crates that I could track
down, but maybe "all-features = true" should be used by default in all
sub-crates? Not sure.~~ (There were many.) I only noticed this because
rust-analyzer's "open docs" features takes me to the sub-crate, not the
main one.

## Solution

Add "all-features = true" to docs.rs metadata for crates that use
features.

## Changelog

### Changed

- Unified features documented on docs.rs between main crate and
sub-crates
2024-03-08 20:03:09 +00:00
Patrick Walton
dfdf2b9ea4
Implement the AnimationGraph, allowing for multiple animations to be blended together. (#11989)
This is an implementation of RFC #51:
https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md

Note that the implementation strategy is different from the one outlined
in that RFC, because two-phase animation has now landed.

# Objective

Bevy needs animation blending. The RFC for this is [RFC 51].

## Solution

This is an implementation of the RFC. Note that the implementation
strategy is different from the one outlined there, because two-phase
animation has now landed.

This is just a draft to get the conversation started. Currently we're
missing a few things:

- [x] A fully-fleshed-out mechanism for transitions
- [x] A serialization format for `AnimationGraph`s
- [x] Examples are broken, other than `animated_fox`
- [x] Documentation

---

## Changelog

### Added

* The `AnimationPlayer` has been reworked to support blending multiple
animations together through an `AnimationGraph`, and as such will no
longer function unless a `Handle<AnimationGraph>` has been added to the
entity containing the player. See [RFC 51] for more details.

* Transition functionality has moved from the `AnimationPlayer` to a new
component, `AnimationTransitions`, which works in tandem with the
`AnimationGraph`.

## Migration Guide

* `AnimationPlayer`s can no longer play animations by themselves and
need to be paired with a `Handle<AnimationGraph>`. Code that was using
`AnimationPlayer` to play animations will need to create an
`AnimationGraph` asset first, add a node for the clip (or clips) you
want to play, and then supply the index of that node to the
`AnimationPlayer`'s `play` method.

* The `AnimationPlayer::play_with_transition()` method has been removed
and replaced with the `AnimationTransitions` component. If you were
previously using `AnimationPlayer::play_with_transition()`, add all
animations that you were playing to the `AnimationGraph`, and create an
`AnimationTransitions` component to manage the blending between them.

[RFC 51]:
https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-03-07 20:22:42 +00:00
James Liu
512b7463a3
Disentangle bevy_utils/bevy_core's reexported dependencies (#12313)
# Objective
Make bevy_utils less of a compilation bottleneck. Tackle #11478.

## Solution
* Move all of the directly reexported dependencies and move them to
where they're actually used.
* Remove the UUID utilities that have gone unused since `TypePath` took
over for `TypeUuid`.
* There was also a extraneous bytemuck dependency on `bevy_core` that
has not been used for a long time (since `encase` became the primary way
to prepare GPU buffers).
* Remove the `all_tuples` macro reexport from bevy_ecs since it's
accessible from `bevy_utils`.

---

## Changelog
Removed: Many of the reexports from bevy_utils (petgraph, uuid, nonmax,
smallvec, and thiserror).
Removed: bevy_core's reexports of bytemuck.

## Migration Guide
bevy_utils' reexports of petgraph, uuid, nonmax, smallvec, and thiserror
have been removed.

bevy_core' reexports of bytemuck's types has been removed. 

Add them as dependencies in your own crate instead.
2024-03-07 02:30:15 +00:00
James Liu
9e5db9abc7
Clean up type registrations (#12314)
# Objective
Fix #12304. Remove unnecessary type registrations thanks to #4154.

## Solution
Conservatively remove type registrations. Keeping the top level
components, resources, and events, but dropping everything else that is
a type of a member of those types.
2024-03-06 16:05:53 +00:00
Gino Valente
5b69613e42
bevy_utils: Add BuildHasher parameter to bevy_utils::Entry type alias (#12308)
# Objective

`bevy_utils::Entry` is only useful when using
`BuildHasherDefault<AHasher>`. It would be great if we didn't have to
write out `bevy_utils::hashbrown::hash_map::Entry` whenever we want to
use a different `BuildHasher`, such as when working with
`bevy_utils::TypeIdMap`.

## Solution

Give `bevy_utils::Entry` a new optional type parameter for defining a
custom `BuildHasher`, such as `NoOpHash`. This parameter defaults to
`BuildHasherDefault<AHasher>`— the `BuildHasher` used by
`bevy_utils::HashMap`.

---

## Changelog

- Added an optional third type parameter to `bevy_utils::Entry` to
specify a custom `BuildHasher`
2024-03-05 02:45:05 +00:00
Sludge
fadc6d08c1
#[reflect(Default)] for Handle/Mesh2dHandle (#12264)
# Objective

- Make default handles constructible via reflection

## Solution

- Add missing `#[reflect(Default)]` to them

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2024-03-04 04:18:02 +00:00
geekvest
d5c32bdc23
remove repetitive code (#12270)
Signed-off-by: geekvest <cuimoman@sohu.com>
2024-03-03 07:58:22 +00:00
James Liu
5619bd09d1
Replace bevy_log's tracing reexport with bevy_utils' (#12254)
# Objective
Fixes #11298. Make the use of bevy_log vs bevy_utils::tracing more
consistent.

## Solution
Replace all uses of bevy_log's logging macros with the reexport from
bevy_utils. Remove bevy_log as a dependency where it's no longer needed
anymore.

Ideally we should just be using tracing directly, but given that all of
these crates are already using bevy_utils, this likely isn't that great
of a loss right now.
2024-03-02 18:38:04 +00:00
Nicola Papale
f7f7e326e5
Add methods to directly load assets from World (#12023)
# Objective

`FromWorld` is often used to group loading and creation of assets for
resources.

With this setup, users often end up repetitively calling
`.resource::<AssetServer>` and `.resource_mut::<Assets<T>>`, and may
have difficulties handling lifetimes of the returned references.

## Solution

Add extension methods to `World` to add and load assets, through a new
extension trait defined in `bevy_asset`.

### Other considerations

* This might be a bit too "magic", as it makes implicit the resource
access.
* We could also implement `DirectAssetAccessExt` on `App`, but it didn't
feel necessary, as `FromWorld` is the principal use-case here.

---

## Changelog

* Add the `DirectAssetAccessExt` trait, which adds the `add_asset`,
`load_asset` and `load_asset_with_settings` method to the `World` type.
2024-02-27 00:28:26 +00:00
nil
3bdeac6a42
Add to_bits and from_bits functions to AssetIndex (#12127)
# Objective

The `AssetIndex` cannot be carried across boundaries that do not allow
explicit rust types.

For context, I ran into this issue while trying to implent an
improvement for bevy_egui which leverages the not-so-new custom loader
API. Passing through a handle directly isn't possible, but instead it
requires stringified URI s. I had to work around the lack of this API s
existance using reflection, which is rather dirty.

## Solution

- Add `to_bits` and `from_bits` functions to `AssetIndex` to allow
moving this type through such boundaries.

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-02-26 21:02:26 +00:00
Tristan Guichaoua
1cded6ac60
Use immutable key for HashMap and HashSet (#12086)
# Objective

Memory usage optimisation

## Solution

`HashMap` and `HashSet`'s keys are immutable. So using mutable types
like `String`, `Vec<T>`, or `PathBuf` as a key is a waste of memory:
they have an extra `usize` for their capacity and may have spare
capacity.
This PR replaces these types by their immutable equivalents `Box<str>`,
`Box<[T]>`, and `Box<Path>`.

For more context, I recommend watching the [Use Arc Instead of
Vec](https://www.youtube.com/watch?v=A4cKi7PTJSs) video.

---------

Co-authored-by: James Liu <contact@jamessliu.com>
2024-02-26 16:27:40 +00:00
James Liu
51edf9cc8f
Remove the UpdateAssets and AssetEvents schedules (#11986)
# Objective
Fix #11845.

## Solution
Remove the `UpdateAssets` and `AssetEvents` schedules. Moved the
`UpdateAssets` systems to `PreUpdate`, and `AssetEvents` systems into
`First`. The former is meant to run before any of the event flushes.

## Future Work
It'd be ideal if we could manually flush the events for assets to avoid
needing two, sort of redundant, systems. This should at least let them
potentially run in parallel with all of the systems in the schedules
they were moved to.

---

## Changelog
Removed: `UpdateAssets` schedule from the main schedule. All systems
have been moved to `PreUpdate`.
Removed: `AssetEvents` schedule from the main schedule. All systems have
been move to `First` with the same system sets.

## Migration Guide
TODO
2024-02-26 16:05:50 +00:00
Ian Forsey
14042b1e34
Normalise root path in file_watcher (#12102)
# Objective

- I hit an issue using the `file_watcher` feature to hot reload assets
for my game. The change in this PR allows me to now hot reload assets.
- The issue stemmed from my project being a multi crate workspace
project structured like so:
```
└── my_game
    ├── my_game_core
    │   ├── src
    │   └── assets
    ├── my_game_editor
    │   └── src/main.rs
    └── my_game
        └── src/main.rs
```

 - `my_game_core` is a crate that holds all my game logic and assets
- `my_game` is the crate that creates the binary for my game (depends on
the game logic and assets in `my_game_core`)
- `my_game_editor` is an editor tool for my game (it also depends on the
game logic and assets in `my_game_core`)

Whilst running `my_game` and `my_game_editor` from cargo during
development I would use `AssetPlugin` like so:

```rust
default_plugins.set(AssetPlugin {
  watch_for_changes_override: Some(true),
  file_path: "../my_game_core/assets".to_string(),
  ..Default::default()
})
```

This works fine; bevy picks up the assets. However on saving an asset I
would get the following panic from `file_watcher`. It wouldn't kill the
app, but I wouldn't see the asset hot reload:

```
thread 'notify-rs debouncer loop' panicked at /Users/ian/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_asset-0.12.1/src/io/file/file_watcher.rs:48:58:
called `Result::unwrap()` on an `Err` value: StripPrefixError(())
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

## Solution

- The solution is to collapse dot segments in the root asset path
`FileWatcher` is using
- There was already bevy code to do this in `AssetPath`, so I extracted
that code so it could be reused in `FileWatcher`
2024-02-25 15:21:06 +00:00
Nicola Papale
78b5e49202
Add a way to get a strong handle from an AssetId (#12088)
# Objective

- Sometimes, it is useful to get a `Handle<T>` from an `AssetId<T>`. For
example, when iterating `Assets` to find a specific asset. So much so
that it's possible to do so with `AssetServer::get_id_handle`
- However, `AssetServer::get_id_handle` doesn't work with assets
directly added to `Assets` using `Assets::add`.
- Fixes #12087

## Solution

- Add `Assets::get_strong_handle` to convert an `AssetId` into an
`Handle`
- Document `AssetServer::get_id_handle` to explain its limitation and
point to `get_strong_handle`.
- Add a test for `get_strong_handle`
- Add a `duplicate_handles` field to `Assets` to avoid dropping assets
with a live handle generated by `get_strong_handle` (more reference
counting yay…)
- Fix typos in `Assets` docs

---

## Changelog

- Add `Assets::get_strong_handle` to convert an `AssetId` into an
`Handle`
2024-02-25 15:20:03 +00:00
Torstein Grindvik
54e2b2ea07
Improve file watcher error msg (#12060)
# Objective

When dealing with custom asset sources it can be a bit tricky to get
asset roots combined with relative paths correct.
It's even harder when it isn't mentioned which path was problematic.

## Solution

Mention which path failed for the file watcher.

Signed-off-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
Co-authored-by: Torstein Grindvik <torstein.grindvik@muybridge.com>
2024-02-23 17:39:33 +00:00
Ame
9d67edc3a6
fix some typos (#12038)
# Objective

Split - containing only the fixed typos

-
https://github.com/bevyengine/bevy/pull/12036#pullrequestreview-1894738751


# Migration Guide
In `crates/bevy_mikktspace/src/generated.rs` 

```rs
// before
pub struct SGroup {
    pub iVertexRepresentitive: i32,
    ..
}

// after
pub struct SGroup {
    pub iVertexRepresentative: i32,
    ..
}
```

In `crates/bevy_core_pipeline/src/core_2d/mod.rs`

```rs
// before
Node2D::ConstrastAdaptiveSharpening

// after
Node2D::ContrastAdaptiveSharpening
```

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: James Liu <contact@jamessliu.com>
Co-authored-by: François <mockersf@gmail.com>
2024-02-22 18:55:22 +00:00
Yutao Yuan
11a3b77811
Create imported_assets directory with full path (#12022)
# Objective

- The file asset source currently creates the `imported_assets/Default`
directory with relative path, which leads to wrongly created directories
when the executable is run with a working directory different from the
project root.

## Solution

- Use the full path instead.
2024-02-21 21:59:59 +00:00
github-actions[bot]
e7c3359c4b
Bump Version after Release (#12020)
Fixes #12016.

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 <mockersf@gmail.com>
2024-02-21 20:58:59 +00:00
Nicola Papale
7e782f1edf
Fix example docs on embedded_asset macro (#12003)
# Objective

The derive macro wasn't doc-commented, so it showed up in the generated
doc as follow:

```rust
#[derive(Asset, TypePath)]
let shader = asset_server.load::<Shader>("embedded://bevy_rock/render/rock.wgsl");
```

Which is very confusing

## Solution

Comment the `derive` attribute as well
2024-02-20 16:13:30 +00:00
Noa
cb5ff51d1e
Qualify embedded_asset expansion with $crate:: (#11961)
# Objective

Right now, if you call `embedded_asset` with 2 arguments as a qualified
path it doesn't work (`bevy::asset::embedded_asset!(app, "foo.wgsl")` ->
"cannot find macro `embedded_asset` in this scope")

## Solution

Use `$crate::` in expansion for 2-arg case.
2024-02-18 21:52:32 +00:00
Carter Anderson
abb8c353f4
Release 0.13.0 (#11920)
Bump Bevy crates to 0.13.0 in preparation for release.

(Note that we accidentally skipped the `0.13.0-dev` step this cycle)
2024-02-17 09:24:25 +00:00
thepackett
16d710cb3f
Fix asset loader registration warning (#11870)
# Objective

When registering and preregistering asset loaders, there would be a
`warn!` if multiple asset loaders use a given extension, and an `info!`
if multiple asset loaders load the same asset type. Since both of these
situations are individually fine, it was decided that these messages
should be removed.

## Solution

Replace both of these messages with a new `warn!` that notes that if
multiple asset loaders share the same asset type _and_ share extensions,
that the loader must be specified in the `.meta` file for those assets
in order to solve the ambiguity. This is a more useful message, since it
notes when a user must take special action / consideration.
2024-02-16 16:30:10 +00:00
Zachary Harrold
7b5a4ec4ed
Use Asset Path Extension for AssetLoader Disambiguation (#11644)
# Objective

- Fixes #11638
- See
[here](https://github.com/bevyengine/bevy/issues/11638#issuecomment-1920508465)
for details on the cause of this issue.

## Solution

- Modified `AssetLoaders` to capture possibility of multiple
`AssetLoader` registrations operating on the same `Asset` type, but
different extensions.
- Added an algorithm which will attempt to resolve via `AssetLoader`
name, then `Asset` type, then by extension. If at any point multiple
loaders fit a particular criteria, the next criteria is used as a tie
breaker.
2024-02-12 15:44:55 +00:00
James Liu
eee71bfa93
Put asset_events behind a run condition (#11800)
# Objective
Scheduling low cost systems has significant overhead due to task pool
contention and the extra machinery to schedule and run them. Following
the example of #7728, `asset_events` is good example of this kind of
system, where there is no work to be done when there are no queued asset
events.

## Solution
Put a run condition on it that checks if there are any queued events.

## Performance
Tested against `many_foxes`, we can see a slight improvement in the
total time spent in `UpdateAssets`. Also noted much less volatility due
to not being at the whim of the OS thread scheduler.

![image](https://github.com/bevyengine/bevy/assets/3137680/e0b282bf-27d0-4fe4-81b9-ecd72ab258e5)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-02-12 15:19:36 +00:00
Doonv
054134fba2
Add ReflectKind (#11664)
# Objective

Fix https://github.com/bevyengine/bevy/issues/11657

## Solution

Add a `ReflectKind` enum, add `Reflect::reflect_kind` which returns a
`ReflectKind`, and add `kind` method implementions to `ReflectRef`,
`ReflectMut`, and `ReflectOwned`, which returns a `ReflectKind`.

I also changed `AccessError` to use this new struct instead of it's own
`TypeKind` struct.

---

## Changelog

- Added `ReflectKind`, an enumeration over the kinds of a reflected type
without its data.
- Added `Reflect::reflect_kind` (with default implementation)
- Added implementation for the `kind` method on `ReflectRef`,
`ReflectMut`, and `ReflectOwned` which gives their kind without any
information, as a `ReflectKind`
2024-02-07 00:36:23 +00:00
SpecificProtagonist
21aa5fe2b6
Use TypeIdMap whenever possible (#11684)
Use `TypeIdMap<T>` instead of `HashMap<TypeId, T>`

- ~~`TypeIdMap` was in `bevy_ecs`. I've kept it there because of
#11478~~
- ~~I haven't swapped `bevy_reflect` over because it doesn't depend on
`bevy_ecs`, but I'd also be happy with moving `TypeIdMap` to
`bevy_utils` and then adding a dependency to that~~
- ~~this is a slight change in the public API of
`DrawFunctionsInternal`, does this need to go in the changelog?~~

## Changelog
- moved `TypeIdMap` to `bevy_utils`
- changed `DrawFunctionsInternal::indices` to `TypeIdMap`

## Migration Guide

- `TypeIdMap` now lives in `bevy_utils`
- `DrawFunctionsInternal::indices` now uses a `TypeIdMap`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-02-03 23:47:04 +00:00
Tristan Guichaoua
694c06f3d0
Inverse missing_docs logic (#11676)
# Objective

Currently the `missing_docs` lint is allowed-by-default and enabled at
crate level when their documentations is complete (see #3492).
This PR proposes to inverse this logic by making `missing_docs`
warn-by-default and mark crates with imcomplete docs allowed.

## Solution

Makes `missing_docs` warn at workspace level and allowed at crate level
when the docs is imcomplete.
2024-02-03 21:40:55 +00:00
CowSociety
8866c61161
Fix AssetTransformer breaking LabeledAssets (#11626)
# Objective

- `AssetTransformer` provides an input asset, and output an asset, but
provides no access to the `LabeledAsset`'s created by the `AssetLoader`.
Labeled sub assets are an extremely important piece of many assets, Gltf
in particular, and without them the amount of transformation on an asset
is limited. In order for `AssetTransformer`'s to be useful, they need to
have access to these sub assets.
- LabeledAsset's loaded by `AssetLoader`s are provided to `AssetSaver`s
in the `LoadAndSave` process, but the `LoadTransformAndSave` process
drops these values in the transform stage, and so `AssetSaver` is given
none.
- Fixes #11606

Ideally the AssetTransformer should not ignore labeled sub assets, and
they should be kept at least for the AssetSaver

## Solution

- I created a new struct similar to `SavedAsset` named
`TransformedAsset` which holds the input asset, and the HashMap of
`LabeledAsset`s. The transform function now takes as input a
`TransformedAsset`, and returns a `TransformedAsset::<AssetOutput>`.
This gives the transform function access to the labeled sub assets
created by the `AssetLoader`.
- I also created `TransformedSubAsset` which holds mutable references to
a sub asset and that sub assets HashMap of `LabeledAsset`s. This allows
you to travers the Tree of `LabeledAsset`s by reference relatively
easily.
- The `LoadTransformAndSave` processor was then reworked to use the new
structs, stopping the `LabeledAsset`s from being dropped.

---

## Changelog

- Created TransformedAsset struct and TransformedSubAsset struct.
- Changed `get_untyped_handle` to return a `UntypedHandle` directly
rather than a reference and added `get_handle` as a typed variant in
SavedAsset and TransformedAsset
- Added `SavedAsset::from_transformed` as a constructor from a
`TransformedAsset`
- Switched LoadTransformAndSave process code to work with new
`TransformedAsset` type
- Added a `ProcessError` for `AssetTransformer` in process.rs
- Switched `AssetTransformer::transform` to use `TransformedAsset` as
input and output.
- Switched `AssetTransformer` to use a `BoxedFuture` like `AssetLoader`
and `AssetSaver` to allow for async transformation code.
- Updated AssetTransformer example to use new structure.
2024-02-02 14:57:31 +00:00
Duncan
176223b406
Fix embedded asset path manipulation (#10383)
# Objective

Fixes #10377

## Solution

Use `Path::strip_prefix` instead of `str::split`. Avoid any explicit "/"
characters in path manipulation.

---

## Changelog

- Added: example of embedded asset loading
- Added: support embedded assets in external crates
- Fixed: resolution of embedded assets
- Fixed: unexpected runtime panic during asset path resolution

## Migration Guide

No API changes.

---------

Co-authored-by: Shane Celis <shane.celis@gmail.com>
2024-02-02 14:49:05 +00:00
Zachary Harrold
afa7b5cba5
Added Support for Extension-less Assets (#10153)
# Objective

- Addresses **Support processing and loading files without extensions**
from #9714
- Addresses **More runtime loading configuration** from #9714
- Fixes #367
- Fixes #10703

## Solution

`AssetServer::load::<A>` and `AssetServer::load_with_settings::<A>` can
now use the `Asset` type parameter `A` to select a registered
`AssetLoader` without inspecting the provided `AssetPath`. This change
cascades onto `LoadContext::load` and `LoadContext::load_with_settings`.
This allows the loading of assets which have incorrect or ambiguous file
extensions.

```rust
// Allow the type to be inferred by context
let handle = asset_server.load("data/asset_no_extension");

// Hint the type through the handle
let handle: Handle<CustomAsset> = asset_server.load("data/asset_no_extension");

// Explicit through turbofish
let handle = asset_server.load::<CustomAsset>("data/asset_no_extension");
```

Since a single `AssetPath` no longer maps 1:1 with an `Asset`, I've also
modified how assets are loaded to permit multiple asset types to be
loaded from a single path. This allows for two different `AssetLoaders`
(which return different types of assets) to both load a single path (if
requested).

```rust
// Uses GltfLoader
let model = asset_server.load::<Gltf>("cube.gltf");

// Hypothetical Blob loader for data transmission (for example)
let blob = asset_server.load::<Blob>("cube.gltf");
```

As these changes are reflected in the `LoadContext` as well as the
`AssetServer`, custom `AssetLoaders` can also take advantage of this
behaviour to create more complex assets.

---

## Change Log

- Updated `custom_asset` example to demonstrate extension-less assets.
- Added `AssetServer::get_handles_untyped` and Added
`AssetServer::get_path_ids`

## Notes

As a part of that refactor, I chose to store `AssetLoader`s (within
`AssetLoaders`) using a `HashMap<TypeId, ...>` instead of a `Vec<...>`.
My reasoning for this was I needed to add a relationship between `Asset`
`TypeId`s and the `AssetLoader`, so instead of having a `Vec` and a
`HashMap`, I combined the two, removing the `usize` index from the
adjacent maps.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-01-31 14:58:08 +00:00
CowSociety
ad0af31b05
Make SavedAsset::get_labeled accept &str as label (#11612)
# Objective

- SavedAsset's iter_labels returns ```&str```, however accessing
LabeledAssets requires ```CowArc<'static, str>```
- Although SavedAsset holds UntypedHandles in its hashmap of
LabeledAssets, they are inaccessible as LabeledAssets are casted to
SavedAsset or ErasedLoadedAsset, which don't contain their
UntypedHandles
- Adresses #11609

## Solution

- Used Trait bounds to allow for either ```CowArc<'static, str>``` or
```&str``` to be used as a label in get_labeled and get_erased_labeled.
- Added method get_untyped_handle to get UntypedHandle from the
LabeledAsset.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-01-30 22:18:41 +00:00