Commit graph

238 commits

Author SHA1 Message Date
sark
84bf6f611a Export anyhow::error for custom asset loaders (#5359)
If users try to implement a custom asset loader, they must manually import anyhow::error as it's used by the asset loader trait but not exported.

2b93ab5812/examples/asset/custom_asset.rs (L25)

Fixes #3138

Co-authored-by: sark <sarkahn@hotmail.com>
2022-07-20 14:14:30 +00:00
François
814f8d1635 update wgpu to 0.13 (#5168)
# Objective

- Update wgpu to 0.13
- ~~Wait, is wgpu 0.13 released? No, but I had most of the changes already ready since playing with webgpu~~ well it has been released now
- Also update parking_lot to 0.12 and naga to 0.9

## Solution

- Update syntax for wgsl shaders https://github.com/gfx-rs/wgpu/blob/master/CHANGELOG.md#wgsl-syntax
- Add a few options, remove some references: https://github.com/gfx-rs/wgpu/blob/master/CHANGELOG.md#other-breaking-changes
- fragment inputs should now exactly match vertex outputs for locations, so I added exports for those to be able to reuse them https://github.com/gfx-rs/wgpu/pull/2704
2022-07-14 21:17:16 +00:00
Ben Reeves
847f47d8d4 Remove rand crate from dependency tree (#3992)
This replaces `rand` with `fastrand` as the source of randomness for `HandleId::new()` in `bevy_asset`. This was the only crate with a dependency on `rand`, and now the dependency exists only as a dev-dependency.

`fastrand` was already in the dependency tree, thanks to `futures-lite`, `async-executor`, and `tempfile` to name a few.

## Changelog

Removed `rand` from dependencies in `bevy_asset` in favor of existing in-tree `fast-rand`
2022-07-14 17:00:01 +00:00
Mark Nokalt
f9c1a8a3d5 docs: Full documentation for bevy_asset (#3536)
# Objective

This PR aims to document the `bevy_asset` crate to complete coverage, while also trying to improve some bits of UX.

### Progress

- [x] Root items
- [x] `handle` module
- [x] `info` module
- [x] `path` module
- [x] `loader` module
- [x] `io` and `filesystem_watcher` module
- [x] `assets` module
- [x] `asset_server` module
- [x] `diagnostic` module
- [x] `debug_asset_server` module
- [x] Crate level documentation
- [x] Add `#![warn(missing_docs)]` lint

Coverage: 100%

## Migration Guide

- Rename `FileAssetIo::get_root_path` uses to `FileAssetIo::get_base_path`

    `FileAssetIo::root_path()` is a getter for the `root_path` field, while `FileAssetIo::get_root_path` returned the parent directory of the asset root path, which was the executable's directory unless `CARGO_MANIFEST_DIR` was set. This change solves the ambiguity between the two methods.
2022-07-12 15:44:09 +00:00
ira
4847f7e3ad Update codebase to use IntoIterator where possible. (#5269)
Remove unnecessary calls to `iter()`/`iter_mut()`.
Mainly updates the use of queries in our code, docs, and examples.

```rust
// From
for _ in list.iter() {
for _ in list.iter_mut() {

// To
for _ in &list {
for _ in &mut list {
```

We already enable the pedantic lint [clippy::explicit_iter_loop](https://rust-lang.github.io/rust-clippy/stable/) inside of Bevy. However, this only warns for a few known types from the standard library.

## Note for reviewers
As you can see the additions and deletions are exactly equal.
Maybe give it a quick skim to check I didn't sneak in a crypto miner, but you don't have to torture yourself by reading every line.
I already experienced enough pain making this PR :) 


Co-authored-by: devil-ira <justthecooldude@gmail.com>
2022-07-11 15:28:50 +00:00
Rob Parrett
5e1756954f Derive default for enums where possible (#5158)
# Objective

Fixes #5153

## Solution

Search for all enums and manually check if they have default impls that can use this new derive.

By my reckoning:

| enum | num |
|-|-|
| total | 159 |
| has default impl | 29 |
| default is unit variant | 23 |
2022-07-01 03:42:15 +00:00
Robert Gabriel Jakabosky
a138804d61 Add reload_asset method to AssetServer. (#5106)
# Objective

Add support for custom `AssetIo` implementations to trigger reloading of an asset.

## Solution

- Add a public method to `AssetServer` to allow forcing the reloading of an asset.

---

## Changelog

- Add method `reload_asset` to `AssetServer`.


Co-authored-by: Robert G. Jakabosky <rjakabosky+neopallium@neoawareness.com>
2022-06-26 21:45:04 +00:00
Jakob Hellermann
218b0fd3b6 bevy_reflect: put serialize into external ReflectSerialize type (#4782)
builds on top of #4780 

# Objective

`Reflect` and `Serialize` are currently very tied together because `Reflect` has a `fn serialize(&self) -> Option<Serializable<'_>>` method. Because of that, we can either implement `Reflect` for types like `Option<T>` with `T: Serialize` and have `fn serialize` be implemented, or without the bound but having `fn serialize` return `None`.

By separating `ReflectSerialize` into a separate type (like how it already is for `ReflectDeserialize`, `ReflectDefault`), we could separately `.register::<Option<T>>()` and `.register_data::<Option<T>, ReflectSerialize>()` only if the type `T: Serialize`.

This PR does not change the registration but allows it to be changed in a future PR.

## Solution

- add the type
```rust
struct ReflectSerialize { .. }
impl<T: Reflect + Serialize> FromType<T> for ReflectSerialize { .. }
```

- remove `#[reflect(Serialize)]` special casing. 

- when serializing reflect value types, look for `ReflectSerialize` in the `TypeRegistry` instead of calling `value.serialize()`
2022-06-20 17:18:58 +00:00
François
bb1d524833 Cleanups in diagnostics (#3871)
- changed `EntityCountDiagnosticsPlugin` to not use an exclusive system to get its entity count
- removed mention of `WgpuResourceDiagnosticsPlugin` in example `log_diagnostics` as it doesn't exist anymore
- added ability to enable, disable ~~or toggle~~ a diagnostic (fix #3767)
- made diagnostic values lazy, so they are only computed if the diagnostic is enabled
- do not log an average for diagnostics with only one value
- removed `sum` function from diagnostic as it isn't really useful
- ~~do not keep an average of the FPS diagnostic. it is already an average on the last 20 frames, so the average FPS was an average of the last 20 frames over the last 20 frames~~
- do not compute the FPS value as an average over the last 20 frames but give the actual "instant FPS"
- updated log format to use variable capture
- added some doc
- the frame counter diagnostic value can be reseted to 0
2022-06-20 17:02:25 +00:00
James Liu
012ae07dc8 Add global init and get accessors for all newtyped TaskPools (#2250)
Right now, a direct reference to the target TaskPool is required to launch tasks on the pools, despite the three newtyped pools (AsyncComputeTaskPool, ComputeTaskPool, and IoTaskPool) effectively acting as global instances. The need to pass a TaskPool reference adds notable friction to spawning subtasks within existing tasks. Possible use cases for this may include chaining tasks within the same pool like spawning separate send/receive I/O tasks after waiting on a network connection to be established, or allowing cross-pool dependent tasks like starting dependent multi-frame computations following a long I/O load. 

Other task execution runtimes provide static access to spawning tasks (i.e. `tokio::spawn`), which is notably easier to use than the reference passing required by `bevy_tasks` right now.

This PR makes does the following:

 * Adds `*TaskPool::init` which initializes a `OnceCell`'ed with a provided TaskPool. Failing if the pool has already been initialized.
 * Adds `*TaskPool::get` which fetches the initialized global pool of the respective type or panics. This generally should not be an issue in normal Bevy use, as the pools are initialized before they are accessed.
 * Updated default task pool initialization to either pull the global handles and save them as resources, or if they are already initialized, pull the a cloned global handle as the resource.

This should make it notably easier to build more complex task hierarchies for dependent tasks. It should also make writing bevy-adjacent, but not strictly bevy-only plugin crates easier, as the global pools ensure it's all running on the same threads.

One alternative considered is keeping a thread-local reference to the pool for all threads in each pool to enable the same `tokio::spawn` interface. This would spawn tasks on the same pool that a task is currently running in. However this potentially leads to potential footgun situations where long running blocking tasks run on `ComputeTaskPool`.
2022-06-09 02:43:24 +00:00
Alice Cecile
3a9383f997 Revert ndk-glue to 0.5 to synchronize with winit (#4916)
# Objective

- Upgrading ndk-glue (our Android interop layer) desynchronized us from winit
- This further broke Android builds, see #4905 (oops...)
- Reverting to 0.5 should help with this, until the new `winit` version releases
- Fixes #4774 and closes #4529
2022-06-04 14:30:44 +00:00
Félix Lescaudey de Maneville
f000c2b951 Clippy improvements (#4665)
# Objective

Follow up to my previous MR #3718 to add new clippy warnings to bevy:

- [x] [~~option_if_let_else~~](https://rust-lang.github.io/rust-clippy/master/#option_if_let_else) (reverted)
- [x] [redundant_else](https://rust-lang.github.io/rust-clippy/master/#redundant_else)
- [x] [match_same_arms](https://rust-lang.github.io/rust-clippy/master/#match_same_arms)
- [x] [semicolon_if_nothing_returned](https://rust-lang.github.io/rust-clippy/master/#semicolon_if_nothing_returned)
- [x] [explicit_iter_loop](https://rust-lang.github.io/rust-clippy/master/#explicit_iter_loop)
- [x] [map_flatten](https://rust-lang.github.io/rust-clippy/master/#map_flatten)

There is one commit per clippy warning, and the matching flags are added to the CI execution.

To test the CI execution you may run `cargo run -p ci -- clippy` at the root.

I choose the add the flags in the `ci` tool crate to avoid having them in every `lib.rs` but I guess it could become an issue with suprise warnings coming up after a commit/push


Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-05-31 01:38:07 +00:00
Daniel McNab
1bbd5c25c0 Enforce type safe usage of Handle::get (#4794)
# Objective

- Sometimes, people might load an asset as one type, then use it with an `Asset`s for a different type.
- See e.g. #4784. 
- This is especially likely with the Gltf types, since users may not have a clear conceptual model of what types the assets will be.
- We had an instance of this ourselves, in the `scene_viewer` example

## Solution

- Make `Assets::get` require a type safe handle.

---

## Changelog

### Changed

- `Assets::<T>::get` and `Assets::<T>::get_mut` now require that the passed handles are `Handle<T>`, improving the type safety of handles.

### Added
- `HandleUntyped::typed_weak`, a helper function for creating a weak typed version of an exisitng `HandleUntyped`.

## Migration Guide

`Assets::<T>::get` and `Assets::<T>::get_mut` now require that the passed handles are `Handle<T>`, improving the type safety of handles. If you were previously passing in:
   - a `HandleId`, use `&Handle::weak(id)` instead, to create a weak handle. You may have been able to store a type safe `Handle` instead.
   - a `HandleUntyped`, use `&handle_untyped.typed_weak()` to create a weak handle of the specified type. This is most likely to be the useful when using [load_folder](https://docs.rs/bevy_asset/latest/bevy_asset/struct.AssetServer.html#method.load_folder)
   - a `Handle<U>` of  of a different type, consider whether this is the correct handle type to store. If it is (i.e. the same handle id is used for multiple different Asset types) use `Handle::weak(handle.id)` to cast to a different type.
2022-05-30 16:59:44 +00:00
dependabot[bot]
5422a2bc16 Update ndk-glue requirement from 0.5 to 0.6 (#3624)
Updates the requirements on [ndk-glue](https://github.com/rust-windowing/android-ndk-rs) to permit the latest version.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/rust-windowing/android-ndk-rs/releases">ndk-glue's releases</a>.</em></p>
<blockquote>
<h2>ndk-glue v0.6.0</h2>
<ul>
<li><strong>Breaking:</strong> Update to <code>ndk-sys 0.3.0</code> and <code>ndk 0.6.0</code>. (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/214">#214</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="f4dc7265aa"><code>f4dc726</code></a> Release ndk-sys-0.3.0, ndk-0.6.0, ndk-glue-0.6.0 (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/214">#214</a>)</li>
<li><a href="8e59a347bd"><code>8e59a34</code></a> ndk-sys: Use <code>jni-sys</code> for low-level JNI bindings (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/209">#209</a>)</li>
<li><a href="240389f1e2"><code>240389f</code></a> ndk-build,cargo-apk: Default <code>target_sdk_version</code> to 30 or lower (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/203">#203</a>)</li>
<li><a href="2d554daa30"><code>2d554da</code></a> Update README.md with links to cargo apk README.md (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/195">#195</a>)</li>
<li><a href="39d4701cc6"><code>39d4701</code></a> cargo-apk: Use <code>min_sdk_version</code> to select compiler target (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/197">#197</a>)</li>
<li><a href="317d71101f"><code>317d711</code></a> ci emulator: Cache AVD emulator setup to speed up repeated jobs (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/202">#202</a>)</li>
<li><a href="6e7658719b"><code>6e76587</code></a> readme: Use <code>console</code> code blocks for shell commands (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/196">#196</a>)</li>
<li><a href="63cbffa77a"><code>63cbffa</code></a> ndk-sys: Add all missing android-related headers with NDK 23.1.7779620 (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/201">#201</a>)</li>
<li><a href="55539dc555"><code>55539dc</code></a> Release ndk-build-0.4.3, cargo-apk-0.8.2 (<a href="https://github-redirect.dependabot.com/rust-windowing/android-ndk-rs/issues/192">#192</a>)</li>
<li>See full diff in <a href="https://github.com/rust-windowing/android-ndk-rs/compare/ndk-glue-0.5.0...ndk-glue-0.6.0">compare view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>
2022-05-16 18:32:26 +00:00
Yutao Yuan
aabc47f290 Make public macros more robust with $crate (#4655)
# Objective

We have some macros that are public but only used internally for now. They fail on user's code due to the use of crate names like `bevy_utils`, while the user only has `bevy::utils`. There are two affected macros.

- `bevy_utils::define_label`: it may be useful in user's code for defining custom kinds of label traits (this is why I made this PR).
- `bevy_asset::load_internal_asset`: not useful currently due to limitations of the debug asset server, but this may change in the future.

## Solution

We can make them work by using `$crate` instead of names of their own crates, which can refer to the macro's defining crate regardless of the user's setup. Even though our objective is rather low-priority here, the solution adds no maintenance cost so it is still worthwhile.
2022-05-06 19:29:45 +00:00
Johannes Hackel
e29bd50de8 Add file metadata to AssetIo (#2123)
This is a replacement for #2106

This adds a `Metadata` struct which contains metadata information about a file, at the moment only the file type.
It also adds a `get_metadata` to `AssetIo` trait and an `asset_io` accessor method to `AssetServer` and `LoadContext`

I am not sure about the changes in `AndroidAssetIo ` and `WasmAssetIo`.
2022-05-02 18:04:47 +00:00
Daniel McNab
bc7293e922 Some minor cleanups of asset_server (#4604)
# Objective

- Code quality bad

## Solution

- Code quality better
- Using rust-analyzer's inline function and inline variable quick assists, I validated that the call to `AssetServer::new` is exactly the same code as the previous version.
2022-04-26 20:47:16 +00:00
Yutao Yuan
8d67832dfa Bump Bevy to 0.8.0-dev (#4505)
# Objective

We should bump our version to 0.8.0-dev after releasing 0.7.0, according to our release checklist.

## Solution

Do it.
2022-04-17 23:04:52 +00:00
Carter Anderson
83c6ffb73c release 0.7.0 (#4487) 2022-04-15 18:05:37 +00:00
Alice Cecile
7ce3ae43e3 Bump Bevy to 0.7.0-dev (#4230)
# Objective

- The [dev docs](https://dev-docs.bevyengine.org/bevy/index.html#) show version 0.6.0, which is actively misleading.

[Image of the problem](https://cdn.discordapp.com/attachments/695741366520512563/953513612943704114/Screenshot_20220316-154100_Firefox-01.jpeg)

Noticed by @ickk, fix proposed by @mockersf.

## Solution

- Bump the version across all Bevy crates to 0.7.0 dev.
- Set a reminder in the Release Checklist to remember to do this each release.
2022-03-19 03:54:15 +00:00
François
baae97d002 iter_mut on Assets: send modified event only when asset is iterated over (#3565)
# Objective

- `Assets<T>::iter_mut` sends `Modified` event for all assets first, then returns the iterator
- This means that events could be sent for assets that would not have been mutated if iteration was stopped before

## Solution

- Send `Modified` event when assets are iterated over.


Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
2022-03-05 21:25:30 +00:00
pubrrr
caf6611c62 remove Events from bevy_app, they now live in bevy_ecs (#4066)
# Objective

Fixes #4064.

## Solution

- remove Events from bevy_app
2022-03-01 19:33:56 +00:00
Alice Cecile
557ab9897a Make get_resource (and friends) infallible (#4047)
# Objective

- In the large majority of cases, users were calling `.unwrap()` immediately after `.get_resource`.
- Attempting to add more helpful error messages here resulted in endless manual boilerplate (see #3899 and the linked PRs).

## Solution

- Add an infallible variant named `.resource` and so on.
- Use these infallible variants over `.get_resource().unwrap()` across the code base.

## Notes

I did not provide equivalent methods on `WorldCell`, in favor of removing it entirely in #3939.

## Migration Guide

Infallible variants of `.get_resource` have been added that implicitly panic, rather than needing to be unwrapped.

Replace `world.get_resource::<Foo>().unwrap()` with `world.resource::<Foo>()`.

## Impact

- `.unwrap` search results before: 1084
- `.unwrap` search results after: 942
- internal `unwrap_or_else` calls added: 4
- trivial unwrap calls removed from tests and code: 146
- uses of the new `try_get_resource` API: 11
- percentage of the time the unwrapping API was used internally: 93%
2022-02-27 22:37:18 +00:00
Carter Anderson
98938a8555 Internal Asset Hot Reloading (#3966)
Adds "hot reloading" of internal assets, which is normally not possible because they are loaded using `include_str` / direct Asset collection access.

This is accomplished via the following:
* Add a new `debug_asset_server` feature flag
* When that feature flag is enabled, create a second App with a second AssetServer that points to a configured location (by default the `crates` folder). Plugins that want to add hot reloading support for their assets can call the new `app.add_debug_asset::<T>()` and `app.init_debug_asset_loader::<T>()` functions.
* Load "internal" assets using the new `load_internal_asset` macro. By default this is identical to the current "include_str + register in asset collection" approach. But if the `debug_asset_server` feature flag is enabled, it will also load the asset dynamically in the debug asset server using the file path. It will then set up a correlation between the "debug asset" and the "actual asset" by listening for asset change events.

This is an alternative to #3673. The goal was to keep the boilerplate and features flags to a minimum for bevy plugin authors, and allow them to home their shaders near relevant code. 

This is a draft because I haven't done _any_ quality control on this yet. I'll probably rename things and remove a bunch of unwraps. I just got it working and wanted to use it to start a conversation.

Fixes #3660
2022-02-18 22:56:57 +00:00
Carter Anderson
b3a1db60f2 Proper prehashing (#3963)
For some keys, it is too expensive to hash them on every lookup. Historically in Bevy, we have regrettably done the "wrong" thing in these cases (pre-computing hashes, then re-hashing them) because Rust's built in hashed collections don't give us the tools we need to do otherwise. Doing this is "wrong" because two different values can result in the same hash. Hashed collections generally get around this by falling back to equality checks on hash collisions. You can't do that if the key _is_ the hash. Additionally, re-hashing a hash increase the odds of collision!
 
#3959 needs pre-hashing to be viable, so I decided to finally properly solve the problem. The solution involves two different changes:

1. A new generalized "pre-hashing" solution in bevy_utils: `Hashed<T>` types, which store a value alongside a pre-computed hash. And `PreHashMap<K, V>` (which uses `Hashed<T>` internally) . `PreHashMap` is just an alias for a normal HashMap that uses `Hashed<T>` as the key and a new `PassHash` implementation as the Hasher. 
2. Replacing the `std::collections` re-exports in `bevy_utils` with equivalent `hashbrown` impls. Avoiding re-hashes requires the `raw_entry_mut` api, which isn't stabilized yet (and may never be ... `entry_ref` has favor now, but also isn't available yet). If std's HashMap ever provides the tools we need, we can move back to that. The latest version of `hashbrown` adds support for the `entity_ref` api, so we can move to that in preparation for an std migration, if thats the direction they seem to be going in. Note that adding hashbrown doesn't increase our dependency count because it was already in our tree.

In addition to providing these core tools, I also ported the "table identity hashing" in `bevy_ecs` to `raw_entry_mut`, which was a particularly egregious case.

The biggest outstanding case is `AssetPathId`, which stores a pre-hash. We need AssetPathId to be cheaply clone-able (and ideally Copy), but `Hashed<AssetPath>` requires ownership of the AssetPath, which makes cloning ids way more expensive. We could consider doing `Hashed<Arc<AssetPath>>`, but cloning an arc is still a non-trivial expensive that needs to be considered. I would like to handle this in a separate PR. And given that we will be re-evaluating the Bevy Assets implementation in the very near future, I'd prefer to hold off until after that conversation is concluded.
2022-02-18 03:26:01 +00:00
danieleades
d8974e7c3d small and mostly pointless refactoring (#2934)
What is says on the tin.

This has got more to do with making `clippy` slightly more *quiet* than it does with changing anything that might greatly impact readability or performance.

that said, deriving `Default` for a couple of structs is a nice easy win
2022-02-13 22:33:55 +00:00
ShadowCurse
62329f7fda Useful error message when two assets have the save UUID (#3739)
# Objective
Fixes #2610 and #3731

## Solution

Added check for TYPE_UUID duplication in  `register_asset_type` with an error message
2022-02-12 19:41:35 +00:00
Daniel McNab
6615b7bf64 Deprecate .system (#3302)
# Objective

- Using `.system()` is no longer idiomatic.

## Solution

- Give a warning when using it
2022-02-08 04:00:58 +00:00
François
75286b8540 check if resource for asset already exists before adding it (#3560)
# Objective

- Fix #3559 
- Avoid erasing existing resource `Assets<T>` when adding it twice

## Solution

- Before creating a new `Assets<T>`, check if it has already been added to the world


Co-authored-by: François <8672791+mockersf@users.noreply.github.com>
Co-authored-by: Aevyrie Roessler <aevyrie@gmail.com>
2022-02-06 01:07:56 +00:00
Robert Swain
e928acb9ff bevy_asset: Add AssetServerSettings watch_for_changes member (#3643)
# Objective

- `asset_server.watch_for_changes().unwrap()` only watches changes for assets loaded **_after_** that call.
- Technically, the `hot_asset_reloading` example is racey as the watch on the asset path is set up in an async task scheduled from the asset `load()`, but the filesystem watcher is only constructed in a call that comes **_after_** the call to `load()`.

## Solution

-  It feels safest to allow enabling watching the filesystem for changes on the asset server from the point of its construction. Therefore, adding such an option to `AssetServerSettings` seemed to be the correct solution.
- Fix `hot_asset_reloading` by inserting the `AssetServerSettings` resource with `watch_for_changes: true` instead of calling `asset_server.watch_for_changes().unwrap()`.
- Document the shortcomings of `.watch_for_changes()`
2022-02-04 03:21:29 +00:00
Daniel McNab
f3de12bc5e Add a warning when watch_for_changes has no effect (#3684)
# Objective

- Users can get confused when they ask for watching to be unsupported, then find it isn't supported
- Fixes https://github.com/bevyengine/bevy/issues/3683

## Solution

- Add a warning if the `watch_for_changes` call would do nothing
2022-01-21 00:29:29 +00:00
Michael Dorst
130953c717 Enable the doc_markdown clippy lint (#3457)
# Objective

CI should check for missing backticks in doc comments.

Fixes #3435

## Solution

`clippy` has a lint for this: `doc_markdown`. This enables that lint in the CI script.

Of course, enabling this lint in CI causes a bunch of lint errors, so I've gone through and fixed all of them. This was a huge edit that touched a ton of files, so I split the PR up by crate.

When all of the following are merged, the CI should pass and this can be merged.

+ [x] #3467
+ [x] #3468
+ [x] #3470 
+ [x] #3469
+ [x] #3471 
+ [x] #3472 
+ [x] #3473 
+ [x] #3474 
+ [x] #3475 
+ [x] #3476 
+ [x] #3477 
+ [x] #3478 
+ [x] #3479 
+ [x] #3480 
+ [x] #3481 
+ [x] #3482 
+ [x] #3483 
+ [x] #3484 
+ [x] #3485 
+ [x] #3486
2022-01-09 23:20:13 +00:00
Carter Anderson
2ee38cb9e0 Release 0.6.0 (#3587) 2022-01-08 10:18:22 +00:00
MrGVSV
36390a80ec Documented Handles and Assets (#3348)
# Objective

Add documentation to [Handle](7356f1586d/crates/bevy_asset/src/handle.rs (L63)) and [Assets](7356f1586d/crates/bevy_asset/src/assets.rs (L48)).

## Tasks
- [x] Document `Handle`
- [x] Document `Assets`

---

Fixes #3347


Co-authored-by: MrGVSV <49806985+MrGVSV@users.noreply.github.com>
2022-01-04 23:38:39 +00:00
Michael Dorst
32d88c7d23 Fix doc_markdown lints in bevy_asset (#3468)
#3457 adds the `doc_markdown` clippy lint, which checks doc comments to make sure code identifiers are escaped with backticks. This causes a lot of lint errors, so this is one of a number of PR's that will fix those lint errors one crate at a time.

This PR fixes lints in the `bevy_asset` crate.
2021-12-29 17:52:39 +00:00
davier
06d9384447 Add FromReflect trait to convert dynamic types to concrete types (#1395)
Dynamic types (`DynamicStruct`, `DynamicTupleStruct`, `DynamicTuple`, `DynamicList` and `DynamicMap`) are used when deserializing scenes, but currently they can only be applied to existing concrete types. This leads to issues when trying to spawn non trivial deserialized scene.
For components, the issue is avoided by requiring that reflected components implement ~~`FromResources`~~ `FromWorld` (or `Default`). When spawning, a new concrete type is created that way, and the dynamic type is applied to it. Unfortunately, some components don't have any valid implementation of these traits.
In addition, any `Vec` or `HashMap` inside a component will panic when a dynamic type is pushed into it (for instance, `Text` panics when adding a text section).

To solve this issue, this PR adds the `FromReflect` trait that creates a concrete type from a dynamic type that represent it, derives the trait alongside the `Reflect` trait, drops the ~~`FromResources`~~ `FromWorld` requirement on reflected components, ~~and enables reflection for UI and Text bundles~~. It also adds the requirement that fields ignored with `#[reflect(ignore)]` implement `Default`, since we need to initialize them somehow.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-12-26 18:49:01 +00:00
Carter Anderson
ffecb05a0a Replace old renderer with new renderer (#3312)
This makes the [New Bevy Renderer](#2535) the default (and only) renderer. The new renderer isn't _quite_ ready for the final release yet, but I want as many people as possible to start testing it so we can identify bugs and address feedback prior to release.

The examples are all ported over and operational with a few exceptions:

* I removed a good portion of the examples in the `shader` folder. We still have some work to do in order to make these examples possible / ergonomic / worthwhile: #3120 and "high level shader material plugins" are the big ones. This is a temporary measure.
* Temporarily removed the multiple_windows example: doing this properly in the new renderer will require the upcoming "render targets" changes. Same goes for the render_to_texture example.
* Removed z_sort_debug: entity visibility sort info is no longer available in app logic. we could do this on the "render app" side, but i dont consider it a priority.
2021-12-14 03:58:23 +00:00
Weasy
a2f0fe24e8 Allow String and &String as Id for AssetServer.get_handle(id) (#3280)
# Objective

Make it easier to build and use an asset path with `format!()`. This can be useful for accessing assets in a loop.

Enabled by this PR:
```rust
let monkey_handle = asset_server.get_handle(&format!("models/monkey/Monkey.gltf#Mesh0/Primitive0"));
let monkey_handle = asset_server.get_handle(format!("models/monkey/Monkey.gltf#Mesh0/Primitive0"));
```

Before this PR:
```rust
let monkey_handle = asset_server.get_handle(format!("models/monkey/Monkey.gltf#Mesh0/Primitive0").as_str());
```

It's just a tiny improvement in ergonomics, but i ran into it and was wondering why the function does not accept a `String` and Bevy is all about simplicity/ergonomics, right? 😄😉

## Solution

Implement `Into<HandleId>` for `String` and `&String`.
2021-12-09 22:40:15 +00:00
François
92a7e16aed Update dependencies ron winit& fix cargo-deny lists (#3244)
# Objective

- there are a few new versions for `ron`, `winit`, `ndk`, `raw-window-handle`
- `cargo-deny` is failing due to new security issues / duplicated dependencies

## Solution

- Update our dependencies
- Note all new security issues, with which of Bevy direct dependency it comes from
- Update duplicate crate list, with which of Bevy direct dependency it comes from

`notify` is not updated here as it's in #2993
2021-12-09 20:14:00 +00:00
François
c6fec1f0c2 Fix clippy lints for 1.57 (#3238)
# Objective

- New clippy lints with rust 1.57 are failing

## Solution

- Fixed clippy lints following suggestions
- I ignored clippy in old renderer because there was many and it will be removed soon
2021-12-02 23:40:37 +00:00
Carter Anderson
8009af3879 Merge New Renderer 2021-11-22 23:57:42 -08:00
Carter Anderson
2e79951659 Shader Imports. Decouple Mesh logic from PBR (#3137)
## Shader Imports

This adds "whole file" shader imports. These come in two flavors:

### Asset Path Imports

```rust
// /assets/shaders/custom.wgsl

#import "shaders/custom_material.wgsl"

[[stage(fragment)]]
fn fragment() -> [[location(0)]] vec4<f32> {
    return get_color();
}
```

```rust
// /assets/shaders/custom_material.wgsl

[[block]]
struct CustomMaterial {
    color: vec4<f32>;
};
[[group(1), binding(0)]]
var<uniform> material: CustomMaterial;
```

### Custom Path Imports

Enables defining custom import paths. These are intended to be used by crates to export shader functionality:

```rust
// bevy_pbr2/src/render/pbr.wgsl

#import bevy_pbr::mesh_view_bind_group
#import bevy_pbr::mesh_bind_group

[[block]]
struct StandardMaterial {
    base_color: vec4<f32>;
    emissive: vec4<f32>;
    perceptual_roughness: f32;
    metallic: f32;
    reflectance: f32;
    flags: u32;
};

/* rest of PBR fragment shader here */
```

```rust
impl Plugin for MeshRenderPlugin {
    fn build(&self, app: &mut bevy_app::App) {
        let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
        shaders.set_untracked(
            MESH_BIND_GROUP_HANDLE,
            Shader::from_wgsl(include_str!("mesh_bind_group.wgsl"))
                .with_import_path("bevy_pbr::mesh_bind_group"),
        );
        shaders.set_untracked(
            MESH_VIEW_BIND_GROUP_HANDLE,
            Shader::from_wgsl(include_str!("mesh_view_bind_group.wgsl"))
                .with_import_path("bevy_pbr::mesh_view_bind_group"),
        );
```

By convention these should use rust-style module paths that start with the crate name. Ultimately we might enforce this convention.

Note that this feature implements _run time_ import resolution. Ultimately we should move the import logic into an asset preprocessor once Bevy gets support for that.

## Decouple Mesh Logic from PBR Logic via MeshRenderPlugin

This breaks out mesh rendering code from PBR material code, which improves the legibility of the code, decouples mesh logic from PBR logic, and opens the door for a future `MaterialPlugin<T: Material>` that handles all of the pipeline setup for arbitrary shader materials.

## Removed `RenderAsset<Shader>` in favor of extracting shaders into RenderPipelineCache

This simplifies the shader import implementation and removes the need to pass around `RenderAssets<Shader>`.

##  RenderCommands are now fallible

This allows us to cleanly handle pipelines+shaders not being ready yet. We can abort a render command early in these cases, preventing bevy from trying to bind group / do draw calls for pipelines that couldn't be bound. This could also be used in the future for things like "components not existing on entities yet". 

# Next Steps

* Investigate using Naga for "partial typed imports" (ex: `#import bevy_pbr::material::StandardMaterial`, which would import only the StandardMaterial struct)
* Implement `MaterialPlugin<T: Material>` for low-boilerplate custom material shaders
* Move shader import logic into the asset preprocessor once bevy gets support for that.

Fixes #3132
2021-11-18 03:45:02 +00:00
Jerome Humbert
94f5d194f4 Doc AssetServer::load() is async (#3129)
# Objective

Document that `AssetServer::load()` is asynchronous.

## Solution

Document that `AssetServer::load()` is asynchronous, and that the asset
will not be immediately available once the call returns. Instead,
explain that the user must call `AssetServer::get_load_state()` to
monitor the loading state of an asset.
2021-11-13 22:07:19 +00:00
François
ac06ea3d17 default features from bevy_asset and bevy_ecs can actually be disabled (#3097)
# Objective

- `bevy_ecs` exposes as an optional feature `bevy_reflect`. Disabling it doesn't compile.
- `bevy_asset` exposes as an optional feature `filesystem_watcher`. Disabling it doesn't compile. It is also not possible to disable this feature from Bevy

## Solution

- Fix compilation errors when disabling the default features. Make it possible to disable the feature `filesystem_watcher` from Bevy
2021-11-13 21:15:22 +00:00
MiniaczQ
8b30dc6354 iter_mut() for Assets type (#3118)
# Objective

Fixes #3117 

## Solution

I took `get_mut()` and did it for all the elements 😏 


Co-authored-by: MiniaczQ <jakub.motyka.2000@gmail.com>
2021-11-13 04:26:42 +00:00
Yoh Deadfall
ffde86efa0 Update to edition 2021 on master (#3028)
Objective
During work on #3009 I've found that not all jobs use actions-rs, and therefore, an previous version of Rust is used for them. So while compilation and other stuff can pass, checking markup and Android build may fail with compilation errors.

Solution
This PR adds `action-rs` for any job running cargo, and updates the edition to 2021.
2021-10-27 00:12:14 +00:00
François
2f4bcc5bf7 Update for edition 2021 (#2997)
# Objective

- update for Edition 2021

## Solution

- remove the `resolver = "2"`
- update for https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html by adding a few ` `
2021-10-25 18:00:13 +00:00
Paweł Grabarz
07ed1d053e Implement and require #[derive(Component)] on all component structs (#2254)
This implements the most minimal variant of #1843 - a derive for marker trait. This is a prerequisite to more complicated features like statically defined storage type or opt-out component reflection.

In order to make component struct's purpose explicit and avoid misuse, it must be annotated with `#[derive(Component)]` (manual impl is discouraged for compatibility). Right now this is just a marker trait, but in the future it might be expanded. Making this change early allows us to make further changes later without breaking backward compatibility for derive macro users.

This already prevents a lot of issues, like using bundles in `insert` calls. Primitive types are no longer valid components as well. This can be easily worked around by adding newtype wrappers and deriving `Component` for them.

One funny example of prevented bad code (from our own tests) is when an newtype struct or enum variant is used. Previously, it was possible to write `insert(Newtype)` instead of `insert(Newtype(value))`. That code compiled, because function pointers (in this case newtype struct constructor) implement `Send + Sync + 'static`, so we allowed them to be used as components. This is no longer the case and such invalid code will trigger a compile error.


Co-authored-by: = <=>
Co-authored-by: TheRawMeatball <therawmeatball@gmail.com>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-10-03 19:23:44 +00:00
Carter Anderson
08969a24b8 Modular Rendering (#2831)
This changes how render logic is composed to make it much more modular. Previously, all extraction logic was centralized for a given "type" of rendered thing. For example, we extracted meshes into a vector of ExtractedMesh, which contained the mesh and material asset handles, the transform, etc. We looked up bindings for "drawn things" using their index in the `Vec<ExtractedMesh>`. This worked fine for built in rendering, but made it hard to reuse logic for "custom" rendering. It also prevented us from reusing things like "extracted transforms" across contexts.

To make rendering more modular, I made a number of changes:

* Entities now drive rendering:
  * We extract "render components" from "app components" and store them _on_ entities. No more centralized uber lists! We now have true "ECS-driven rendering"
  * To make this perform well, I implemented #2673 in upstream Bevy for fast batch insertions into specific entities. This was merged into the `pipelined-rendering` branch here: #2815
* Reworked the `Draw` abstraction:
  * Generic `PhaseItems`: each draw phase can define its own type of "rendered thing", which can define its own "sort key"
  * Ported the 2d, 3d, and shadow phases to the new PhaseItem impl (currently Transparent2d, Transparent3d, and Shadow PhaseItems)
  * `Draw` trait and and `DrawFunctions` are now generic on PhaseItem
  * Modular / Ergonomic `DrawFunctions` via `RenderCommands`
    * RenderCommand is a trait that runs an ECS query and produces one or more RenderPass calls. Types implementing this trait can be composed to create a final DrawFunction. For example the DrawPbr DrawFunction is created from the following DrawCommand tuple. Const generics are used to set specific bind group locations:
        ```rust
         pub type DrawPbr = (
            SetPbrPipeline,
            SetMeshViewBindGroup<0>,
            SetStandardMaterialBindGroup<1>,
            SetTransformBindGroup<2>,
            DrawMesh,
        );
        ```
    * The new `custom_shader_pipelined` example illustrates how the commands above can be reused to create a custom draw function:
       ```rust
       type DrawCustom = (
           SetCustomMaterialPipeline,
           SetMeshViewBindGroup<0>,
           SetTransformBindGroup<2>,
           DrawMesh,
       );
       ``` 
* ExtractComponentPlugin and UniformComponentPlugin:
  * Simple, standardized ways to easily extract individual components and write them to GPU buffers
* Ported PBR and Sprite rendering to the new primitives above.
* Removed staging buffer from UniformVec in favor of direct Queue usage
  * Makes UniformVec much easier to use and more ergonomic. Completely removes the need for custom render graph nodes in these contexts (see the PbrNode and view Node removals and the much simpler call patterns in the relevant Prepare systems).
* Added a many_cubes_pipelined example to benchmark baseline 3d rendering performance and ensure there were no major regressions during this port. Avoiding regressions was challenging given that the old approach of extracting into centralized vectors is basically the "optimal" approach. However thanks to a various ECS optimizations and render logic rephrasing, we pretty much break even on this benchmark!
* Lifetimeless SystemParams: this will be a bit divisive, but as we continue to embrace "trait driven systems" (ex: ExtractComponentPlugin, UniformComponentPlugin, DrawCommand), the ergonomics of `(Query<'static, 'static, (&'static A, &'static B, &'static)>, Res<'static, C>)` were getting very hard to bear. As a compromise, I added "static type aliases" for the relevant SystemParams. The previous example can now be expressed like this: `(SQuery<(Read<A>, Read<B>)>, SRes<C>)`. If anyone has better ideas / conflicting opinions, please let me know!
* RunSystem trait: a way to define Systems via a trait with a SystemParam associated type. This is used to implement the various plugins mentioned above. I also added SystemParamItem and QueryItem type aliases to make "trait stye" ecs interactions nicer on the eyes (and fingers).
* RenderAsset retrying: ensures that render assets are only created when they are "ready" and allows us to create bind groups directly inside render assets (which significantly simplified the StandardMaterial code). I think ultimately we should swap this out on "asset dependency" events to wait for dependencies to load, but this will require significant asset system changes.
* Updated some built in shaders to account for missing MeshUniform fields
2021-09-23 06:16:11 +00:00
Hoidigan
34f0085ba0 Doc warnings (#2577)
Fixes #2576 

Add <> to links where needed, fix typo and refactored names, and add docs.rs links for external items.
2021-09-14 22:46:18 +00:00
sark
4c3c4b5e40 Nightly clippy fixes (#2702)
A few minor changes to fix warnings emitted from clippy on the nightly toolchain, including redundant_allocation, unwrap_or_else_default, and collapsible_match, fixes #2698
2021-09-09 16:41:21 +00:00
François
1a758dd9e2 update ndk-glue to 0.4 (#2684)
# Objective

- We currently depends on ndk 0.2, 0.3, 0.4
- Only 0.2 dependencies comes from Bevy itself

## Solution

- Replace #1371 
- Update Bevy to ndk-glue 0.4
- Also fixes duplicate dependency CI issue
2021-08-19 01:02:15 +00:00
Carter Anderson
a89a954a17 Not me ... us (#2654)
I don't see much of a reason at this point to boost my name over anyone elses. We are all Bevy Contributors.
2021-08-15 20:08:52 +00:00
Carter Anderson
7b336fd779 fix nightly clippy lints (#2568)
Fix new nightly clippy lints on `pipelined-rendering`
2021-07-30 03:17:27 +00:00
Boxy
0b800e547b Fix some nightly clippy lints (#2522)
on nightly these two clippy lints fail:
- [needless_borrow](https://rust-lang.github.io/rust-clippy/master/#needless_borrow)
- [unused_unit](https://rust-lang.github.io/rust-clippy/master/#unused_unit)
2021-07-29 19:36:39 -07:00
Josh Kuhn
54ff7aaa1e Bump notify to 5.0.0-pre.11 (#2564)
# Objective

notify 5.0.0-pre.11 breaks the interface again, but apparently in a way that's similar to how it used to be

## Solution

Bump `bevy_asset` dependency on notify to `5.0.0-pre.11` and fix the errors that crop up.

It looks like `pre.11` was mentioned in #2528 by @mockersf but there's no mention of why `pre.10` was chosen ultimately.
2021-07-29 23:56:16 +00:00
Boxy
5ffff03b33 Fix some nightly clippy lints (#2522)
on nightly these two clippy lints fail:
- [needless_borrow](https://rust-lang.github.io/rust-clippy/master/#needless_borrow)
- [unused_unit](https://rust-lang.github.io/rust-clippy/master/#unused_unit)
2021-07-29 20:52:15 +00:00
François
b724a0f586 Down with the system! (#2496)
# Objective

- Remove all the `.system()` possible.
- Check for remaining missing cases.

## Solution

- Remove all `.system()`, fix compile errors
- 32 calls to `.system()` remains, mostly internals, the few others should be removed after #2446
2021-07-27 23:42:36 +00:00
bjorn3
6d6bc2a8b4 Merge AppBuilder into App (#2531)
This is extracted out of eb8f973646476b4a4926ba644a77e2b3a5772159 and includes some additional changes to remove all references to AppBuilder and fix examples that still used App::build() instead of App::new(). In addition I didn't extract the sub app feature as it isn't ready yet.

You can use `git diff --diff-filter=M eb8f973646476b4a4926ba644a77e2b3a5772159` to find all differences in this PR. The `--diff-filtered=M` filters all files added in the original commit but not in this commit away.

Co-Authored-By: Carter Anderson <mcanders1@gmail.com>
2021-07-27 20:21:06 +00:00
Carter Anderson
4ac2ed7cc6 pipelined rendering proof of concept 2021-07-24 16:43:37 -07:00
François
a4e5e2790e fix version of notify to 5.0.0-pre.2 (#2528)
# Objective

- https://github.com/notify-rs/notify changed their api in the latest pre-release of 0.5.0
- This breaks current main AND v0.5.0

## Solution

- Fix the dependency to the known working version

before : https://docs.rs/notify/5.0.0-pre.2/notify/trait.Watcher.html
after : https://docs.rs/notify/5.0.0-pre.11/notify/trait.Watcher.html
2021-07-24 01:41:48 +00:00
Carter Anderson
e167a1d9cf Relicense Bevy under the dual MIT or Apache-2.0 license (#2509)
This relicenses Bevy under the dual MIT or Apache-2.0 license. For rationale, see #2373.

* Changes the LICENSE file to describe the dual license. Moved the MIT license to docs/LICENSE-MIT. Added the Apache-2.0 license to docs/LICENSE-APACHE. I opted for this approach over dumping both license files at the root (the more common approach) for a number of reasons:
  * Github links to the "first" license file (LICENSE-APACHE) in its license links (you can see this in the wgpu and rust-analyzer repos). People clicking these links might erroneously think that the apache license is the only option. Rust and Amethyst both use COPYRIGHT or COPYING files to solve this problem, but this creates more file noise (if you do everything at the root) and the naming feels way less intuitive. 
  * People have a reflex to look for a LICENSE file. By providing a single license file at the root, we make it easy for them to understand our licensing approach. 
  * I like keeping the root clean and noise free
  * There is precedent for putting the apache and mit license text in sub folders (amethyst) 
* Removed the `Copyright (c) 2020 Carter Anderson` copyright notice from the MIT license. I don't care about this attribution, it might make license compliance more difficult in some cases, and it didn't properly attribute other contributors. We shoudn't replace it with something like "Copyright (c) 2021 Bevy Contributors" because "Bevy Contributors" is not a legal entity. Instead, we just won't include the copyright line (which has precedent ... Rust also uses this approach).
* Updates crates to use the new "MIT OR Apache-2.0" license value
* Removes the old legion-transform license file from bevy_transform. bevy_transform has been its own, fully custom implementation for a long time and that license no longer applies.
* Added a License section to the main readme
* Updated our Bevy Plugin licensing guidelines.

As a follow-up we should update the website to properly describe the new license.

Closes #2373
2021-07-23 21:11:51 +00:00
bjorn3
fbf561c2bb Update minimal version requirements for dependencies (#2460)
This was tested using cargo generate-lockfile -Zminimal-versions.
The following indirect dependencies also have minimal version
dependencies. For at least num, rustc-serialize and rand this is
necessary to compile on rustc versions that are not older than 1.0.

* num = "0.1.27"
* rustc-serialize = "0.3.20"
* termcolor = "1.0.4"
* libudev-sys = "0.1.1"
* rand = "0.3.14"
* ab_glyph = "0.2.7

Based on https://github.com/bevyengine/bevy/pull/2455
2021-07-15 21:25:49 +00:00
bjorn3
ebd10681ac Remove unused deps (#2455)
# Objective

Reduce compilation time

# Solution

Remove unused dependencies. While this PR doesn't remove any crates from `Cargo.lock`, it may unlock more build parallelism.
2021-07-14 20:52:50 +00:00
Theia Vogel
85a10eccc5 Fix AssetServer::get_asset_loader deadlock (#2395)
# Objective

Fixes a possible deadlock between `AssetServer::get_asset_loader` / `AssetServer::add_loader`

A thread could take the `extension_to_loader_index` read lock,
and then have the `server.loader` write lock taken in add_loader
before it can. Then add_loader can't take the extension_to_loader_index
lock, and the program deadlocks.

To be more precise:

## Step 1: Thread 1 grabs the `extension_to_loader_index` lock on lines 138..139:

3a1867a92e/crates/bevy_asset/src/asset_server.rs (L133-L145)

## Step 2: Thread 2 grabs the `server.loader` write lock on line 107:

3a1867a92e/crates/bevy_asset/src/asset_server.rs (L103-L116)

## Step 3: Deadlock, since Thread 1 wants to grab `server.loader` on line 141...:

3a1867a92e/crates/bevy_asset/src/asset_server.rs (L133-L145)

... and Thread 2 wants to grab 'extension_to_loader_index` on lines 111..112:

3a1867a92e/crates/bevy_asset/src/asset_server.rs (L103-L116)


## Solution

Fixed by descoping the extension_to_loader_index lock, since
`get_asset_loader` doesn't need to hold the read lock on the extensions map for the duration,
just to get a copyable usize. The block might not be needed,
I think I could have gotten away with just inserting a `copied()`
call into the chain, but I wanted to make the reasoning clear for
future maintainers.
2021-07-06 17:35:16 +00:00
Nathan Ward
71bf07f5c0 [assets] Fix AssetServer::get_handle_path (#2310)
# Objective

- Currently `AssetServer::get_handle_path` always returns `None` since the inner hash map is never written to.

## Solution

- Inside the `load_untracked` function, insert the asset path into the map.

This is similar to #1290 (thanks @TheRawMeatball)
2021-06-09 20:04:22 +00:00
Nathan Ward
e549f14359 [assets] properly set LoadState with invalid asset extension (#2318)
# Objective

- Currently, when calling any of the `AssetServer`'s `load` functions, if the extension does not exist for the given path, the returned handle's load state is always `LoadState::NotLoaded`. 
- This is due to the `load_async` function early returning without properly creating a `SourceInfo` for the requested asset.
- Fixes #2261

## Solution
- Add the `SourceInfo` prior to checking for valid extension loaders. And set the `LoadState` to `Failed` if the according loader does not exist.
2021-06-08 19:39:59 +00:00
Nathan Ward
fe32a60577 [assets] set LoadState properly and more testing! (#2226)
1) Sets `LoadState` properly on all failing cases in `AssetServer::load_async`
2) Adds more tests for sad and happy paths of asset loading

_Note_: this brings in the `tempfile` crate.
2021-06-08 02:46:44 +00:00
Nathan Ward
27d809fd23 [assets] remove unnecessary temporary strong handles (#2304)
# Objective

- When creating an asset, the `update_asset_storage` function was unnecessarily creating an extraneous `Handle` to the created asset via calling `set`. This has some overhead as the `RefChange::Increment/Decrement` event was being sent.  
- A similar exteraneous handle is also created in `load_async` when loading dependencies. 

## Solution

- Have the implementation use `Assets::set_untracked` and `AssetServer::load_untracked` so no intermediate handle is created.
2021-06-07 18:32:57 +00:00
Nathan Ward
0b67084e10 [assets] fix Assets being set as 'changed' each frame (#2280)
## Objective
- Fixes: #2275 
- `Assets` were being flagged as 'changed' each frame regardless of if the assets were actually being updated. 

## Solution
- Only have `Assets` change detection be triggered when the collection is actually modified. 
- This includes utilizing `ResMut` further down the stack instead of a `&mut Assets` directly.
2021-06-02 02:30:14 +00:00
François
739224f981 fix diagnostic length for asset count (#2165)
fixes #2156 
limit the diagnostic name to `MAX_DIAGNOSTIC_NAME_WIDTH` length
2021-05-14 19:31:36 +00:00
Carter Anderson
ce6dda2d4e fix new "inconsistent struct constructor" lint (#2127)
Not super sold on the rationale behind this one, but we can revisit if it ever becomes painful.
2021-05-06 23:25:16 +00:00
François
4f0499b91f Asset re-loading while it's being deleted (#2011)
fixes #824
fixes #1956 

* marked asset loading methods as `must_use`
* fixed asset re-loading while asset is still loading to work as comment is describing code
* introduced a 1 frame delay between unused asset marking and actual asset removal
2021-05-04 20:34:22 +00:00
Nikita Zdanovitch
5390be0871 Replace derive(Default) with impl in AssetCountDiagnosticsPlugin (#2077)
Hi, ran into this problem with the derive macro.

It fails trying to derive the Default trait when the asset does not implements it also. This is unnecessary because this plugin does not need that from the asset type, just needs to create the phantom data.
2021-05-02 20:00:55 +00:00
bjorn3
3af3334cfe Various cleanups (#2046)
This includes a few safety improvements and a variety of other cleanups. See the individual commits.
2021-05-01 20:07:06 +00:00
François
c9b33e15f8 gltf: load textures asynchronously using io task pool (#1767)
While trying to reduce load time of gltf files, I noticed most of the loading time is spent transforming bytes into an actual texture.

This PR add asynchronously loading for them using io task pool in gltf loader. It reduces loading of a large glb file from 15 seconds to 6~8 on my laptop

To allow asynchronous tasks in an asset loader, I added a reference to the task pool from the asset server in the load context, which I can use later in the loader.

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2021-04-30 20:12:50 +00:00
Lucas Rocha
b1ed28e17e Hide re-exported docs (#1985)
Solves #1957 

Co-authored-by: caelumLaron <caelum.laron@gmail.com>
2021-04-27 18:29:33 +00:00
François
0a8576b710 support assets of any size (#1997)
Fixes #1892 

The following code is a cut down version of the issue, and crashes the same way:
```rust
enum AssetLifecycleEvent <T> {
    Create(T),
    Free
}

fn main() {
    let (sender, _receiver) = crossbeam_channel::unbounded();
    sender.send(AssetLifecycleEvent::<[u32; 32000]>::Free).unwrap();
}
```

- We're creating a channel that need to be able to hold `AssetLifecycleEvent::Create(T)` which has the size of our type `T`
- The two variants of the enums have a very different size

By keeping `T` boxed while sending through the channel, it doesn't crash
2021-04-24 18:14:04 +00:00
MinerSebas
458312236a Document setting "CARGO_MANIFEST_DIR" for asset root (#1950)
This was nowhere documented inside Bevy.
Should I also mention the use case of debugging a project?

Closes #810

Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com>
2021-04-19 22:16:23 +00:00
bjorn3
6a4051be3a Make some asset loading functions monomorphic (#1861)
This reduces the size of executables when using bevy as dylib by
ensuring that they get codegened in bevy_assets instead of the game
itself. This by extension avoids pulling in parts of bevy_tasks and
async_task.

Before this change the breakout example was 923k big after this change
it is only 775k big for cg_clif. For cg_llvm in release mode breakout
shrinks from 356k to 316k. For cg_llvm in debug mode breakout shrinks
from 3814k to 3057k.
2021-04-10 16:17:32 +00:00
Carter Anderson
97d8e4e179 Release 0.5.0 (#1835) 2021-04-06 18:48:48 +00:00
Jakob Hellermann
ad60046982 fix clippy lints (#1756) 2021-03-25 20:48:18 +00:00
François
86e2fc53d0 improve error message when asset type hasn't beed added to app (#1487)
Error message noticed in #1475 

When an asset type hasn't been added to the app but a load was attempted, the error message wasn't helpful:
```
thread 'IO Task Pool (0)' panicked at 'Failed to find AssetLifecycle for label Some("Mesh0/Primitive0"), which has an asset type 8ecbac0f-f545-4473-ad43-e1f4243af51e. Are you sure that is a registered asset type?', /.cargo/git/checkouts/bevy-f7ffde730c324c74/89a41bc/crates/bevy_asset/src/asset_server.rs:435:17
```
means that 
```rust
.add_asset::<bevy::render::prelude::Mesh>()
```
needs to be added.

* type name was not given, only UUID, which may make it hard to identify type across bevy/plugins
* instruction were not helpful as the `register_asset_type` method is not public

new error message:
```
thread 'IO Task Pool (1)' panicked at 'Failed to find AssetLifecycle for label 'Some("Mesh0/Primitive0")', which has an asset type "bevy_render::mesh::mesh::Mesh" (UUID 8ecbac0f-f545-4473-ad43-e1f4243af51e). Are you sure this asset type has been added to your app builder?', /bevy/crates/bevy_asset/src/asset_server.rs:435:17
```
2021-03-14 00:36:15 +00:00
Simon Guillot
aa81aaf3fa Small improvement of code quality of Assets::set* methods (#1649)
As mentioned in #1609.

I'm not sure if this is desirable, but on top of factoring the `set` and `set_untracked` methods I added a warning when the return value of `set` isn't used to mitigate similar issues.

I silenced it for the only occurence where it's currently done  68606934e3/crates/bevy_asset/src/asset_server.rs (L468)
2021-03-14 00:19:44 +00:00
Carter Anderson
b17f8a4bce format comments (#1612)
Uses the new unstable comment formatting features added to rustfmt.toml.
2021-03-11 00:27:30 +00:00
TheRawMeatball
d9b8b3e618 Add EventWriter (#1575)
This adds a `EventWriter<T>` `SystemParam` that is just a thin wrapper around `ResMut<Events<T>>`. This is primarily to have API symmetry between the reader and writer, and has the added benefit of easily improving the API later with no breaking changes.
2021-03-07 20:42:04 +00:00
Carter Anderson
3a2a68852c Bevy ECS V2 (#1525)
# Bevy ECS V2

This is a rewrite of Bevy ECS (basically everything but the new executor/schedule, which are already awesome). The overall goal was to improve the performance and versatility of Bevy ECS. Here is a quick bulleted list of changes before we dive into the details:

* Complete World rewrite
* Multiple component storage types:
    * Tables: fast cache friendly iteration, slower add/removes (previously called Archetypes)
    * Sparse Sets: fast add/remove, slower iteration
* Stateful Queries (caches query results for faster iteration. fragmented iteration is _fast_ now)
* Stateful System Params (caches expensive operations. inspired by @DJMcNab's work in #1364)
* Configurable System Params (users can set configuration when they construct their systems. once again inspired by @DJMcNab's work)
* Archetypes are now "just metadata", component storage is separate
* Archetype Graph (for faster archetype changes)
* Component Metadata
    * Configure component storage type
    * Retrieve information about component size/type/name/layout/send-ness/etc
    * Components are uniquely identified by a densely packed ComponentId
    * TypeIds are now totally optional (which should make implementing scripting easier)
* Super fast "for_each" query iterators
* Merged Resources into World. Resources are now just a special type of component
* EntityRef/EntityMut builder apis (more efficient and more ergonomic)
* Fast bitset-backed `Access<T>` replaces old hashmap-based approach everywhere
* Query conflicts are determined by component access instead of archetype component access (to avoid random failures at runtime)
    * With/Without are still taken into account for conflicts, so this should still be comfy to use
* Much simpler `IntoSystem` impl
* Significantly reduced the amount of hashing throughout the ecs in favor of Sparse Sets (indexed by densely packed ArchetypeId, ComponentId, BundleId, and TableId)
* Safety Improvements
    * Entity reservation uses a normal world reference instead of unsafe transmute
    * QuerySets no longer transmute lifetimes
    * Made traits "unsafe" where relevant
    * More thorough safety docs
* WorldCell
    * Exposes safe mutable access to multiple resources at a time in a World 
* Replaced "catch all" `System::update_archetypes(world: &World)` with `System::new_archetype(archetype: &Archetype)`
* Simpler Bundle implementation
* Replaced slow "remove_bundle_one_by_one" used as fallback for Commands::remove_bundle with fast "remove_bundle_intersection"
* Removed `Mut<T>` query impl. it is better to only support one way: `&mut T` 
* Removed with() from `Flags<T>` in favor of `Option<Flags<T>>`, which allows querying for flags to be "filtered" by default 
* Components now have is_send property (currently only resources support non-send)
* More granular module organization
* New `RemovedComponents<T>` SystemParam that replaces `query.removed::<T>()`
* `world.resource_scope()` for mutable access to resources and world at the same time
* WorldQuery and QueryFilter traits unified. FilterFetch trait added to enable "short circuit" filtering. Auto impled for cases that don't need it
* Significantly slimmed down SystemState in favor of individual SystemParam state
* System Commands changed from `commands: &mut Commands` back to `mut commands: Commands` (to allow Commands to have a World reference)

Fixes #1320

## `World` Rewrite

This is a from-scratch rewrite of `World` that fills the niche that `hecs` used to. Yes, this means Bevy ECS is no longer a "fork" of hecs. We're going out our own!

(the only shared code between the projects is the entity id allocator, which is already basically ideal)

A huge shout out to @SanderMertens (author of [flecs](https://github.com/SanderMertens/flecs)) for sharing some great ideas with me (specifically hybrid ecs storage and archetype graphs). He also helped advise on a number of implementation details.

## Component Storage (The Problem)

Two ECS storage paradigms have gained a lot of traction over the years:

* **Archetypal ECS**: 
    * Stores components in "tables" with static schemas. Each "column" stores components of a given type. Each "row" is an entity.
    * Each "archetype" has its own table. Adding/removing an entity's component changes the archetype.
    * Enables super-fast Query iteration due to its cache-friendly data layout
    * Comes at the cost of more expensive add/remove operations for an Entity's components, because all components need to be copied to the new archetype's "table"
* **Sparse Set ECS**:
    * Stores components of the same type in densely packed arrays, which are sparsely indexed by densely packed unsigned integers (Entity ids)
    * Query iteration is slower than Archetypal ECS because each entity's component could be at any position in the sparse set. This "random access" pattern isn't cache friendly. Additionally, there is an extra layer of indirection because you must first map the entity id to an index in the component array.
    * Adding/removing components is a cheap, constant time operation 

Bevy ECS V1, hecs, legion, flec, and Unity DOTS are all "archetypal ecs-es". I personally think "archetypal" storage is a good default for game engines. An entity's archetype doesn't need to change frequently in general, and it creates "fast by default" query iteration (which is a much more common operation). It is also "self optimizing". Users don't need to think about optimizing component layouts for iteration performance. It "just works" without any extra boilerplate.

Shipyard and EnTT are "sparse set ecs-es". They employ "packing" as a way to work around the "suboptimal by default" iteration performance for specific sets of components. This helps, but I didn't think this was a good choice for a general purpose engine like Bevy because:

1. "packs" conflict with each other. If bevy decides to internally pack the Transform and GlobalTransform components, users are then blocked if they want to pack some custom component with Transform.
2. users need to take manual action to optimize

Developers selecting an ECS framework are stuck with a hard choice. Select an "archetypal" framework with "fast iteration everywhere" but without the ability to cheaply add/remove components, or select a "sparse set" framework to cheaply add/remove components but with slower iteration performance.

## Hybrid Component Storage (The Solution)

In Bevy ECS V2, we get to have our cake and eat it too. It now has _both_ of the component storage types above (and more can be added later if needed):

* **Tables** (aka "archetypal" storage)
    * The default storage. If you don't configure anything, this is what you get
    * Fast iteration by default
    * Slower add/remove operations
* **Sparse Sets**
    * Opt-in
    * Slower iteration
    * Faster add/remove operations

These storage types complement each other perfectly. By default Query iteration is fast. If developers know that they want to add/remove a component at high frequencies, they can set the storage to "sparse set":

```rust
world.register_component(
    ComponentDescriptor:🆕:<MyComponent>(StorageType::SparseSet)
).unwrap();
```

## Archetypes

Archetypes are now "just metadata" ... they no longer store components directly. They do store:

* The `ComponentId`s of each of the Archetype's components (and that component's storage type)
    * Archetypes are uniquely defined by their component layouts
    * For example: entities with "table" components `[A, B, C]` _and_ "sparse set" components `[D, E]` will always be in the same archetype.
* The `TableId` associated with the archetype
    * For now each archetype has exactly one table (which can have no components),
    * There is a 1->Many relationship from Tables->Archetypes. A given table could have any number of archetype components stored in it:
        * Ex: an entity with "table storage" components `[A, B, C]` and "sparse set" components `[D, E]` will share the same `[A, B, C]` table as an entity with `[A, B, C]` table component and `[F]` sparse set components.
        * This 1->Many relationship is how we preserve fast "cache friendly" iteration performance when possible (more on this later)
* A list of entities that are in the archetype and the row id of the table they are in
* ArchetypeComponentIds
    * unique densely packed identifiers for (ArchetypeId, ComponentId) pairs
    * used by the schedule executor for cheap system access control
* "Archetype Graph Edges" (see the next section)  

## The "Archetype Graph"

Archetype changes in Bevy (and a number of other archetypal ecs-es) have historically been expensive to compute. First, you need to allocate a new vector of the entity's current component ids, add or remove components based on the operation performed, sort it (to ensure it is order-independent), then hash it to find the archetype (if it exists). And thats all before we get to the _already_ expensive full copy of all components to the new table storage.

The solution is to build a "graph" of archetypes to cache these results. @SanderMertens first exposed me to the idea (and he got it from @gjroelofs, who came up with it). They propose adding directed edges between archetypes for add/remove component operations. If `ComponentId`s are densely packed, you can use sparse sets to cheaply jump between archetypes.

Bevy takes this one step further by using add/remove `Bundle` edges instead of `Component` edges. Bevy encourages the use of `Bundles` to group add/remove operations. This is largely for "clearer game logic" reasons, but it also helps cut down on the number of archetype changes required. `Bundles` now also have densely-packed `BundleId`s. This allows us to use a _single_ edge for each bundle operation (rather than needing to traverse N edges ... one for each component). Single component operations are also bundles, so this is strictly an improvement over a "component only" graph.

As a result, an operation that used to be _heavy_ (both for allocations and compute) is now two dirt-cheap array lookups and zero allocations.

## Stateful Queries

World queries are now stateful. This allows us to:

1. Cache archetype (and table) matches
    * This resolves another issue with (naive) archetypal ECS: query performance getting worse as the number of archetypes goes up (and fragmentation occurs).
2. Cache Fetch and Filter state
    * The expensive parts of fetch/filter operations (such as hashing the TypeId to find the ComponentId) now only happen once when the Query is first constructed
3. Incrementally build up state
    * When new archetypes are added, we only process the new archetypes (no need to rebuild state for old archetypes)

As a result, the direct `World` query api now looks like this:

```rust
let mut query = world.query::<(&A, &mut B)>();
for (a, mut b) in query.iter_mut(&mut world) {
}
```

Requiring `World` to generate stateful queries (rather than letting the `QueryState` type be constructed separately) allows us to ensure that _all_ queries are properly initialized (and the relevant world state, such as ComponentIds). This enables QueryState to remove branches from its operations that check for initialization status (and also enables query.iter() to take an immutable world reference because it doesn't need to initialize anything in world).

However in systems, this is a non-breaking change. State management is done internally by the relevant SystemParam.

## Stateful SystemParams

Like Queries, `SystemParams` now also cache state. For example, `Query` system params store the "stateful query" state mentioned above. Commands store their internal `CommandQueue`. This means you can now safely use as many separate `Commands` parameters in your system as you want. `Local<T>` system params store their `T` value in their state (instead of in Resources). 

SystemParam state also enabled a significant slim-down of SystemState. It is much nicer to look at now.

Per-SystemParam state naturally insulates us from an "aliased mut" class of errors we have hit in the past (ex: using multiple `Commands` system params).

(credit goes to @DJMcNab for the initial idea and draft pr here #1364)

## Configurable SystemParams

@DJMcNab also had the great idea to make SystemParams configurable. This allows users to provide some initial configuration / values for system parameters (when possible). Most SystemParams have no config (the config type is `()`), but the `Local<T>` param now supports user-provided parameters:

```rust

fn foo(value: Local<usize>) {    
}

app.add_system(foo.system().config(|c| c.0 = Some(10)));
```

## Uber Fast "for_each" Query Iterators

Developers now have the choice to use a fast "for_each" iterator, which yields ~1.5-3x iteration speed improvements for "fragmented iteration", and minor ~1.2x iteration speed improvements for unfragmented iteration. 

```rust
fn system(query: Query<(&A, &mut B)>) {
    // you now have the option to do this for a speed boost
    query.for_each_mut(|(a, mut b)| {
    });

    // however normal iterators are still available
    for (a, mut b) in query.iter_mut() {
    }
}
```

I think in most cases we should continue to encourage "normal" iterators as they are more flexible and more "rust idiomatic". But when that extra "oomf" is needed, it makes sense to use `for_each`.

We should also consider using `for_each` for internal bevy systems to give our users a nice speed boost (but that should be a separate pr).

## Component Metadata

`World` now has a `Components` collection, which is accessible via `world.components()`. This stores mappings from `ComponentId` to `ComponentInfo`, as well as `TypeId` to `ComponentId` mappings (where relevant). `ComponentInfo` stores information about the component, such as ComponentId, TypeId, memory layout, send-ness (currently limited to resources), and storage type.

## Significantly Cheaper `Access<T>`

We used to use `TypeAccess<TypeId>` to manage read/write component/archetype-component access. This was expensive because TypeIds must be hashed and compared individually. The parallel executor got around this by "condensing" type ids into bitset-backed access types. This worked, but it had to be re-generated from the `TypeAccess<TypeId>`sources every time archetypes changed.

This pr removes TypeAccess in favor of faster bitset access everywhere. We can do this thanks to the move to densely packed `ComponentId`s and `ArchetypeComponentId`s.

## Merged Resources into World

Resources had a lot of redundant functionality with Components. They stored typed data, they had access control, they had unique ids, they were queryable via SystemParams, etc. In fact the _only_ major difference between them was that they were unique (and didn't correlate to an entity).

Separate resources also had the downside of requiring a separate set of access controls, which meant the parallel executor needed to compare more bitsets per system and manage more state.

I initially got the "separate resources" idea from `legion`. I think that design was motivated by the fact that it made the direct world query/resource lifetime interactions more manageable. It certainly made our lives easier when using Resources alongside hecs/bevy_ecs. However we already have a construct for safely and ergonomically managing in-world lifetimes: systems (which use `Access<T>` internally).

This pr merges Resources into World:

```rust
world.insert_resource(1);
world.insert_resource(2.0);
let a = world.get_resource::<i32>().unwrap();
let mut b = world.get_resource_mut::<f64>().unwrap();
*b = 3.0;
```

Resources are now just a special kind of component. They have their own ComponentIds (and their own resource TypeId->ComponentId scope, so they don't conflict wit components of the same type). They are stored in a special "resource archetype", which stores components inside the archetype using a new `unique_components` sparse set (note that this sparse set could later be used to implement Tags). This allows us to keep the code size small by reusing existing datastructures (namely Column, Archetype, ComponentFlags, and ComponentInfo). This allows us the executor to use a single `Access<ArchetypeComponentId>` per system. It should also make scripting language integration easier.

_But_ this merge did create problems for people directly interacting with `World`. What if you need mutable access to multiple resources at the same time? `world.get_resource_mut()` borrows World mutably!

## WorldCell

WorldCell applies the `Access<ArchetypeComponentId>` concept to direct world access:

```rust
let world_cell = world.cell();
let a = world_cell.get_resource_mut::<i32>().unwrap();
let b = world_cell.get_resource_mut::<f64>().unwrap();
```

This adds cheap runtime checks (a sparse set lookup of `ArchetypeComponentId` and a counter) to ensure that world accesses do not conflict with each other. Each operation returns a `WorldBorrow<'w, T>` or `WorldBorrowMut<'w, T>` wrapper type, which will release the relevant ArchetypeComponentId resources when dropped.

World caches the access sparse set (and only one cell can exist at a time), so `world.cell()` is a cheap operation. 

WorldCell does _not_ use atomic operations. It is non-send, does a mutable borrow of world to prevent other accesses, and uses a simple `Rc<RefCell<ArchetypeComponentAccess>>` wrapper in each WorldBorrow pointer. 

The api is currently limited to resource access, but it can and should be extended to queries / entity component access.

## Resource Scopes

WorldCell does not yet support component queries, and even when it does there are sometimes legitimate reasons to want a mutable world ref _and_ a mutable resource ref (ex: bevy_render and bevy_scene both need this). In these cases we could always drop down to the unsafe `world.get_resource_unchecked_mut()`, but that is not ideal!

Instead developers can use a "resource scope"

```rust
world.resource_scope(|world: &mut World, a: &mut A| {
})
```

This temporarily removes the `A` resource from `World`, provides mutable pointers to both, and re-adds A to World when finished. Thanks to the move to ComponentIds/sparse sets, this is a cheap operation.

If multiple resources are required, scopes can be nested. We could also consider adding a "resource tuple" to the api if this pattern becomes common and the boilerplate gets nasty.

## Query Conflicts Use ComponentId Instead of ArchetypeComponentId

For safety reasons, systems cannot contain queries that conflict with each other without wrapping them in a QuerySet. On bevy `main`, we use ArchetypeComponentIds to determine conflicts. This is nice because it can take into account filters:

```rust
// these queries will never conflict due to their filters
fn filter_system(a: Query<&mut A, With<B>>, b: Query<&mut B, Without<B>>) {
}
```

But it also has a significant downside:
```rust
// these queries will not conflict _until_ an entity with A, B, and C is spawned
fn maybe_conflicts_system(a: Query<(&mut A, &C)>, b: Query<(&mut A, &B)>) {
}
```

The system above will panic at runtime if an entity with A, B, and C is spawned. This makes it hard to trust that your game logic will run without crashing.

In this pr, I switched to using `ComponentId` instead. This _is_ more constraining. `maybe_conflicts_system` will now always fail, but it will do it consistently at startup. Naively, it would also _disallow_ `filter_system`, which would be a significant downgrade in usability. Bevy has a number of internal systems that rely on disjoint queries and I expect it to be a common pattern in userspace.

To resolve this, I added a new `FilteredAccess<T>` type, which wraps `Access<T>` and adds with/without filters. If two `FilteredAccess` have with/without values that prove they are disjoint, they will no longer conflict.

## EntityRef / EntityMut

World entity operations on `main` require that the user passes in an `entity` id to each operation:

```rust
let entity = world.spawn((A, )); // create a new entity with A
world.get::<A>(entity);
world.insert(entity, (B, C));
world.insert_one(entity, D);
```

This means that each operation needs to look up the entity location / verify its validity. The initial spawn operation also requires a Bundle as input. This can be awkward when no components are required (or one component is required).

These operations have been replaced by `EntityRef` and `EntityMut`, which are "builder-style" wrappers around world that provide read and read/write operations on a single, pre-validated entity:

```rust
// spawn now takes no inputs and returns an EntityMut
let entity = world.spawn()
    .insert(A) // insert a single component into the entity
    .insert_bundle((B, C)) // insert a bundle of components into the entity
    .id() // id returns the Entity id

// Returns EntityMut (or panics if the entity does not exist)
world.entity_mut(entity)
    .insert(D)
    .insert_bundle(SomeBundle::default());
{
    // returns EntityRef (or panics if the entity does not exist)
    let d = world.entity(entity)
        .get::<D>() // gets the D component
        .unwrap();
    // world.get still exists for ergonomics
    let d = world.get::<D>(entity).unwrap();
}

// These variants return Options if you want to check existence instead of panicing 
world.get_entity_mut(entity)
    .unwrap()
    .insert(E);

if let Some(entity_ref) = world.get_entity(entity) {
    let d = entity_ref.get::<D>().unwrap();
}
```

This _does not_ affect the current Commands api or terminology. I think that should be a separate conversation as that is a much larger breaking change.

## Safety Improvements

* Entity reservation in Commands uses a normal world borrow instead of an unsafe transmute
* QuerySets no longer transmutes lifetimes
* Made traits "unsafe" when implementing a trait incorrectly could cause unsafety
* More thorough safety docs

## RemovedComponents SystemParam

The old approach to querying removed components: `query.removed:<T>()` was confusing because it had no connection to the query itself. I replaced it with the following, which is both clearer and allows us to cache the ComponentId mapping in the SystemParamState:

```rust
fn system(removed: RemovedComponents<T>) {
    for entity in removed.iter() {
    }
} 
```

## Simpler Bundle implementation

Bundles are no longer responsible for sorting (or deduping) TypeInfo. They are just a simple ordered list of component types / data. This makes the implementation smaller and opens the door to an easy "nested bundle" implementation in the future (which i might even add in this pr). Duplicate detection is now done once per bundle type by World the first time a bundle is used.

## Unified WorldQuery and QueryFilter types

(don't worry they are still separate type _parameters_ in Queries .. this is a non-breaking change)

WorldQuery and QueryFilter were already basically identical apis. With the addition of `FetchState` and more storage-specific fetch methods, the overlap was even clearer (and the redundancy more painful).

QueryFilters are now just `F: WorldQuery where F::Fetch: FilterFetch`. FilterFetch requires `Fetch<Item = bool>` and adds new "short circuit" variants of fetch methods. This enables a filter tuple like `(With<A>, Without<B>, Changed<C>)` to stop evaluating the filter after the first mismatch is encountered. FilterFetch is automatically implemented for `Fetch` implementations that return bool.

This forces fetch implementations that return things like `(bool, bool, bool)` (such as the filter above) to manually implement FilterFetch and decide whether or not to short-circuit.

## More Granular Modules

World no longer globs all of the internal modules together. It now exports `core`, `system`, and `schedule` separately. I'm also considering exporting `core` submodules directly as that is still pretty "glob-ey" and unorganized (feedback welcome here).

## Remaining Draft Work (to be done in this pr)

* ~~panic on conflicting WorldQuery fetches (&A, &mut A)~~
    * ~~bevy `main` and hecs both currently allow this, but we should protect against it if possible~~
* ~~batch_iter / par_iter (currently stubbed out)~~
* ~~ChangedRes~~
    * ~~I skipped this while we sort out #1313. This pr should be adapted to account for whatever we land on there~~.
* ~~The `Archetypes` and `Tables` collections use hashes of sorted lists of component ids to uniquely identify each archetype/table. This hash is then used as the key in a HashMap to look up the relevant ArchetypeId or TableId. (which doesn't handle hash collisions properly)~~
* ~~It is currently unsafe to generate a Query from "World A", then use it on "World B" (despite the api claiming it is safe). We should probably close this gap. This could be done by adding a randomly generated WorldId to each world, then storing that id in each Query. They could then be compared to each other on each `query.do_thing(&world)` operation. This _does_ add an extra branch to each query operation, so I'm open to other suggestions if people have them.~~
* ~~Nested Bundles (if i find time)~~

## Potential Future Work

* Expand WorldCell to support queries.
* Consider not allocating in the empty archetype on `world.spawn()`
    * ex: return something like EntityMutUninit, which turns into EntityMut after an `insert` or `insert_bundle` op
    * this actually regressed performance last time i tried it, but in theory it should be faster
* Optimize SparseSet::insert (see `PERF` comment on insert)
* Replace SparseArray `Option<T>` with T::MAX to cut down on branching
    * would enable cheaper get_unchecked() operations
* upstream fixedbitset optimizations
    * fixedbitset could be allocation free for small block counts (store blocks in a SmallVec)
    * fixedbitset could have a const constructor 
* Consider implementing Tags (archetype-specific by-value data that affects archetype identity) 
    * ex: ArchetypeA could have `[A, B, C]` table components and `[D(1)]` "tag" component. ArchetypeB could have `[A, B, C]` table components and a `[D(2)]` tag component. The archetypes are different, despite both having D tags because the value inside D is different.
    * this could potentially build on top of the `archetype.unique_components` added in this pr for resource storage.
* Consider reverting `all_tuples` proc macro in favor of the old `macro_rules` implementation
    * all_tuples is more flexible and produces cleaner documentation (the macro_rules version produces weird type parameter orders due to parser constraints)
    * but unfortunately all_tuples also appears to make Rust Analyzer sad/slow when working inside of `bevy_ecs` (does not affect user code)
* Consider "resource queries" and/or "mixed resource and entity component queries" as an alternative to WorldCell
    * this is basically just "systems" so maybe it's not worth it
* Add more world ops
    * `world.clear()`
    * `world.reserve<T: Bundle>(count: usize)`
 * Try using the old archetype allocation strategy (allocate new memory on resize and copy everything over). I expect this to improve batch insertion performance at the cost of unbatched performance. But thats just a guess. I'm not an allocation perf pro :)
 * Adapt Commands apis for consistency with new World apis 

## Benchmarks

key:

* `bevy_old`: bevy `main` branch
* `bevy`: this branch
* `_foreach`: uses an optimized for_each iterator
* ` _sparse`: uses sparse set storage (if unspecified assume table storage)
* `_system`: runs inside a system (if unspecified assume test happens via direct world ops)

### Simple Insert (from ecs_bench_suite)

![image](https://user-images.githubusercontent.com/2694663/109245573-9c3ce100-7795-11eb-9003-bfd41cd5c51f.png)

### Simpler Iter (from ecs_bench_suite)

![image](https://user-images.githubusercontent.com/2694663/109245795-ffc70e80-7795-11eb-92fb-3ffad09aabf7.png)

### Fragment Iter (from ecs_bench_suite)

![image](https://user-images.githubusercontent.com/2694663/109245849-0fdeee00-7796-11eb-8d25-eb6b7a682c48.png)

### Sparse Fragmented Iter

Iterate a query that matches 5 entities from a single matching archetype, but there are 100 unmatching archetypes

![image](https://user-images.githubusercontent.com/2694663/109245916-2b49f900-7796-11eb-9a8f-ed89c203f940.png)
 
### Schedule (from ecs_bench_suite)

![image](https://user-images.githubusercontent.com/2694663/109246428-1fab0200-7797-11eb-8841-1b2161e90fa4.png)

### Add Remove Component (from ecs_bench_suite)

![image](https://user-images.githubusercontent.com/2694663/109246492-39e4e000-7797-11eb-8985-2706bd0495ab.png)


### Add Remove Component Big

Same as the test above, but each entity has 5 "large" matrix components and 1 "large" matrix component is added and removed

![image](https://user-images.githubusercontent.com/2694663/109246517-449f7500-7797-11eb-835e-28b6790daeaa.png)


### Get Component

Looks up a single component value a large number of times

![image](https://user-images.githubusercontent.com/2694663/109246129-87ad1880-7796-11eb-9fcb-c38012aa7c70.png)
2021-03-05 07:54:35 +00:00
Daniel McNab
e61d7920e3 Add suffixes to diagnostics and other cleanup (#1505)
Also a few related clean ups to diagnostics
Old look (from the log_diagnostics_example):
<details>
<summary>Old look hidden to avoid clutter </summary>

![image](https://user-images.githubusercontent.com/36049421/108776774-bc349080-755a-11eb-8569-d4832abf6bc3.png)

</details>
New look: 

![image](https://user-images.githubusercontent.com/36049421/108776587-82638a00-755a-11eb-96eb-539026d59bcb.png)

In particular, notice that the width of the diagnostics has been significantly reduced - within vscode the value no longer wraps on my 1920 width monitor. The value is still 105 columns wide, so there is room for improvement however.
2021-03-03 03:43:15 +00:00
Archina
b8a0ab01ba add to lower case to make asset loading case insensitive (#1427)
This should fix bug #1425
2021-03-03 03:11:10 +00:00
Alexander Sepity
c2a427f1a3
Non-string labels (#1423 continued) (#1473)
Non-string labels
2021-02-18 13:20:37 -08:00
dependabot[bot]
05b8b5c8c2
Update crossbeam-channel requirement from 0.4.4 to 0.5.0 (#668)
Updates the requirements on [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) to permit the latest version.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.4.4...crossbeam-channel-0.5.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-02-01 13:30:38 -08:00
François
83e30a841a
bind the labeled asset type to the actual loaded asset (#1363)
bind the labeled asset type to the actual loaded asset
2021-01-31 13:54:15 -08:00
Alice Cecile
6f5a4d9deb
Rename add_resource to insert_resource (#1356)
* Renamed add_resource to insert_resource

* Changed usage of add_resource to insert_resource

* Renamed add_thread_local_resource
2021-01-30 12:55:13 -08:00
Zicklag
af67231567
Fix Bug in Asset Server Error Message Formatter (#1340) 2021-01-29 13:26:21 -08:00
Zicklag
b6485ccf29
Process Asset File Extensions With Multiple Dots (#1277)
Process Asset File Extensions With Multiple Dots
Fixes #1276
2021-01-25 12:37:23 -08:00
Will Crichton
3d0c4e380c
Don't panic on error when loading assets (#1286)
* Don't panic on IO errors
* Better formatting for asset server errors
2021-01-23 13:23:16 -08:00
Christopher Durham
4d5ba7918b
Update rand requirement from 0.7 to 0.8 (#1114)
* Update rand requirement from 0.7 to 0.8

* Update examples' usage of Rng::gen_range
2021-01-17 13:43:03 -08:00
François
21794fe6df
make more information available from loaded GLTF model (#1020)
make more information available from loaded GLTF model 
* make gltf nodes available as assets
* add list of primitive per mesh, and their associated material
* complete gltf structure
* get names of gltf assets
* only load materials once
* add labels with node names
2020-12-31 14:57:15 -06:00
François
b28365f966
updates on diagnostics (log + new diagnostics) (#1085)
* move print diagnostics to log

* entity count diagnostic

* asset count diagnostic

* remove useless `pub`s

* use `BTreeMap` instead of `HashMap`

* get entity count from world

* keep ordered list of diagnostics
2020-12-24 13:28:31 -06:00
Carter Anderson
3b2c6ce49b
release 0.4.0 (#1093) 2020-12-19 13:28:00 -06:00