2020-11-28 00:39:59 +00:00
|
|
|
[package]
|
|
|
|
name = "bevy_reflect"
|
2024-07-08 12:54:08 +00:00
|
|
|
version = "0.15.0-dev"
|
2021-10-27 00:12:14 +00:00
|
|
|
edition = "2021"
|
2020-11-28 00:39:59 +00:00
|
|
|
description = "Dynamically interact with rust types"
|
|
|
|
homepage = "https://bevyengine.org"
|
|
|
|
repository = "https://github.com/bevyengine/bevy"
|
2021-07-23 21:11:51 +00:00
|
|
|
license = "MIT OR Apache-2.0"
|
2020-11-28 00:39:59 +00:00
|
|
|
keywords = ["bevy"]
|
2024-11-17 09:38:13 +00:00
|
|
|
rust-version = "1.81.0"
|
2020-11-28 00:39:59 +00:00
|
|
|
|
|
|
|
[features]
|
2024-12-05 21:15:21 +00:00
|
|
|
default = ["std", "smallvec", "debug"]
|
|
|
|
std = [
|
|
|
|
"bevy_utils/std",
|
|
|
|
"erased-serde/std",
|
|
|
|
"downcast-rs/std",
|
|
|
|
"serde/std",
|
|
|
|
"spin/std",
|
|
|
|
"glam?/std",
|
|
|
|
"smol_str?/std",
|
|
|
|
"uuid?/std",
|
|
|
|
]
|
2023-06-08 20:33:21 +00:00
|
|
|
# When enabled, provides Bevy-related reflection implementations
|
2024-05-27 14:15:22 +00:00
|
|
|
bevy = ["smallvec", "smol_str"]
|
2024-01-28 14:55:30 +00:00
|
|
|
glam = ["dep:glam"]
|
2024-12-05 21:15:21 +00:00
|
|
|
petgraph = ["dep:petgraph", "std"]
|
2024-03-07 02:30:15 +00:00
|
|
|
smallvec = ["dep:smallvec"]
|
|
|
|
uuid = ["dep:uuid"]
|
2024-12-05 21:15:21 +00:00
|
|
|
wgpu-types = ["dep:wgpu-types", "std"]
|
bevy_reflect: Contextual serialization error messages (#13888)
# Objective
Reflection serialization can be difficult to debug. A lot of times a
type fails to be serialized and the user is left wondering where that
type came from.
This is most often encountered with Bevy's scenes. Attempting to
serialize all resources in the world will fail because some resources
can't be serialized.
For example, users will often get complaints about `bevy_utils::Instant`
not registering `ReflectSerialize`. Well, `Instant` can't be serialized,
so the only other option is to exclude the resource that contains it.
But what resource contains it? This is where reflection serialization
can get a little tricky (it's `Time<Real>` btw).
## Solution
Add the `debug_stack` feature to `bevy_reflect`. When enabled, the
reflection serializers and deserializers will keep track of the current
type stack. And this stack will be used in error messages to help with
debugging.
Now, if we unknowingly try to serialize `Time<Real>`, we'll get the
following error:
```
type `bevy_utils::Instant` did not register the `ReflectSerialize` type data. For certain types, this may need to be registered manually using `register_type_data` (stack: `bevy_time::time::Time<bevy_time::real::Real>` -> `bevy_time::real::Real` -> `bevy_utils::Instant`)
```
### Implementation
This makes use of `thread_local!` to manage an internal `TypeInfoStack`
which holds a stack of `&'static TypeInfo`. We push to the stack before
a type is (de)serialized and pop from the stack afterwards.
Using a thread-local should be fine since we know two (de)serializers
can't be running at the same time (and if they're running on separate
threads, then we're still good).
The only potential issue would be if a user went through one of the
sub-serializers, like `StructSerializer`. However, I don't think many
users are going through these types (I don't even know if we necessarily
want to keep those public either, but we'll save that for a different
PR). Additionally, this is just a debug feature that only affects error
messages, so it wouldn't have any drastically negative effect. It would
just result in the stack not being cleared properly if there were any
errors.
Lastly, this is not the most performant implementation since we now
fetch the `TypeInfo` an extra time. But I figured that for a debug tool,
it wouldn't matter too much.
### Feature
This also adds a `debug` feature, which enables the `debug_stack`
feature.
I added it because I think we may want to potentially add more debug
tools in the future, and this gives us a good framework for adding
those. Users who want all debug features, present and future, can just
set `debug`. If they only want this feature, then they can just use
`debug_stack`.
I also made the `debug` feature default to help capture the widest
audience (i.e. the users who want this feature but don't know they do).
However, if we think it's better as a non-default feature, I can change
it!
And if there's any bikeshedding around the name `debug_stack`, let me
know!
## Testing
Run the following command:
```
cargo test --package bevy_reflect --features debug_stack
```
---
## Changelog
- Added the `debug` and `debug_stack` features to `bevy_reflect`
- Updated the error messages returned by the reflection serializers and
deserializers to include more contextual information when the
`debug_stack` or `debug` feature is enabled
2024-09-09 17:52:40 +00:00
|
|
|
# Enables features useful for debugging reflection
|
|
|
|
debug = ["debug_stack"]
|
|
|
|
# When enabled, keeps track of the current serialization/deserialization context for better error messages
|
|
|
|
debug_stack = []
|
2022-10-18 13:49:57 +00:00
|
|
|
# When enabled, allows documentation comments to be accessed via reflection
|
|
|
|
documentation = ["bevy_reflect_derive/documentation"]
|
2024-07-14 15:55:31 +00:00
|
|
|
# Enables function reflection
|
|
|
|
functions = ["bevy_reflect_derive/functions"]
|
2020-11-28 00:39:59 +00:00
|
|
|
|
|
|
|
[dependencies]
|
|
|
|
# bevy
|
2024-07-08 12:54:08 +00:00
|
|
|
bevy_reflect_derive = { path = "derive", version = "0.15.0-dev" }
|
2024-12-05 21:15:21 +00:00
|
|
|
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev", default-features = false, features = [
|
|
|
|
"alloc",
|
|
|
|
] }
|
2024-07-08 12:54:08 +00:00
|
|
|
bevy_ptr = { path = "../bevy_ptr", version = "0.15.0-dev" }
|
2020-11-28 00:39:59 +00:00
|
|
|
|
2024-12-10 19:45:50 +00:00
|
|
|
# used by bevy-utils, but it also needs reflect impls
|
|
|
|
foldhash = { version = "0.1.3", default-features = false }
|
|
|
|
|
2020-11-28 00:39:59 +00:00
|
|
|
# other
|
2024-12-05 21:15:21 +00:00
|
|
|
erased-serde = { version = "0.4", default-features = false, features = [
|
|
|
|
"alloc",
|
|
|
|
] }
|
|
|
|
disqualified = { version = "1.0", default-features = false }
|
|
|
|
downcast-rs = { version = "1.2", default-features = false }
|
2024-12-06 17:03:55 +00:00
|
|
|
thiserror = { version = "2", default-features = false }
|
|
|
|
derive_more = { version = "1", default-features = false, features = ["from"] }
|
2024-12-05 21:15:21 +00:00
|
|
|
serde = { version = "1", default-features = false, features = ["alloc"] }
|
|
|
|
spin = { version = "0.9.8", default-features = false, features = [
|
|
|
|
"once",
|
|
|
|
"rwlock",
|
|
|
|
] }
|
bevy_reflect: Update `EulerRot` to match `glam` 0.29 (#15402)
# Objective
#15349 added an `impl_reflect!` for `glam::EulerRot`. This was done by
copying and pasting the enum definition from `glam` into `bevy_reflect`
so that the macro could interpret the variants.
However, as mentioned in the description for that PR, this would need to
be updated for `glam` 0.29, as it had not been updated yet.
#15249 came and updated `glam` to 0.29, but did not change these impls.
This is understandable as failing to do so doesn't cause any compile
errors.
This PR updates the definition and aims to make this silent breakage a
little less silent.
## Solution
Firstly, I updated the definition for `EulerRot` to match the one from
`glam`.
Secondly, I added the `assert_type_match` crate, which I created
specifically to solve this problem. By using this crate, we'll get a
compile time error if `glam` ever decides to change `EulerRot` again.
In the future we can consider using it for other types with this
problem, including in other crates (I'm pretty sure `bevy_window` and/or
`bevy_winit` also copy+paste some types). I made sure to use as few
dependencies as possible so everything should already be in-tree (it's
just `quote`, `proc-macro2`, and `syn` with default features).
## Testing
No tests added. CI should pass.
---
## Migration Guide
The reflection implementation for `EulerRot` has been updated to align
with `glam` 0.29. Please update any reflection-based usages accordingly.
2024-09-23 22:50:12 +00:00
|
|
|
assert_type_match = "0.1.1"
|
2023-12-24 15:35:09 +00:00
|
|
|
|
2024-12-05 21:15:21 +00:00
|
|
|
smallvec = { version = "1.11", default-features = false, optional = true }
|
|
|
|
glam = { version = "0.29", default-features = false, features = [
|
|
|
|
"serde",
|
|
|
|
], optional = true }
|
Implement the `AnimationGraph`, allowing for multiple animations to be blended together. (#11989)
This is an implementation of RFC #51:
https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md
Note that the implementation strategy is different from the one outlined
in that RFC, because two-phase animation has now landed.
# Objective
Bevy needs animation blending. The RFC for this is [RFC 51].
## Solution
This is an implementation of the RFC. Note that the implementation
strategy is different from the one outlined there, because two-phase
animation has now landed.
This is just a draft to get the conversation started. Currently we're
missing a few things:
- [x] A fully-fleshed-out mechanism for transitions
- [x] A serialization format for `AnimationGraph`s
- [x] Examples are broken, other than `animated_fox`
- [x] Documentation
---
## Changelog
### Added
* The `AnimationPlayer` has been reworked to support blending multiple
animations together through an `AnimationGraph`, and as such will no
longer function unless a `Handle<AnimationGraph>` has been added to the
entity containing the player. See [RFC 51] for more details.
* Transition functionality has moved from the `AnimationPlayer` to a new
component, `AnimationTransitions`, which works in tandem with the
`AnimationGraph`.
## Migration Guide
* `AnimationPlayer`s can no longer play animations by themselves and
need to be paired with a `Handle<AnimationGraph>`. Code that was using
`AnimationPlayer` to play animations will need to create an
`AnimationGraph` asset first, add a node for the clip (or clips) you
want to play, and then supply the index of that node to the
`AnimationPlayer`'s `play` method.
* The `AnimationPlayer::play_with_transition()` method has been removed
and replaced with the `AnimationTransitions` component. If you were
previously using `AnimationPlayer::play_with_transition()`, add all
animations that you were playing to the `AnimationGraph`, and create an
`AnimationTransitions` component to manage the blending between them.
[RFC 51]:
https://github.com/bevyengine/rfcs/blob/main/rfcs/51-animation-composition.md
---------
Co-authored-by: Rob Parrett <robparrett@gmail.com>
2024-03-07 20:22:42 +00:00
|
|
|
petgraph = { version = "0.6", features = ["serde-1"], optional = true }
|
2024-12-05 21:15:21 +00:00
|
|
|
smol_str = { version = "0.2.0", default-features = false, features = [
|
|
|
|
"serde",
|
|
|
|
], optional = true }
|
|
|
|
uuid = { version = "1.0", default-features = false, optional = true, features = [
|
|
|
|
"v4",
|
|
|
|
"serde",
|
|
|
|
] }
|
2024-12-03 17:41:09 +00:00
|
|
|
variadics_please = "1.0"
|
2024-11-05 21:18:48 +00:00
|
|
|
wgpu-types = { version = "23", features = ["serde"], optional = true }
|
2020-11-28 00:39:59 +00:00
|
|
|
|
|
|
|
[dev-dependencies]
|
2022-09-02 14:20:49 +00:00
|
|
|
ron = "0.8.0"
|
bevy_reflect: Binary formats (#6140)
# Objective
Closes #5934
Currently it is not possible to de/serialize data to non-self-describing formats using reflection.
## Solution
Add support for non-self-describing de/serialization using reflection.
This allows us to use binary formatters, like [`postcard`](https://crates.io/crates/postcard):
```rust
#[derive(Reflect, FromReflect, Debug, PartialEq)]
struct Foo {
data: String
}
let mut registry = TypeRegistry::new();
registry.register::<Foo>();
let input = Foo {
data: "Hello world!".to_string()
};
// === Serialize! === //
let serializer = ReflectSerializer::new(&input, ®istry);
let bytes: Vec<u8> = postcard::to_allocvec(&serializer).unwrap();
println!("{:?}", bytes); // Output: [129, 217, 61, 98, ...]
// === Deserialize! === //
let deserializer = UntypedReflectDeserializer::new(®istry);
let dynamic_output = deserializer
.deserialize(&mut postcard::Deserializer::from_bytes(&bytes))
.unwrap();
let output = <Foo as FromReflect>::from_reflect(dynamic_output.as_ref()).unwrap();
assert_eq!(expected, output); // OK!
```
#### Crates Tested
- ~~[`rmp-serde`](https://crates.io/crates/rmp-serde)~~ Apparently, this _is_ self-describing
- ~~[`bincode` v2.0.0-rc.1](https://crates.io/crates/bincode/2.0.0-rc.1) (using [this PR](https://github.com/bincode-org/bincode/pull/586))~~ This actually works for the latest release (v1.3.3) of [`bincode`](https://crates.io/crates/bincode) as well. You just need to be sure to use fixed-int encoding.
- [`postcard`](https://crates.io/crates/postcard)
## Future Work
Ideally, we would refactor the `serde` module, but I don't think I'll do that in this PR so as to keep the diff relatively small (and to avoid any painful rebases). This should probably be done once this is merged, though.
Some areas we could improve with a refactor:
* Split deserialization logic across multiple files
* Consolidate helper functions/structs
* Make the logic more DRY
---
## Changelog
- Add support for non-self-describing de/serialization using reflection.
Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2022-11-04 02:22:54 +00:00
|
|
|
rmp-serde = "1.1"
|
|
|
|
bincode = "1.3"
|
2023-11-23 14:04:51 +00:00
|
|
|
serde_json = "1.0"
|
|
|
|
serde = { version = "1", features = ["derive"] }
|
2024-01-18 17:21:18 +00:00
|
|
|
static_assertions = "1.1.0"
|
2022-10-18 13:49:57 +00:00
|
|
|
|
|
|
|
[[example]]
|
|
|
|
name = "reflect_docs"
|
|
|
|
path = "examples/reflect_docs.rs"
|
|
|
|
required-features = ["documentation"]
|
2023-11-18 20:58:48 +00:00
|
|
|
|
|
|
|
[lints]
|
|
|
|
workspace = true
|
2024-03-08 20:03:09 +00:00
|
|
|
|
|
|
|
[package.metadata.docs.rs]
|
2024-07-29 23:10:16 +00:00
|
|
|
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
|
2024-03-08 20:03:09 +00:00
|
|
|
all-features = true
|