Commit graph

20 commits

Author SHA1 Message Date
Charles Bournhonesque
9223201d54
Make the MapEntities trait generic over Mappers, and add a simpler EntityMapper (#11428)
# Objective

My motivation are to resolve some of the issues I describe in this
[PR](https://github.com/bevyengine/bevy/issues/11415):
- not being able to easily mapping entities because the current
EntityMapper requires `&mut World` access
- not being able to create my own `EntityMapper` because some components
(`Parent` or `Children`) do not provide any public way of modifying the
inner entities

This PR makes the `MapEntities` trait accept a generic type that
implements `Mapper` to perform the mapping.
This means we don't need to use `EntityMapper` to perform our mapping,
we can use any type that implements `Mapper`. Basically this change is
very similar to what `serde` does. Instead of specifying directly how to
map entities for a given type, we have 2 distinct steps:
- the user implements `MapEntities` to define how the type will be
traversed and which `Entity`s will be mapped
  - the `Mapper` defines how the mapping is actually done
This is similar to the distinction between `Serialize` (`MapEntities`)
and `Serializer` (`Mapper`).

This allows networking library to map entities without having to use the
existing `EntityMapper` (which requires `&mut World` access and the use
of `world_scope()`)


## Migration Guide
- The existing `EntityMapper` (notably used to replicate `Scenes` across
different `World`s) has been renamed to `SceneEntityMapper`

- The `MapEntities` trait now works with a generic `EntityMapper`
instead of the specific struct `EntityMapper`.
Calls to `fn map_entities(&mut self, entity_mapper: &mut EntityMapper)`
need to be updated to
`fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M)`

- The new trait `EntityMapper` has been added to the prelude

---------

Co-authored-by: Charles Bournhonesque <cbournhonesque@snapchat.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
2024-01-28 19:51:46 +00:00
Joseph
7d69d3195f
refactor: Simplify lifetimes for Commands and related types (#11445)
# Objective

It would be convenient to be able to call functions with `Commands` as a
parameter without having to move your own instance of `Commands`. Since
this struct is composed entirely of references, we can easily get an
owned instance of `Commands` by shortening the lifetime.

## Solution

Add `Commands::reborrow`, `EntiyCommands::reborrow`, and
`Deferred::reborrow`, which returns an owned version of themselves with
a shorter lifetime.

Remove unnecessary lifetimes from `EntityCommands`. The `'w` and `'s`
lifetimes only have to be separate for `Commands` because it's used as a
`SystemParam` -- this is not the case for `EntityCommands`.

---

## Changelog

Added `Commands::reborrow`. This is useful if you have `&mut Commands`
but need `Commands`. Also added `EntityCommands::reborrow` and
`Deferred:reborrow` which serve the same purpose.

## Migration Guide

The lifetimes for `EntityCommands` have been simplified.

```rust
// Before (Bevy 0.12)
struct MyStruct<'w, 's, 'a> {
     commands: EntityCommands<'w, 's, 'a>,
}

// After (Bevy 0.13)
struct MyStruct<'a> {
    commands: EntityCommands<'a>,
}
```

The method `EntityCommands::commands` now returns `Commands` rather than
`&mut Commands`.

```rust
// Before (Bevy 0.12)
let commands = entity_commands.commands();
commands.spawn(...);

// After (Bevy 0.13)
let mut commands = entity_commands.commands();
commands.spawn(...);
```
2024-01-22 15:35:42 +00:00
Giacomo Stevanato
eff96e20a0
Add ReflectFromWorld and replace the FromWorld requirement on ReflectComponent and ReflectBundle with FromReflect (#9623)
# Objective

- `FromType<T>` for `ReflectComponent` and `ReflectBundle` currently
require `T: FromWorld` for two reasons:
    - they include a `from_world` method;
- they create dummy `T`s using `FromWorld` and then `apply` a `&dyn
Reflect` to it to simulate `FromReflect`.
- However `FromWorld`/`Default` may be difficult/weird/impractical to
implement, while `FromReflect` is easier and also more natural for the
job.
- See also
https://discord.com/channels/691052431525675048/1146022009554337792

## Solution

- Split `from_world` from `ReflectComponent` and `ReflectBundle` into
its own `ReflectFromWorld` struct.
- Replace the requirement on `FromWorld` in `ReflectComponent` and
`ReflectBundle` with `FromReflect`

---

## Changelog

- `ReflectComponent` and `ReflectBundle` no longer offer a `from_world`
method.
- `ReflectComponent` and `ReflectBundle`'s `FromType<T>` implementation
no longer requires `T: FromWorld`, but now requires `FromReflect`.
- `ReflectComponent::insert`, `ReflectComponent::apply_or_insert` and
`ReflectComponent::copy` now take an extra `&TypeRegistry` parameter.
- There is now a new `ReflectFromWorld` struct.

## Migration Guide

- Existing uses of `ReflectComponent::from_world` and
`ReflectBundle::from_world` will have to be changed to
`ReflectFromWorld::from_world`.
- Users of `#[reflect(Component)]` and `#[reflect(Bundle)]` will need to
also implement/derive `FromReflect`.
- Users of `#[reflect(Component)]` and `#[reflect(Bundle)]` may now want
to also add `FromWorld` to the list of reflected traits in case their
`FromReflect` implementation may fail.
- Users of `ReflectComponent` will now need to pass a `&TypeRegistry` to
its `insert`, `apply_or_insert` and `copy` methods.
2024-01-19 16:08:57 +00:00
Doonv
189ceaf0d3
Replace or document ignored doctests (#11040)
# Objective

There are a lot of doctests that are `ignore`d for no documented reason.
And that should be fixed.

## Solution

I searched the bevy repo with the regex ` ```[a-z,]*ignore ` in order to
find all `ignore`d doctests. For each one of the `ignore`d doctests, I
did the following steps:
1. Attempt to remove the `ignored` attribute while still passing the
test. I did this by adding hidden dummy structs and imports.
2. If step 1 doesn't work, attempt to replace the `ignored` attribute
with the `no_run` attribute while still passing the test.
3. If step 2 doesn't work, keep the `ignored` attribute but add
documentation for why the `ignored` attribute was added.

---------

Co-authored-by: François <mockersf@gmail.com>
2024-01-01 16:50:56 +00:00
tygyh
fd308571c4
Remove unnecessary path prefixes (#10749)
# Objective

- Shorten paths by removing unnecessary prefixes

## Solution

- Remove the prefixes from many paths which do not need them. Finding
the paths was done automatically using built-in refactoring tools in
Jetbrains RustRover.
2023-11-28 23:43:40 +00:00
Helix
879893c30a
fix insert_reflect panic caused by clone_value (#10627)
# Objective

- `insert_reflect` relies on `reflect_type_path`, which doesn't gives
the actual type path for object created by `clone_value`, leading to an
unexpected panic. This is a workaround for it.
- Fix #10590 

## Solution

- Tries to get type path from `get_represented_type_info` if get failed
from `reflect_type_path`.

---

## Defect remaining

- `get_represented_type_info` implies a shortage on performance than
using `TypeRegistry`.
2023-11-28 00:17:10 +00:00
Mike
11b1b3a24f
delete methods deprecated in 0.12 (#10693)
## Changelog

- delete methods deprecated in 0.12
2023-11-24 16:15:47 +00:00
BD103
04ceb46fe0
Use EntityHashMap for EntityMapper (#10415)
# Objective

- There is a specialized hasher for entities:
[`EntityHashMap`](https://docs.rs/bevy/latest/bevy/utils/type.EntityHashMap.html)
- [`EntityMapper`] currently uses a normal `HashMap<Entity, Entity>`
- Fixes #10391

## Solution

- Replace the normal `HashMap` with the more performant `EntityHashMap`

## Questions

- This does change public API. Should a system be implemented to help
migrate code?
  - Perhaps an `impl From<HashMap<K, V, S>> for EntityHashMap<K, V>`
- I updated to docs for each function that I changed, but I may have
missed something

---

## Changelog

- Changed `EntityMapper` to use `EntityHashMap` instead of normal
`HashMap`

## Migration Guide

If you are using the following types, update their listed methods to use
the new `EntityHashMap`. `EntityHashMap` has the same methods as the
normal `HashMap`, so you just need to replace the name.

### `EntityMapper`

- `get_map`
- `get_mut_map`
- `new`
- `world_scope`

### `ReflectMapEntities`

- `map_all_entities`
- `map_entities`
- `write_to_world`

### `InstanceInfo`

- `entity_map`
  - This is a property, not a method.

---

This is my first time contributing in a while, and I'm not familiar with
the usage of `EntityMapper`. I changed the type definition and fixed all
errors, but there may have been things I've missed. Please keep an eye
out for me!
2023-11-07 08:23:04 +00:00
radiish
262846e702
reflect: TypePath part 2 (#8768)
# Objective

- Followup to #7184.
- ~Deprecate `TypeUuid` and remove its internal references.~ No longer
part of this PR.
- Use `TypePath` for the type registry, and (de)serialisation instead of
`std::any::type_name`.
- Allow accessing type path information behind proxies.

## Solution
- Introduce methods on `TypeInfo` and friends for dynamically querying
type path. These methods supersede the old `type_name` methods.
- Remove `Reflect::type_name` in favor of `DynamicTypePath::type_path`
and `TypeInfo::type_path_table`.
- Switch all uses of `std::any::type_name` in reflection, non-debugging
contexts to use `TypePath`.

---

## Changelog

- Added `TypePathTable` for dynamically accessing methods on `TypePath`
through `TypeInfo` and the type registry.
- Removed `type_name` from all `TypeInfo`-like structs.
- Added `type_path` and `type_path_table` methods to all `TypeInfo`-like
structs.
- Removed `Reflect::type_name` in favor of
`DynamicTypePath::reflect_type_path` and `TypeInfo::type_path`.
- Changed the signature of all `DynamicTypePath` methods to return
strings with a static lifetime.

## Migration Guide

- Rely on `TypePath` instead of `std::any::type_name` for all stability
guarantees and for use in all reflection contexts, this is used through
with one of the following APIs:
  - `TypePath::type_path` if you have a concrete type and not a value.
- `DynamicTypePath::reflect_type_path` if you have an `dyn Reflect`
value without a concrete type.
- `TypeInfo::type_path` for use through the registry or if you want to
work with the represented type of a `DynamicFoo`.
  
- Remove `type_name` from manual `Reflect` implementations.
- Use `type_path` and `type_path_table` in place of `type_name` on
`TypeInfo`-like structs.
- Use `get_with_type_path(_mut)` over `get_with_type_name(_mut)`.

## Note to reviewers

I think if anything we were a little overzealous in merging #7184 and we
should take that extra care here.

In my mind, this is the "point of no return" for `TypePath` and while I
think we all agree on the design, we should carefully consider if the
finer details and current implementations are actually how we want them
moving forward.

For example [this incorrect `TypePath` implementation for
`String`](3fea3c6c0b/crates/bevy_reflect/src/impls/std.rs (L90))
(note that `String` is in the default Rust prelude) snuck in completely
under the radar.
2023-10-09 19:33:03 +00:00
Bruce Mitchener
ae95ba5278
Fix typos. (#9922)
# Objective

- Have docs with fewer typos.1

## Solution

- Fix typos as they are found.
2023-09-25 18:35:46 +00:00
Bruce Mitchener
5e91e5f3ce
Improve doc formatting. (#9840)
# Objective

- Identifiers in docs should be marked up with backticks.

## Solution

- Mark up more identifiers in the docs with backticks.
2023-09-18 19:43:56 +00:00
Joseph
bc8bf34818
Allow disjoint mutable world access via EntityMut (#9419)
# Objective

Fix #4278
Fix #5504
Fix #9422

Provide safe ways to borrow an entire entity, while allowing disjoint
mutable access. `EntityRef` and `EntityMut` are not suitable for this,
since they provide access to the entire world -- they are just helper
types for working with `&World`/`&mut World`.

This has potential uses for reflection and serialization

## Solution

Remove `EntityRef::world`, which allows it to soundly be used within
queries.

`EntityMut` no longer supports structural world mutations, which allows
multiple instances of it to exist for different entities at once.
Structural world mutations are performed using the new type
`EntityWorldMut`.

```rust
fn disjoint_system(
     q2: Query<&mut A>,
     q1: Query<EntityMut, Without<A>>,
) { ... }

let [entity1, entity2] = world.many_entities_mut([id1, id2]);
*entity1.get_mut::<T>().unwrap() = *entity2.get().unwrap();

for entity in world.iter_entities_mut() {
    ...
}
```

---

## Changelog

- Removed `EntityRef::world`, to fix a soundness issue with queries.
+ Removed the ability to structurally mutate the world using
`EntityMut`, which allows it to be used in queries.
+ Added `EntityWorldMut`, which is used to perform structural mutations
that are no longer allowed using `EntityMut`.

## Migration Guide

**Note for maintainers: ensure that the guide for #9604 is updated
accordingly.**

Removed the method `EntityRef::world`, to fix a soundness issue with
queries. If you need access to `&World` while using an `EntityRef`,
consider passing the world as a separate parameter.

`EntityMut` can no longer perform 'structural' world mutations, such as
adding or removing components, or despawning the entity. Additionally,
`EntityMut::world`, `EntityMut::world_mut` , and
`EntityMut::world_scope` have been removed.
Instead, use the newly-added type `EntityWorldMut`, which is a helper
type for working with `&mut World`.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2023-08-28 23:30:59 +00:00
Noah
72fc63e594
implement insert and remove reflected entity commands (#8895)
# Objective

To enable non exclusive system usage of reflected components and make
reflection more ergonomic to use by making it more in line with standard
entity commands.

## Solution

- Implements a new `EntityCommands` extension trait for reflection
related functions in the reflect module of bevy_ecs.
- Implements 4 new commands, `insert_reflect`,
`insert_reflect_with_registry`, `remove_reflect`, and
`remove_reflect_with_registry`. Both insert commands take a `Box<dyn
Reflect>` component while the remove commands take the component type
name.

- Made `EntityCommands` fields pub(crate) to allow access in the reflect
module. (Might be worth making these just public to enable user end
custom entity commands in a different pr)
- Added basic tests to ensure the commands are actually working.
- Documentation of functions.

---

## Changelog

Added:
-  Implements 4 new commands on the new entity commands extension.
- `insert_reflect`
- `remove_reflect`
- `insert_reflect_with_registry`
- `remove_reflect_with_registry`

The commands operate the same except the with_registry commands take a
generic parameter for a resource that implements `AsRef<TypeRegistry>`.
Otherwise the default commands use the `AppTypeRegistry` for reflection
data.

Changed:

- Made `EntityCommands` fields pub(crate) to allow access in the reflect
module.

> Hopefully this time it works. Please don't make me rebase again ☹
2023-08-28 18:21:20 +00:00
Zachary Harrold
394e2b0c91
Replaced EntityMap with HashMap (#9461)
# Objective

- Fixes #9321

## Solution

- `EntityMap` has been replaced by a simple `HashMap<Entity, Entity>`.

---

## Changelog

- `EntityMap::world_scope` has been replaced with `World::world_scope`
to avoid creating a new trait. This is a public facing change to the
call semantics, but has no effect on results or behaviour.
- `EntityMap`, as a `HashMap`, now operates on `&Entity` rather than
`Entity`. This changes many standard access functions (e.g, `.get`) in a
public-facing way.

## Migration Guide

- Calls to `EntityMap::world_scope` can be directly replaced with the
following:
  `map.world_scope(&mut world)` -> `world.world_scope(&mut map)`
- Calls to legacy `EntityMap` methods such as `EntityMap::get` must
explicitly include de/reference symbols:
  `let entity = map.get(parent);` -> `let &entity = map.get(&parent);`
2023-08-28 17:18:16 +00:00
Hennadii Chernyshchyk
fb9a65fa0d
bevy_scene: Add ReflectBundle (#9165)
# Objective

Similar to #6344, but contains only `ReflectBundle` changes. Useful for
scripting. The implementation has also been updated to look exactly like
`ReflectComponent`.

---

## Changelog

### Added

- Reflection for bundles.

---------

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2023-08-28 16:50:43 +00:00
ClayenKitten
ffc572728f
Fix typos throughout the project (#9090)
# Objective

Fix typos throughout the project.

## Solution

[`typos`](https://github.com/crate-ci/typos) project was used for
scanning, but no automatic corrections were applied. I checked
everything by hand before fixing.

Most of the changes are documentation/comments corrections. Also, there
are few trivial changes to code (variable name, pub(crate) function name
and a few error/panic messages).

## Unsolved

`bevy_reflect_derive` has
[typo](1b51053f19/crates/bevy_reflect/bevy_reflect_derive/src/type_path.rs (L76))
in enum variant name that I didn't fix. Enum is `pub(crate)`, so there
shouldn't be any trouble if fixed. However, code is tightly coupled with
macro usage, so I decided to leave it for more experienced contributor
just in case.
2023-07-10 00:11:51 +00:00
Gino Valente
aeeb20ec4c
bevy_reflect: FromReflect Ergonomics Implementation (#6056)
# Objective

**This implementation is based on
https://github.com/bevyengine/rfcs/pull/59.**

---

Resolves #4597

Full details and motivation can be found in the RFC, but here's a brief
summary.

`FromReflect` is a very powerful and important trait within the
reflection API. It allows Dynamic types (e.g., `DynamicList`, etc.) to
be formed into Real ones (e.g., `Vec<i32>`, etc.).

This mainly comes into play concerning deserialization, where the
reflection deserializers both return a `Box<dyn Reflect>` that almost
always contain one of these Dynamic representations of a Real type. To
convert this to our Real type, we need to use `FromReflect`.

It also sneaks up in other ways. For example, it's a required bound for
`T` in `Vec<T>` so that `Vec<T>` as a whole can be made `FromReflect`.
It's also required by all fields of an enum as it's used as part of the
`Reflect::apply` implementation.

So in other words, much like `GetTypeRegistration` and `Typed`, it is
very much a core reflection trait.

The problem is that it is not currently treated like a core trait and is
not automatically derived alongside `Reflect`. This makes using it a bit
cumbersome and easy to forget.

## Solution

Automatically derive `FromReflect` when deriving `Reflect`.

Users can then choose to opt-out if needed using the
`#[reflect(from_reflect = false)]` attribute.

```rust
#[derive(Reflect)]
struct Foo;

#[derive(Reflect)]
#[reflect(from_reflect = false)]
struct Bar;

fn test<T: FromReflect>(value: T) {}

test(Foo); // <-- OK
test(Bar); // <-- Panic! Bar does not implement trait `FromReflect`
```

#### `ReflectFromReflect`

This PR also automatically adds the `ReflectFromReflect` (introduced in
#6245) registration to the derived `GetTypeRegistration` impl— if the
type hasn't opted out of `FromReflect` of course.

<details>
<summary><h4>Improved Deserialization</h4></summary>

> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.

And since we can do all the above, we might as well improve
deserialization. We can now choose to deserialize into a Dynamic type or
automatically convert it using `FromReflect` under the hood.

`[Un]TypedReflectDeserializer::new` will now perform the conversion and
return the `Box`'d Real type.

`[Un]TypedReflectDeserializer::new_dynamic` will work like what we have
now and simply return the `Box`'d Dynamic type.

```rust
// Returns the Real type
let reflect_deserializer = UntypedReflectDeserializer::new(&registry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;

let output: SomeStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;

// Returns the Dynamic type
let reflect_deserializer = UntypedReflectDeserializer::new_dynamic(&registry);
let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;

let output: DynamicStruct = reflect_deserializer.deserialize(&mut deserializer)?.take()?;
```

</details>

---

## Changelog

* `FromReflect` is now automatically derived within the `Reflect` derive
macro
* This includes auto-registering `ReflectFromReflect` in the derived
`GetTypeRegistration` impl
* ~~Renamed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic`, respectively~~ **Descoped**
* ~~Changed `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` to automatically convert the
deserialized output using `FromReflect`~~ **Descoped**

## Migration Guide

* `FromReflect` is now automatically derived within the `Reflect` derive
macro. Items with both derives will need to remove the `FromReflect`
one.

  ```rust
  // OLD
  #[derive(Reflect, FromReflect)]
  struct Foo;
  
  // NEW
  #[derive(Reflect)]
  struct Foo;
  ```

If using a manual implementation of `FromReflect` and the `Reflect`
derive, users will need to opt-out of the automatic implementation.

  ```rust
  // OLD
  #[derive(Reflect)]
  struct Foo;
  
  impl FromReflect for Foo {/* ... */}
  
  // NEW
  #[derive(Reflect)]
  #[reflect(from_reflect = false)]
  struct Foo;
  
  impl FromReflect for Foo {/* ... */}
  ```

<details>
<summary><h4>Removed Migrations</h4></summary>

> **Warning**
> This section includes changes that have since been descoped from this
PR. They will likely be implemented again in a followup PR. I am mainly
leaving these details in for archival purposes, as well as for reference
when implementing this logic again.

* The reflect deserializers now perform a `FromReflect` conversion
internally. The expected output of `TypedReflectDeserializer::new` and
`UntypedReflectDeserializer::new` is no longer a Dynamic (e.g.,
`DynamicList`), but its Real counterpart (e.g., `Vec<i32>`).

  ```rust
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(&registry);
  let mut deserializer = ron:🇩🇪:Deserializer::from_str(input)?;
  
  // OLD
let output: DynamicStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
  
  // NEW
let output: SomeStruct = reflect_deserializer.deserialize(&mut
deserializer)?.take()?;
  ```

Alternatively, if this behavior isn't desired, use the
`TypedReflectDeserializer::new_dynamic` and
`UntypedReflectDeserializer::new_dynamic` methods instead:

  ```rust
  // OLD
  let reflect_deserializer = UntypedReflectDeserializer::new(&registry);
  
  // NEW
let reflect_deserializer =
UntypedReflectDeserializer::new_dynamic(&registry);
  ```

</details>

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-06-29 01:31:34 +00:00
Nicola Papale
0294bb191d
Move AppTypeRegistry to bevy_ecs (#8901)
# Objective

- Use `AppTypeRegistry` on API defined in `bevy_ecs`
(https://github.com/bevyengine/bevy/pull/8895#discussion_r1234748418)

A lot of the API on `Reflect` depends on a registry. When it comes to
the ECS. We should use `AppTypeRegistry` in the general case.

This is however impossible in `bevy_ecs`, since `AppTypeRegistry` is
defined in `bevy_app`.

## Solution

- Move `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`
- Still add the resource in the `App` plugin, since bevy_ecs itself
doesn't know of plugins

Note that `bevy_ecs` is a dependency of `bevy_app`, so nothing
revolutionary happens.

## Alternative

- Define the API as a trait in `bevy_app` over `bevy_ecs`. (though this
prevents us from using bevy_ecs internals)
- Do not rely on `AppTypeRegistry` for the API in question, requring
users to extract themselves the resource and pass it to the API methods.

---

## Changelog

- Moved `AppTypeRegistry` resource definition from `bevy_app` to
`bevy_ecs`

## Migration Guide

- If you were **not** using a `prelude::*` to import `AppTypeRegistry`,
you should update your imports:

```diff
- use bevy::app::AppTypeRegistry;
+ use bevy::ecs::reflect::AppTypeRegistry
```
2023-06-21 17:25:01 +00:00
Nicola Papale
28e9c522f7
Make function pointers of ecs Reflect* public (#8687)
Repetitively fetching ReflectResource and ReflectComponent from the
TypeRegistry is costly.

We want to access the underlying `fn`s. to do so, we expose the
`ReflectResourceFns` and `ReflectComponentFns` stored in ReflectResource
and ReflectComponent.

---

## Changelog

- Add the `fn_pointers` methods to `ReflectResource` and
`ReflectComponent` returning the underlying `ReflectResourceFns` and
`ReflectComponentFns`
2023-06-19 14:06:58 +00:00
Nicola Papale
08962f1e50
Split the bevy_ecs reflect.rs module (#8834)
# Objective

- Cleanup the `reflect.rs` file in `bevy_ecs`, it's very large and can
get difficult to navigate

## Solution

- Split the file into 3 modules, re-export the types in the
`reflect/mod.rs` to keep a perfectly identical API.
- Add **internal** architecture doc explaining how `ReflectComponent`
works. Note that this doc is internal only, since `component.rs` is not
exposed publicly.

### Tips to reviewers

To review this change properly, you need to compare it to the previous
version of `reflect.rs`. The diff from this PR does not help at all!
What you will need to do is compare `reflect.rs` individually with each
newly created file.

Here is how I did it:

- Adding my fork as remote `git remote add nicopap
https://github.com/nicopap/bevy.git`
- Checkout out the branch `git checkout nicopap/split_ecs_reflect`
- Checkout the old `reflect.rs` by running `git checkout HEAD~1 --
crates/bevy_ecs/src/reflect.rs`
- Compare the old with the new with `git diff --no-index
crates/bevy_ecs/src/reflect.rs crates/bevy_ecs/src/reflect/component.rs`

You could also concatenate everything into a single file and compare
against it:

- `cat
crates/bevy_ecs/src/reflect/{component,resource,map_entities,mod}.rs >
new_reflect.rs`
- `git diff --no-index  crates/bevy_ecs/src/reflect.rs new_reflect.rs`
2023-06-18 23:43:10 +00:00