Conversation
|
I remember writing a ggrs rapier demo at some point in the past, where I had to serialize the Is there a way users can add this plugin themselves without it being distributed as part of this crate? What do you think @johanhelsing ? |
5866f1a to
1dd9a5a
Compare
Oh yes, that's why I was so excited to have the use std::marker::PhantomData;
use postcard::{from_bytes, to_allocvec};
use serde::{de::DeserializeOwned, Serialize};
use crate::Strategy;
/// A [`Strategy`] based on [`Reflect`] and [`FromWorld`]
pub struct PostcardStrategy<T: Serialize + DeserializeOwned>(PhantomData<T>);
impl<T: Serialize + DeserializeOwned> Strategy for PostcardStrategy<T> {
type Target = T;
type Stored = Vec<u8>;
#[inline(always)]
fn store(target: &Self::Target) -> Self::Stored {
to_allocvec(target).unwrap()
}
#[inline(always)]
fn load(stored: &Self::Stored) -> Self::Target {
from_bytes(stored).unwrap()
}
}
// ...
app.add_plugins(ComponentSnapshotPlugin::<PostcardStrategy<RapierContext>>::default());Where the only type imported is the public |
johanhelsing
left a comment
There was a problem hiding this comment.
I think it could be useful to have this for cases like the rapier serialization.
Cargo.toml
Outdated
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
|
||
| [features] | ||
| default = ["serde"] |
There was a problem hiding this comment.
Perhaps not enable it by default? Does bevy depend on serde or postcard?
There was a problem hiding this comment.
Good point! I've had a look through bevy, matchbox (with ggrs feature enabled), and ggrs. Out of those three crates, serde version 1 is always included, ron version 0.8 is included (from bevy), and bincode is included (matchbox and ggrs)
I've updated this PR to use ron and bincode instead, as they are already in the dependency graph. I've still kept them behind feature flags so you can remove them if desired.
459437f to
0eb4128
Compare
0eb4128 to
f30a67a
Compare
|
Just wanted to call-out here that while this strategy is cool and could be very useful for integrating with Rapier directly via your own There are several I am curious to know how you've handled this case. For me, I've settled on creating N "blessed entities" and initializing Rapier with all of them, promising myself I can only rollback those N entities. Later, I will do all the (de)serializing directly and then only updating the appropriate properties on the ( |
Objective
In my personal project, I've hit an issue where the Rapier library has a large state object,
RapierContext, which cannot be cloned, copied, or reflected for snapshotting. However, it does implement SerdeSerialize + Deserialize. It would be convenient and broadly applicable if snapshots natively supported Serde.Solution
I've created an optional snapshot strategy using Serde and Postcard, gated by the newly added
serdefeature:Notes
I haven't done extensive performance testing with this strategy, but I think it's a safe bet it's probably the slowest. This is why I've chosen Postcard as the target format for de/serialization, as it is designed for embedded
no-stduse, where performance would be highly valued.I also don't believe Rapier requires this addition to work, and this could also be added by an end user entirely through the current public API. However, I can imagine many others potentially reaching for this functionality, and I wrote it for myself, so I figured I might as well offer it here as well!
Finally, I've made this branch based off of my #83 for testing purposes, but these changes could be easily ported to any alternate Bevy 0.12 upgrade branch as required.