https://github.com/mintlu8/bevy_serde_lens
Stateful, structural and pretty serialization framework for the bevy engine.
https://github.com/mintlu8/bevy_serde_lens
bevy rust save serde serialization
Last synced: 3 months ago
JSON representation
Stateful, structural and pretty serialization framework for the bevy engine.
- Host: GitHub
- URL: https://github.com/mintlu8/bevy_serde_lens
- Owner: mintlu8
- License: apache-2.0
- Created: 2024-02-28T20:20:33.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-25T22:18:02.000Z (about 1 year ago)
- Last Synced: 2024-04-25T22:32:46.958Z (about 1 year ago)
- Topics: bevy, rust, save, serde, serialization
- Language: Rust
- Homepage:
- Size: 85 KB
- Stars: 9
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# bevy_serde_lens
[](https://crates.io/crates/bevy_serde_lens)
[](https://docs.rs/bevy_serde_lens/latest/bevy_serde_lens/)
[](https://bevyengine.org/learn/book/plugin-development/)Blazingly fast, schema based and human-readable serialization crate for the bevy engine.
## Features
* Stateful serialization and deserialization with world access.
* No systems, no plugins.
* Blazingly fast (compared to `DynamicScene`).
* Treat an `Entity`, its `Component`s and children as a single serde object.
* Deserialize trait objects like `Box`, as an alternative to `typetag`.
* Supports every serde format using familiar syntax.
* Serialize `Handle`s and provide a generalized data interning interface.
* No reflection needed.## Getting Started
Imagine we have a typical `Character` bundle.
First we derive `BevyObject`:
```rust
#[derive(Bundle, BevyObject)]
#[bevy_object(query)]
pub struct Character {
pub transform: Transform,
pub name: Name,
pub position: Position,
pub hp: Hp,
}
```* `#[bevy_object(query)]`
This indicates we are serializing a query instead of a hierarchical tree, which improves performance.
To serialize we simply do:
```rust
serde_json::to_string(&world.serialize_lens::());
```This finds all entities that fits the `QueryFilter` of the bundle and serializes them in an array.
To deserialize we use `deserialize_scope`:
```rust
world.deserialize_scope(|| {
// Returned object doesn't matter, data is stored in the world.
let _ = serde_json::from_str::>(&json_string);
})
```This statement spawns new entities in the world and fills them with deserialized data.
You might want to delete current entities before loading new ones,
to delete all associated entities of a serialization:```rust
// Despawn all character.
world.despawn_bound_objects::()
```To save multiple types of objects in a batch, create a batch serialization type with the `batch!` macro.
```rust
type SaveFile = batch!(
Character, Monster,
// Use `SerializeResource` to serialize a resource.
SerializeResource,
);
world.serialize_lens::()
world.deserialize_scope(|| {
let _ = serde_json::from_str::>(&json_string);
})
world.despawn_bound_objects::()
```This saves each type in a map entry:
```rust
{
"Character": [
{ .. },
{ .. },
..
],
"Monster": [ .. ],
"Terrain": ..
}
```## Advanced Serialization
`BevyObject` is not just a clone of `Bundle`, we support additional types.
* `impl BevyObject`: Components are automatically `BevyObject` and `BevyObject` can contain multiple other `BevyObject`s.
* `Maybe` can be used if an item may or may not exist.
* `DefaultInit` initializes a non-serialize component with `FromWorld`.
* `Child` finds and serializes a single `BevyObject` in children.
* `ChildVec` finds and serializes multiple `BevyObject`s in children.New in 0.5:
* `Child` finds and serializes a single `BevyObject` from a custom children component.
* `ChildVec` finds and serializes multiple `BevyObject`s from a custom children component.See the `BevyObject` derive macro for more details.
```rust
// Note we cannot derive bundle anymore.
// #[bevy_object(query)] also cannot be used due to children being serialized.
#[derive(BevyObject)]
#[bevy_object(rename = "character")]
pub struct Character {
pub transform: Transform,
pub name: Name,
pub position: Position,
pub hp: Hp,
#[serde(default)]
pub weapon: Maybe
#[serde(skip)]
pub cache: DefaultInit,
pub potions: ChildVec
}
```## Stateful Serialization
When using `bevy_serde_lens` you can use `with_world` to access `&World`
in `Serialize` implementations and `with_world_mut` to access `&mut World`
in `Deserialize` implementations.These functions actually comes from `bevy_serde_lens_core`
which is more semver stable and more suited as a dependency for library authors.## Serialize Handles
To serialize a `Handle` as its string path, you can use `#[serde(with = "PathHandle")]`.
To serialize its content, use `#[serde(with = "UniqueHandle")]`.```rust
#[derive(Component, Serialize, Deserialize)]
struct MySprite {
#[serde(with = "PathHandle")]
image: Handle
}
```Or use the newtype directly.
```rust
#[derive(Component, Serialize, Deserialize)]
struct MySprite {
image: PathHandle
}
```## TypeTag
We provide registration based deserialization as an alternative to the `typetag` crate.
See the `typetagged` module for details.## Versions
| bevy | bevy-serde-lens-core | bevy-serde-lens |
|------|----------------------|--------------------|
| 0.13 | - | 0.1-0.3 |
| 0.14 | 0.14 | 0.4 |
| 0.15 | 0.15 | 0.5-latest |## License
Licensed under either of
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or )
* MIT license ([LICENSE-MIT](LICENSE-MIT) or )at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.