# Objective
- Provide a generic and _reflectable_ way to iterate over contained
entities
## Solution
Adds two new traits:
* `VisitEntities`: Reflectable iteration, accepts a closure rather than
producing an iterator. Implemented by default for `IntoIterator`
implementing types. A proc macro is also provided.
* A `Mut` variant of the above. Its derive macro uses the same field
attribute to avoid repetition.
## Testing
Added a test for `VisitEntities` that also transitively tests its derive
macro as well as the default `MapEntities` impl.
# Objective
Fixes#15394
## Solution
Observers now validate params.
System registry has a new error variant for when system running fails
due to invalid parameters.
Run once now returns a `Result<Out, RunOnceError>` instead of `Out`.
This is more inline with system registry, which also returns a result.
I'll address warning messages in #15500.
## Testing
Added one test for each case.
---
## Migration Guide
- `RunSystemOnce::run_system_once` and
`RunSystemOnce::run_system_once_with` now return a `Result<Out>` instead
of just `Out`
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Zachary Harrold <zac@harrold.com.au>
# Objective
- Fixes#6370
- Closes#6581
## Solution
- Added the following lints to the workspace:
- `std_instead_of_core`
- `std_instead_of_alloc`
- `alloc_instead_of_core`
- Used `cargo +nightly fmt` with [item level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Item%5C%3A)
to split all `use` statements into single items.
- Used `cargo clippy --workspace --all-targets --all-features --fix
--allow-dirty` to _attempt_ to resolve the new linting issues, and
intervened where the lint was unable to resolve the issue automatically
(usually due to needing an `extern crate alloc;` statement in a crate
root).
- Manually removed certain uses of `std` where negative feature gating
prevented `--all-features` from finding the offending uses.
- Used `cargo +nightly fmt` with [crate level use
formatting](https://rust-lang.github.io/rustfmt/?version=v1.6.0&search=#Crate%5C%3A)
to re-merge all `use` statements matching Bevy's previous styling.
- Manually fixed cases where the `fmt` tool could not re-merge `use`
statements due to conditional compilation attributes.
## Testing
- Ran CI locally
## Migration Guide
The MSRV is now 1.81. Please update to this version or higher.
## Notes
- This is a _massive_ change to try and push through, which is why I've
outlined the semi-automatic steps I used to create this PR, in case this
fails and someone else tries again in the future.
- Making this change has no impact on user code, but does mean Bevy
contributors will be warned to use `core` and `alloc` instead of `std`
where possible.
- This lint is a critical first step towards investigating `no_std`
options for Bevy.
---------
Co-authored-by: François Mockers <francois.mockers@vleue.com>
# Objective
- Add a test case for #14300Fixes#14300
## Solution
`SceneEntityMapper` relies on operations on `Entities` that require
flushing in advance, such as `alloc` and `free`. Previously, it wasn't
calling `world.flush_entities()` itself and relied on its caller having
flushed beforehand. This wasn't an issue before observers and hooks were
released, since entity reservation was happening at expected times. Now
that hooks and observers are a thing, they can introduce a need to
flush.
We have a few options:
* Flush after each observer/hook run
* Flush between each paired observer/hook and operation that requires a
flush
* Flush before operations requiring it
The first option for this case seemed trickier to reason about than I
wanted, since it involved the `BundleInserter` and its
`UnsafeWorldCell`, and the second is generally harder to track down. The
third seemed the most straightforward and conventional, since we can see
a flush occurring at the start of a number of `World` methods.
Therefore, we're letting `SceneEntityMapper` be in charge of upholding
its own invariants and calling `flush_entities` when it's created.
## Testing
Added a new test case modeled after #14300
# Objective
- Makes naming between add_child and add_children more consistent
- Fixes#15101
## Solution
renamed push_children to add_children
## Testing
- Did you test these changes? If so, how?
Ran tests + grep search for any instance of `push_child`
- Are there any parts that need more testing?
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
ran tests on WSL2
---
## Migration Guide
> This section is optional. If there are no breaking changes, you can
delete this section.
- If this PR is a breaking change (relative to the last release of
Bevy), describe how a user might need to migrate their code to support
these changes
rename any use of `push_children()` to the updated `add_children()`
# Objective
It would be convenient to be able to quickly deny or allow all
components and resources on a `DynamicSceneBuilder` with a single method
call.
Context: #15210 renamed `{allow/deny}_all` to
`{allow/deny}_all_components`.
## Solution
Added two new methods to `DynamicSceneBuilder`, `allow_all` and
`deny_all`, which affect both the component and resource filters.
## Showcase
### Before
```rust
let builder = DynamicSceneBuilder::from_world(world)
.deny_all_components()
.deny_all_resources();
```
### After
```rust
let builder = DynamicSceneBuilder::from_world(world).deny_all();
```
# Objective
The method names on `DynamicSceneBuilder` are misleading. Specifically,
`deny_all` and `allow_all` implies everything will be denied/allowed,
including all components and resources. In reality, these methods only
apply to components (which is mentioned in the docs).
## Solution
- change `deny_all` and `allow_all` to `deny_all_components` and
`allow_all_components`
- also, change the remaining methods to mention component where it makes
sense
We could also add the `deny_all` and `allow_all` methods back later,
only this time, they would deny/allow both resources and components.
## Showcase
### Before
```rust
let builder = DynamicSceneBuilder::from_world(world)
.deny_all()
.deny_all_resources()
.allow::<MyComponent>();
```
### After
```rust
let builder = DynamicSceneBuilder::from_world(world)
.deny_all_components()
.deny_all_resources()
.allow_component::<MyComponent>();
```
## Migration Guide
the following invocations on `DynamicSceneBuilder` should be changed by
users
- `with_filter` -> `with_component_filter`
- `allow` -> `allow_component`
- `deny` -> `deny_component`
- `allow_all` -> `allow_all_components`
- `deny_all` -> `deny_all_components`
# Objective
Fix#10284.
## Solution
When `DynamicSceneBuilder` extracts entities, they are cloned via
`PartialReflect::clone_value`, making them into dynamic versions of the
original components. This loses any custom `ReflectSerialize` type data.
Dynamic scenes are deserialized with the original types, not the dynamic
versions, and so any component with a custom serialize may fail. In this
case `Rect` and `Vec2`. The dynamic version includes the field names 'x'
and 'y' but the `Serialize` impl doesn't, hence the "expect float"
error.
The solution here: Instead of using `clone_value` to clone the
components, `FromReflect` clones and retains the original information
needed to serialize with any custom `Serialize` impls. I think using
something like `reflect_clone` from
(https://github.com/bevyengine/bevy/pull/13432) might make this more
efficient.
I also did the same when deserializing dynamic scenes to appease some of
the round-trip tests which use `ReflectPartialEq`, which requires the
types be the same and not a unique/proxy pair. I'm not sure it's
otherwise necessary. Maybe this would also be more efficient when
spawning dynamic scenes with `reflect_clone` instead of `FromReflect`
again?
An alternative solution would be to fall back to the dynamic version
when deserializing `DynamicScene`s if the custom version fails. I think
that's possible. Or maybe simply always deserializing via the dynamic
route for dynamic scenes?
## Testing
This example is similar to the original test case in #10284:
``` rust
#![allow(missing_docs)]
use bevy::{prelude::*, scene::SceneInstanceReady};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, (save, load).chain())
.observe(check)
.run();
}
static SAVEGAME_SAVE_PATH: &str = "savegame.scn.ron";
fn save(world: &mut World) {
let entity = world.spawn(OrthographicProjection::default()).id();
let scene = DynamicSceneBuilder::from_world(world)
.extract_entity(entity)
.build();
if let Some(registry) = world.get_resource::<AppTypeRegistry>() {
let registry = registry.read();
let serialized_scene = scene.serialize(®istry).unwrap();
// println!("{}", serialized_scene);
std::fs::write(format!("assets/{SAVEGAME_SAVE_PATH}"), serialized_scene).unwrap();
}
world.entity_mut(entity).despawn_recursive();
}
fn load(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn(DynamicSceneBundle {
scene: asset_server.load(SAVEGAME_SAVE_PATH),
..default()
});
}
fn check(_trigger: Trigger<SceneInstanceReady>, query: Query<&OrthographicProjection>) {
dbg!(query.single());
}
```
## Migration Guide
The `DynamicScene` format is changed to use custom serialize impls so
old scene files will need updating:
Old:
```ron
(
resources: {},
entities: {
4294967299: (
components: {
"bevy_render:📷:projection::OrthographicProjection": (
near: 0.0,
far: 1000.0,
viewport_origin: (
x: 0.5,
y: 0.5,
),
scaling_mode: WindowSize(1.0),
scale: 1.0,
area: (
min: (
x: -1.0,
y: -1.0,
),
max: (
x: 1.0,
y: 1.0,
),
),
),
},
),
},
)
```
New:
```ron
(
resources: {},
entities: {
4294967299: (
components: {
"bevy_render:📷:projection::OrthographicProjection": (
near: 0.0,
far: 1000.0,
viewport_origin: (0.5, 0.5),
scaling_mode: WindowSize(1.0),
scale: 1.0,
area: (
min: (-1.0, -1.0),
max: (1.0, 1.0),
),
),
},
),
},
)
```
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
Fixes: https://github.com/bevyengine/bevy/issues/14515
## Solution
Sorts the iterator with itertools' sorted_by function. This is required
given that 'self.entries' is an immutable &[Box<dyn PartialReflect]
which also doesn't implement Clone or Copy.
## Testing
The modifications passed the unit testing only after they were edited to
ensure that the items were in alphabetical order.
I haven't checked for performance implications.
# Objective
- Crate-level prelude modules, such as `bevy_ecs::prelude`, are plagued
with inconsistency! Let's fix it!
## Solution
Format all preludes based on the following rules:
1. All preludes should have brief documentation in the format of:
> The _name_ prelude.
>
> This includes the most common types in this crate, re-exported for
your convenience.
2. All documentation should be outer, not inner. (`///` instead of
`//!`.)
3. No prelude modules should be annotated with `#[doc(hidden)]`. (Items
within them may, though I'm not sure why this was done.)
## Testing
- I manually searched for the term `mod prelude` and updated all
occurrences by hand. 🫠
---------
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
- Implements the [Unique Reflect
RFC](https://github.com/nicopap/rfcs/blob/bevy-reflect-api/rfcs/56-better-reflect.md).
## Solution
- Implements the RFC.
- This implementation differs in some ways from the RFC:
- In the RFC, it was suggested `Reflect: Any` but `PartialReflect:
?Any`. During initial implementation I tried this, but we assume the
`PartialReflect: 'static` in a lot of places and the changes required
crept out of the scope of this PR.
- `PartialReflect::try_into_reflect` originally returned `Option<Box<dyn
Reflect>>` but i changed this to `Result<Box<dyn Reflect>, Box<dyn
PartialReflect>>` since the method takes by value and otherwise there
would be no way to recover the type. `as_full` and `as_full_mut` both
still return `Option<&(mut) dyn Reflect>`.
---
## Changelog
- Added `PartialReflect`.
- `Reflect` is now a subtrait of `PartialReflect`.
- Moved most methods on `Reflect` to the new `PartialReflect`.
- Added `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect}`.
- Added `PartialReflect::{try_as_reflect, try_as_reflect_mut,
try_into_reflect}`.
- Added `<dyn PartialReflect>::{try_downcast_ref, try_downcast_mut,
try_downcast, try_take}` supplementing the methods on `dyn Reflect`.
## Migration Guide
- Most instances of `dyn Reflect` should be changed to `dyn
PartialReflect` which is less restrictive, however trait bounds should
generally stay as `T: Reflect`.
- The new `PartialReflect::{as_partial_reflect, as_partial_reflect_mut,
into_partial_reflect, try_as_reflect, try_as_reflect_mut,
try_into_reflect}` methods as well as `Reflect::{as_reflect,
as_reflect_mut, into_reflect}` will need to be implemented for manual
implementors of `Reflect`.
## Future Work
- This PR is designed to be followed up by another "Unique Reflect Phase
2" that addresses the following points:
- Investigate making serialization revolve around `Reflect` instead of
`PartialReflect`.
- [Remove the `try_*` methods on `dyn PartialReflect` since they are
stop
gaps](https://github.com/bevyengine/bevy/pull/7207#discussion_r1083476050).
- Investigate usages like `ReflectComponent`. In the places they
currently use `PartialReflect`, should they be changed to use `Reflect`?
- Merging this opens the door to lots of reflection features we haven't
been able to implement.
- We could re-add [the `Reflectable`
trait](8e3488c880/crates/bevy_reflect/src/reflect.rs (L337-L342))
and make `FromReflect` a requirement to improve [`FromReflect`
ergonomics](https://github.com/bevyengine/rfcs/pull/59). This is
currently not possible because dynamic types cannot sensibly be
`FromReflect`.
- Since this is an alternative to #5772, #5781 would be made cleaner.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
# Objective
The `SceneInstanceReady` event would be more ergonomic (and potentially
efficient) if it could be delivered to listeners attached to the scene
entities becoming ready rather than into a World-global queue.
This is an evolution of @Shatur's work in #9313.
## Solution
The scene spawner is changed to trigger observers on the scene entity
when it is ready rather than enqueue an event with `EventWriter`.
This addresses the two outstanding feature requests mentioned on #2218,
that i) the events should be "scoped" in some way and ii) that the
`InstanceId` should be included in the event.
## Testing
Modified the `scene_spawner::tests::event` test to use the new
mechanism.
---
## Changelog
- Changed `SceneInstanceReady` to trigger an entity observer rather than
be written to an event queue.
- Changed `SceneInstanceReady` to carry the `InstanceId` of the scene.
## Migration Guide
If you have a system which read `SceneInstanceReady` events:
> ```fn ready_system(ready_events: EventReader<'_, '_,
SceneInstanceReady>) {```
It must be rewritten as an observer:
> ```commands.observe(|trigger: Trigger<SceneInstanceReady>| {```
Or, if you were expecting the event in relation to a specific entity or
entities, as an entity observer:
> ```commands.entity(entity).observe(|trigger:
Trigger<SceneInstanceReady>| {```
# Objective
- Fix issue #2611
## Solution
- Add `--generate-link-to-definition` to all the `rustdoc-args` arrays
in the `Cargo.toml`s (for docs.rs)
- Add `--generate-link-to-definition` to the `RUSTDOCFLAGS` environment
variable in the docs workflow (for dev-docs.bevyengine.org)
- Document all the workspace crates in the docs workflow (needed because
otherwise only the source code of the `bevy` package will be included,
making the argument useless)
- I think this also fixes#3662, since it fixes the bug on
dev-docs.bevyengine.org, while on docs.rs it has been fixed for a while
on their side.
---
## Changelog
- The source code viewer on docs.rs now includes links to the
definitions.
# Objective
Fixes a regression in [previously merged but then reverted
pr](https://github.com/bevyengine/bevy/pull/13714) that aligns
lower-level `Scene` API with that in `DynamicScene`. Please look at the
original pr for more details.
The problem was `spawn_sync_internal` is used in `spawn_queued_scenes`.
Since instance creation was moved up a level we need to make sure we add
a specific instance to `SceneSpawner::spawned_instances` when using
`spawn_sync_internal` (just like we do for `DynamicScene`).
Please look at the last commit when reviewing.
## Testing
`alien_cake_addict` and `deferred_rendering` examples look as expected.
## Changelog
Changed `Scene::write_to_world_with` to take `entity_map` as an argument
and no longer return an `InstanceInfo`
## Migration Guide
`Scene::write_to_world_with` no longer returns an `InstanceInfo`.
Before
```rust
scene.write_to_world_with(world, ®istry)
```
After
```rust
let mut entity_map = EntityHashMap::default();
scene.write_to_world_with(world, &mut entity_map, ®istry)
```
# Objective
- Often in games you will want to create chains of systems that modify
some event. For example, a chain of damage systems that handle a
DamageEvent and modify the underlying value before the health system
finally consumes the event. Right now this requires either:
* Using a component added to the entity
* Consuming and refiring events
Neither is ideal when really all we want to do is read the events value,
modify it, and write it back.
## Solution
- Create an EventMutator class similar to EventReader but with ResMut<T>
and iterators that return &mut so that events can be mutated.
## Testing
- I replicated all the existing tests for EventReader to make sure
behavior was the same (I believe) and added a number of tests specific
to testing that 1) events can actually be mutated, and that 2)
EventReader sees changes from EventMutator for events it hasn't already
seen.
## Migration Guide
Users currently using `ManualEventReader` should use `EventCursor`
instead. `ManualEventReader` will be removed in Bevy 0.16. Additionally,
`Events::get_reader` has been replaced by `Events::get_cursor`.
Users currently directly accessing the `Events` resource for mutation
should move to `EventMutator` if possible.
---------
Co-authored-by: poopy <gonesbird@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Bump version after release
This PR has been auto-generated
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
# Objective
- Emit an event regardless of scene type (`Scene` and `DynamicScene`).
- Also send the `InstanceId` along.
Follow-up to #11002.
Fixes#2218.
## Solution
- Send `SceneInstanceReady` regardless of scene type.
- Make `SceneInstanceReady::parent` `Option`al.
- Add `SceneInstanceReady::id`.
---
## Changelog
### Changed
- `SceneInstanceReady` is now sent for `Scene` as well.
`SceneInstanceReady::parent` is an `Option` and
`SceneInstanceReady::id`, an `InstanceId`, is added to identify the
corresponding `Scene`.
## Migration Guide
- `SceneInstanceReady { parent: Entity }` is now `SceneInstanceReady {
id: InstanceId, parent: Option<Entity> }`.
# Objective
The `AssetReader` trait allows customizing the behavior of fetching
bytes for an `AssetPath`, and expects implementors to return `dyn
AsyncRead + AsyncSeek`. This gives implementors of `AssetLoader` great
flexibility to tightly integrate their asset loading behavior with the
asynchronous task system.
However, almost all implementors of `AssetLoader` don't use the async
functionality at all, and just call `AsyncReadExt::read_to_end(&mut
Vec<u8>)`. This is incredibly inefficient, as this method repeatedly
calls `poll_read` on the trait object, filling the vector 32 bytes at a
time. At my work we have assets that are hundreds of megabytes which
makes this a meaningful overhead.
## Solution
Turn the `Reader` type alias into an actual trait, with a provided
method `read_to_end`. This provided method should be more efficient than
the existing extension method, as the compiler will know the underlying
type of `Reader` when generating this function, which removes the
repeated dynamic dispatches and allows the compiler to make further
optimizations after inlining. Individual implementors are able to
override the provided implementation -- for simple asset readers that
just copy bytes from one buffer to another, this allows removing a large
amount of overhead from the provided implementation.
Now that `Reader` is an actual trait, I also improved the ergonomics for
implementing `AssetReader`. Currently, implementors are expected to box
their reader and return it as a trait object, which adds unnecessary
boilerplate to implementations. This PR changes that trait method to
return a pseudo trait alias, which allows implementors to return `impl
Reader` instead of `Box<dyn Reader>`. Now, the boilerplate for boxing
occurs in `ErasedAssetReader`.
## Testing
I made identical changes to my company's fork of bevy. Our app, which
makes heavy use of `read_to_end` for asset loading, still worked
properly after this. I am not aware if we have a more systematic way of
testing asset loading for correctness.
---
## Migration Guide
The trait method `bevy_asset::io::AssetReader::read` (and `read_meta`)
now return an opaque type instead of a boxed trait object. Implementors
of these methods should change the type signatures appropriately
```rust
impl AssetReader for MyReader {
// Before
async fn read<'a>(&'a self, path: &'a Path) -> Result<Box<Reader<'a>>, AssetReaderError> {
let reader = // construct a reader
Box::new(reader) as Box<Reader<'a>>
}
// After
async fn read<'a>(&'a self, path: &'a Path) -> Result<impl Reader + 'a, AssetReaderError> {
// create a reader
}
}
```
`bevy::asset::io::Reader` is now a trait, rather than a type alias for a
trait object. Implementors of `AssetLoader::load` will need to adjust
the method signature accordingly
```rust
impl AssetLoader for MyLoader {
async fn load<'a>(
&'a self,
// Before:
reader: &'a mut bevy::asset::io::Reader,
// After:
reader: &'a mut dyn bevy::asset::io::Reader,
_: &'a Self::Settings,
load_context: &'a mut LoadContext<'_>,
) -> Result<Self::Asset, Self::Error> {
}
```
Additionally, implementors of `AssetReader` that return a type
implementing `futures_io::AsyncRead` and `AsyncSeek` might need to
explicitly implement `bevy::asset::io::Reader` for that type.
```rust
impl bevy::asset::io::Reader for MyAsyncReadAndSeek {}
```
# Objective
The `BuildChildren` and `BuildWorldChildren` traits are mostly
identical, so I decided to try and merge them. I'm not sure of the
history, maybe they were added before GATs existed.
## Solution
- Add an associated type to `BuildChildren` which reflects the prior
differences between the `BuildChildren` and `BuildWorldChildren` traits.
- Add `ChildBuild` trait that is the bounds for
`BuildChildren::Builder`, with impls for `ChildBuilder` and
`WorldChildBuilder`.
- Remove `BuildWorldChildren` trait and replace it with an impl of
`BuildChildren` for `EntityWorldMut`.
## Testing
I ran several of the examples that use entity hierarchies, mainly UI.
---
## Changelog
n/a
## Migration Guide
n/a
# Objective
There were some issues with the `serialize` feature:
- `bevy_app` had a `serialize` feature and a dependency on `serde` even
there is no usage of serde at all inside `bevy_app`
- the `bevy_app/serialize` feature enabled `bevy_ecs/serde`, which is
strange
- `bevy_internal/serialize` did not enable `bevy_app/serialize` so there
was no way of serializing an Entity in bevy 0.14
## Solution
- Remove `serde` and `bevy_app/serialize`
- Add a `serialize` flag on `bevy_ecs` that enables `serde`
- ` bevy_internal/serialize` now enables `bevy_ecs/serialize`
# Objective
`Scene` and `DynamicScene` work with `InstanceInfo` at different levels
of abstraction
- `Scene::write_to_world_with` returns an `InstanceInfo` whereas
`DynamicScene::write_to_world_with` returns `()`. Instances are created
one level higher at the `SceneSpawner` API level.
- `DynamicScene::write_to_world_with` takes the `entity_map` as an
argument whereas the `Scene` version is less flexible and creates a new
one for you. No reason this needs to be the case.
## Solution
I propose changing `Scene::write_to_world_with` to match the API we have
for `DynamicScene`. Returning the `InstanceInfo` as we do today just
seems like a leaky abstraction - it's only used in
`spawn_sync_internal`. Being able to pass in an entity_map gives you
more flexibility with how you write entities to a world.
This also moves `InstanceInfo` out of `Scene` which is cleaner
conceptually. If someone wants to work with instances then they should
work with `SceneSpawner` - I see `write_to_world_with` as a lower-level
API to be used with exclusive world access.
## Testing
Code is just shifting things around.
## Changelog
Changed `Scene::write_to_world_with` to take `entity_map` as an argument
and no longer return an `InstanceInfo`
## Migration Guide
`Scene::write_to_world_with` no longer returns an `InstanceInfo`.
Before
```rust
scene.write_to_world_with(world, ®istry)
```
After
```rust
let mut entity_map = EntityHashMap::default();
scene.write_to_world_with(world, &mut entity_map, ®istry)
```
# Objective
- Fix#10958 by performing entity mapping on the entities inside of
resources.
## Solution
- Resources can reflect(MapEntitiesResource) and impl MapEntities to get
access to the mapper during the world insert of the scene.
## Testing
- A test resource_entity_map_maps_entities confirms the desired
behavior.
## Changelog
- Added reflect(MapEntitiesResource) for mapping entities on Resources
in a DynamicScene.
fixes 10958
# Objective
- `README.md` is a common file that usually gives an overview of the
folder it is in.
- When on <https://crates.io>, `README.md` is rendered as the main
description.
- Many crates in this repository are lacking `README.md` files, which
makes it more difficult to understand their purpose.
<img width="1552" alt="image"
src="https://github.com/bevyengine/bevy/assets/59022059/78ebf91d-b0c4-4b18-9874-365d6310640f">
- There are also a few inconsistencies with `README.md` files that this
PR and its follow-ups intend to fix.
## Solution
- Create a `README.md` file for all crates that do not have one.
- This file only contains the title of the crate (underscores removed,
proper capitalization, acronyms expanded) and the <https://shields.io>
badges.
- Remove the `readme` field in `Cargo.toml` for `bevy` and
`bevy_reflect`.
- This field is redundant because [Cargo automatically detects
`README.md`
files](https://doc.rust-lang.org/cargo/reference/manifest.html#the-readme-field).
The field is only there if you name it something else, like `INFO.md`.
- Fix capitalization of `bevy_utils`'s `README.md`.
- It was originally `Readme.md`, which is inconsistent with the rest of
the project.
- I created two commits renaming it to `README.md`, because Git appears
to be case-insensitive.
- Expand acronyms in title of `bevy_ptr` and `bevy_utils`.
- In the commit where I created all the new `README.md` files, I
preferred using expanded acronyms in the titles. (E.g. "Bevy Developer
Tools" instead of "Bevy Dev Tools".)
- This commit changes the title of existing `README.md` files to follow
the same scheme.
- I do not feel strongly about this change, please comment if you
disagree and I can revert it.
- Add <https://shields.io> badges to `bevy_time` and `bevy_transform`,
which are the only crates currently lacking them.
---
## Changelog
- Added `README.md` files to all crates missing it.
# Objective
- Fixes#12976
## Solution
This one is a doozy.
- Run `cargo +beta clippy --workspace --all-targets --all-features` and
fix all issues
- This includes:
- Moving inner attributes to be outer attributes, when the item in
question has both inner and outer attributes
- Use `ptr::from_ref` in more scenarios
- Extend the valid idents list used by `clippy:doc_markdown` with more
names
- Use `Clone::clone_from` when possible
- Remove redundant `ron` import
- Add backticks to **so many** identifiers and items
- I'm sorry whoever has to review this
---
## Changelog
- Added links to more identifiers in documentation.
# Objective
Minimize the number of dependencies low in the tree.
## Solution
* Remove the dependency on rustc-hash in bevy_ecs (not used) and
bevy_macro_utils (only used in one spot).
* Deduplicate the dependency on `sha1_smol` with the existing blake3
dependency already being used for bevy_asset.
* Remove the unused `ron` dependency on `bevy_app`
* Make the `serde` dependency for `bevy_ecs` optional. It's only used
for serializing Entity.
* Change the `wgpu` dependency to `wgpu-types`, and make it optional for
`bevy_color`.
* Remove the unused `thread-local` dependency on `bevy_render`.
* Make multiple dependencies for `bevy_tasks` optional and enabled only
when running with the `multi-threaded` feature. Preferably they'd be
disabled all the time on wasm, but I couldn't find a clean way to do
this.
---
## Changelog
TODO
## Migration Guide
TODO
# Objective
This is a necessary precursor to #9122 (this was split from that PR to
reduce the amount of code to review all at once).
Moving `!Send` resource ownership to `App` will make it unambiguously
`!Send`. `SubApp` must be `Send`, so it can't wrap `App`.
## Solution
Refactor `App` and `SubApp` to not have a recursive relationship. Since
`SubApp` no longer wraps `App`, once `!Send` resources are moved out of
`World` and into `App`, `SubApp` will become unambiguously `Send`.
There could be less code duplication between `App` and `SubApp`, but
that would break `App` method chaining.
## Changelog
- `SubApp` no longer wraps `App`.
- `App` fields are no longer publicly accessible.
- `App` can no longer be converted into a `SubApp`.
- Various methods now return references to a `SubApp` instead of an
`App`.
## Migration Guide
- To construct a sub-app, use `SubApp::new()`. `App` can no longer
convert into `SubApp`.
- If you implemented a trait for `App`, you may want to implement it for
`SubApp` as well.
- If you're accessing `app.world` directly, you now have to use
`app.world()` and `app.world_mut()`.
- `App::sub_app` now returns `&SubApp`.
- `App::sub_app_mut` now returns `&mut SubApp`.
- `App::get_sub_app` now returns `Option<&SubApp>.`
- `App::get_sub_app_mut` now returns `Option<&mut SubApp>.`
# Objective
- Fix#12746
- When users despawn a scene, the `InstanceId` within `spawned_scenes`
and `spawned_dynamic_scenes` is not removed, causing a potential memory
leak
## Solution
- `spawned_scenes` field was never used, and I removed it
- Add a component remove hook for `Handle<DynamicScene>`, and when the
`Handle<DynamicScene>` component is removed, delete the corresponding
`InstanceId` from `spawned_dynamic_scenes`
# Objective
- A scene usually gets created using the `SceneBundle` or
`DynamicSceneBundle`. This means that the scene's entities get added as
children of the root entity (the entity on which the `SceneBundle` gets
added)
- When the scene gets deleted using the `SceneSpawner`, the scene's
entities are deleted, but the `Children` component of the root entity
doesn't get updated. This means that the hierarchy becomes unsound, with
Children linking to non-existing components.
## Solution
- Update the `despawn_sync` logic to also update the `Children` from any
parents of the scene, if there are any
- Adds a test where a Scene gets despawned and checks for dangling
Children references on the parent. The test fails on `main` but works
here.
## Alternative implementations
- One option could be to add a `parent: Option<Entity>` on the
[InstanceInfo](df15cd7dcc/crates/bevy_scene/src/scene_spawner.rs (L27))
struct that tracks if the SceneInstance was added as a child of a root
entity
Adopted from and closes https://github.com/bevyengine/bevy/pull/9914 by
@djeedai
# Objective
Fix the use of `TypeRegistry` instead of `TypeRegistryArc` in dynamic
scene and its serializer.
Rename `DynamicScene::serialize_ron()` into `serialize()` to highlight
the fact this is not about serializing to RON specifically, but rather
about serializing to the official Bevy scene format (`.scn` /
`.scn.ron`) which the `SceneLoader` can deserialize (and which happens
to be based in RON, but that not the object here). Also make the link
with the documentation of `SceneLoader` so users understand the full
serializing cycle of a Bevy dynamic scene.
Document `SceneSerializer` with an example showing how to serialize to a
custom format (here: RON), which is easily transposed to serializing
into any other format.
Fixes#9520
## Changelog
### Changed
* `SceneSerializer` and all related serializing helper types now take a
`&TypeRegistry` instead of a `&TypeRegistryArc`. ([SceneSerializer
needlessly uses specifically
&TypeRegistryArc #9520](https://github.com/bevyengine/bevy/issues/9520))
* `DynamicScene::serialize_ron()` was renamed to `serialize()`.
## Migration Guide
* `SceneSerializer` and all related serializing helper types now take a
`&TypeRegistry` instead of a `&TypeRegistryArc`. You can upgrade by
getting the former from the latter with `TypeRegistryArc::read()`,
_e.g._
```diff
let registry_arc: TypeRegistryArc = [...];
- let serializer = SceneSerializer(&scene, ®istry_arc);
+ let registry = registry_arc.read();
+ let serializer = SceneSerializer(&scene, ®istry);
```
* Rename `DynamicScene::serialize_ron()` to `serialize()`.
---------
Co-authored-by: Jerome Humbert <djeedai@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecil@gmail.com>
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
Co-authored-by: James Liu <contact@jamessliu.com>
# Objective
Resolves#3824. `unsafe` code should be the exception, not the norm in
Rust. It's obviously needed for various use cases as it's interfacing
with platforms and essentially running the borrow checker at runtime in
the ECS, but the touted benefits of Bevy is that we are able to heavily
leverage Rust's safety, and we should be holding ourselves accountable
to that by minimizing our unsafe footprint.
## Solution
Deny `unsafe_code` workspace wide. Add explicit exceptions for the
following crates, and forbid it in almost all of the others.
* bevy_ecs - Obvious given how much unsafe is needed to achieve
performant results
* bevy_ptr - Works with raw pointers, even more low level than bevy_ecs.
* bevy_render - due to needing to integrate with wgpu
* bevy_window - due to needing to integrate with raw_window_handle
* bevy_utils - Several unsafe utilities used by bevy_ecs. Ideally moved
into bevy_ecs instead of made publicly usable.
* bevy_reflect - Required for the unsafe type casting it's doing.
* bevy_transform - for the parallel transform propagation
* bevy_gizmos - For the SystemParam impls it has.
* bevy_assets - To support reflection. Might not be required, not 100%
sure yet.
* bevy_mikktspace - due to being a conversion from a C library. Pending
safe rewrite.
* bevy_dynamic_plugin - Inherently unsafe due to the dynamic loading
nature.
Several uses of unsafe were rewritten, as they did not need to be using
them:
* bevy_text - a case of `Option::unchecked` could be rewritten as a
normal for loop and match instead of an iterator.
* bevy_color - the Pod/Zeroable implementations were replaceable with
bytemuck's derive macros.
# Objective
We have `ReflectSerializer` and `TypedReflectSerializer`. The former is
the one users will most often use since the latter takes a bit more
effort to deserialize.
However, our deserializers are named `UntypedReflectDeserializer` and
`TypedReflectDeserializer`. There is no obvious indication that
`UntypedReflectDeserializer` must be used with `ReflectSerializer` since
the names don't quite match up.
## Solution
Rename `UntypedReflectDeserializer` back to `ReflectDeserializer`
(initially changed as part of #5723).
Also update the docs for both deserializers (as they were pretty out of
date) and include doc examples.
I also updated the docs for the serializers, too, just so that
everything is consistent.
---
## Changelog
- Renamed `UntypedReflectDeserializer` to `ReflectDeserializer`
- Updated docs for `ReflectDeserializer`, `TypedReflectDeserializer`,
`ReflectSerializer`, and `TypedReflectSerializer`
## Migration Guide
`UntypedReflectDeserializer` has been renamed to `ReflectDeserializer`.
Usages will need to be updated accordingly.
```diff
- let reflect_deserializer = UntypedReflectDeserializer::new(®istry);
+ let reflect_deserializer = ReflectDeserializer::new(®istry);
```
# Objective
Currently the built docs only shows the logo and favicon for the top
level `bevy` crate. This makes views like
https://docs.rs/bevy_ecs/latest/bevy_ecs/ look potentially unrelated to
the project at first glance.
## Solution
Reproduce the docs attributes for every crate that Bevy publishes.
Ideally this would be done with some workspace level Cargo.toml control,
but AFAICT, such support does not exist.
Fixes#12600
## Solution
Removed Into<AssetId<T>> for Handle<T> as proposed in Issue
conversation, fixed dependent code
## Migration guide
If you use passing Handle by value as AssetId, you should pass reference
or call .id() method on it
Before (0.13):
`assets.insert(handle, value);`
After (0.14):
`assets.insert(&handle, value);`
or
`assets.insert(handle.id(), value);`
# Objective
Simplify implementing some asset traits without Box::pin(async move{})
shenanigans.
Fixes (in part) https://github.com/bevyengine/bevy/issues/11308
## Solution
Use async-fn in traits when possible in all traits. Traits with return
position impl trait are not object safe however, and as AssetReader and
AssetWriter are both used with dynamic dispatch, you need a Boxed
version of these futures anyway.
In the future, Rust is [adding
](https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html)proc
macros to generate these traits automatically, and at some point in the
future dyn traits should 'just work'. Until then.... this seemed liked
the right approach given more ErasedXXX already exist, but, no clue if
there's plans here! Especially since these are public now, it's a bit of
an unfortunate API, and means this is a breaking change.
In theory this saves some performance when these traits are used with
static dispatch, but, seems like most code paths go through dynamic
dispatch, which boxes anyway.
I also suspect a bunch of the lifetime annotations on these function
could be simplified now as the BoxedFuture was often the only thing
returned which needed a lifetime annotation, but I'm not touching that
for now as traits + lifetimes can be so tricky.
This is a revival of
[pull/11362](https://github.com/bevyengine/bevy/pull/11362) after a
spectacular merge f*ckup, with updates to the latest Bevy. Just to recap
some discussion:
- Overall this seems like a win for code quality, especially when
implementing these traits, but a loss for having to deal with ErasedXXX
variants.
- `ConditionalSend` was the preferred name for the trait that might be
Send, to deal with wasm platforms.
- When reviewing be sure to disable whitespace difference, as that's 95%
of the PR.
## Changelog
- AssetReader, AssetWriter, AssetLoader, AssetSaver and Process now use
async-fn in traits rather than boxed futures.
## Migration Guide
- Custom implementations of AssetReader, AssetWriter, AssetLoader,
AssetSaver and Process should switch to async fn rather than returning a
bevy_utils::BoxedFuture.
- Simultaniously, to use dynamic dispatch on these traits you should
instead use dyn ErasedXXX.
# Objective
Fix missing `TextBundle` (and many others) which are present in the main
crate as default features but optional in the sub-crate. See:
- https://docs.rs/bevy/0.13.0/bevy/ui/node_bundles/index.html
- https://docs.rs/bevy_ui/0.13.0/bevy_ui/node_bundles/index.html
~~There are probably other instances in other crates that I could track
down, but maybe "all-features = true" should be used by default in all
sub-crates? Not sure.~~ (There were many.) I only noticed this because
rust-analyzer's "open docs" features takes me to the sub-crate, not the
main one.
## Solution
Add "all-features = true" to docs.rs metadata for crates that use
features.
## Changelog
### Changed
- Unified features documented on docs.rs between main crate and
sub-crates
# Objective
Fixes https://github.com/bevyengine/bevy/issues/11628
## Migration Guide
`Command` and `CommandQueue` have migrated from `bevy_ecs::system` to
`bevy_ecs::world`, so `use bevy_ecs::world::{Command, CommandQueue};`
when necessary.
# Objective
- In #9623 I forgot to change the `FromWorld` requirement for
`ReflectResource`, fix that;
- Fix#12129
## Solution
- Use the same approach as in #9623 to try using `FromReflect` and
falling back to the `ReflectFromWorld` contained in the `TypeRegistry`
provided
- Just reflect `Resource` on `State<S>` since now that's possible
without introducing new bounds.
---
## Changelog
- `ReflectResource`'s `FromType<T>` implementation no longer requires
`T: FromWorld`, but instead now requires `FromReflect`.
- `ReflectResource::insert`, `ReflectResource::apply_or_insert` and
`ReflectResource::copy` now take an extra `&TypeRegistry` parameter.
## Migration Guide
- Users of `#[reflect(Resource)]` will need to also implement/derive
`FromReflect` (should already be the default).
- Users of `#[reflect(Resource)]` may now want to also add `FromWorld`
to the list of reflected traits in case their `FromReflect`
implementation may fail.
- Users of `ReflectResource` will now need to pass a `&TypeRegistry` to
its `insert`, `apply_or_insert` and `copy` methods.
Fixes#12016.
Bump version after release
This PR has been auto-generated
Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François <mockersf@gmail.com>
# Objective
Reduce the size of `bevy_utils`
(https://github.com/bevyengine/bevy/issues/11478)
## Solution
Move `EntityHash` related types into `bevy_ecs`. This also allows us
access to `Entity`, which means we no longer need `EntityHashMap`'s
first generic argument.
---
## Changelog
- Moved `bevy::utils::{EntityHash, EntityHasher, EntityHashMap,
EntityHashSet}` into `bevy::ecs::entity::hash` .
- Removed `EntityHashMap`'s first generic argument. It is now hardcoded
to always be `Entity`.
## Migration Guide
- Uses of `bevy::utils::{EntityHash, EntityHasher, EntityHashMap,
EntityHashSet}` now have to be imported from `bevy::ecs::entity::hash`.
- Uses of `EntityHashMap` no longer have to specify the first generic
parameter. It is now hardcoded to always be `Entity`.
# Objective
Send `SceneInstanceReady` only once per scene.
## Solution
I assume that this was not intentional.
So I just changed it to only be sent once per scene.
---
## Changelog
### Fixed
- Fixed `SceneInstanceReady` being emitted for every `Entity` in a
scene.
Use `TypeIdMap<T>` instead of `HashMap<TypeId, T>`
- ~~`TypeIdMap` was in `bevy_ecs`. I've kept it there because of
#11478~~
- ~~I haven't swapped `bevy_reflect` over because it doesn't depend on
`bevy_ecs`, but I'd also be happy with moving `TypeIdMap` to
`bevy_utils` and then adding a dependency to that~~
- ~~this is a slight change in the public API of
`DrawFunctionsInternal`, does this need to go in the changelog?~~
## Changelog
- moved `TypeIdMap` to `bevy_utils`
- changed `DrawFunctionsInternal::indices` to `TypeIdMap`
## Migration Guide
- `TypeIdMap` now lives in `bevy_utils`
- `DrawFunctionsInternal::indices` now uses a `TypeIdMap`.
---------
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective
Currently the `missing_docs` lint is allowed-by-default and enabled at
crate level when their documentations is complete (see #3492).
This PR proposes to inverse this logic by making `missing_docs`
warn-by-default and mark crates with imcomplete docs allowed.
## Solution
Makes `missing_docs` warn at workspace level and allowed at crate level
when the docs is imcomplete.