use std::marker::PhantomData;
use bevy::prelude::*;
use serde::{
Deserialize,
Serialize,
de::DeserializeSeed,
};
pub trait CaptureInput<P> {
type Builder: 'static;
fn builder(pathway: &P, world: &World) -> Self::Builder;
fn build(builder: Self::Builder, pathway: &P, world: &World) -> Self;
}
pub trait CaptureOutput<P>: Sized {
type Builder: 'static;
type Error;
fn builder(self, pathway: &P, world: &mut World) -> Self::Builder;
fn build(builder: Self::Builder, pathway: &P, world: &mut World) -> Result<Self, Self::Error>;
}
pub trait CaptureSerialize {
type Value<'a>: Serialize + Send + Sync
where
Self: 'a;
fn value<'a>(&'a self, world: &'a World) -> Self::Value<'a>;
}
pub trait CaptureDeserialize {
type Seed<'a>: for<'de> DeserializeSeed<'de, Value = Self> + Send + Sync;
fn seed(world: &World) -> Self::Seed<'_>;
}
impl<T, P> CaptureInput<P> for T
where
T: Default + 'static,
{
type Builder = T;
fn builder(_pathway: &P, _world: &World) -> Self::Builder {
T::default()
}
fn build(builder: Self::Builder, _pathway: &P, _world: &World) -> Self {
builder
}
}
impl<T, P> CaptureOutput<P> for T
where
T: Default + 'static,
{
type Builder = T;
type Error = ();
fn builder(self, _pathway: &P, _world: &mut World) -> Self::Builder {
self
}
fn build(
builder: Self::Builder,
_pathway: &P,
_world: &mut World,
) -> Result<Self, Self::Error> {
Ok(builder)
}
}
impl<T> CaptureSerialize for T
where
T: Serialize + Send + Sync,
{
type Value<'a>
= &'a T
where
T: 'a;
fn value<'a>(&'a self, _world: &'a World) -> Self::Value<'a> {
self
}
}
impl<T> CaptureDeserialize for T
where
T: for<'de> Deserialize<'de> + Send + Sync,
{
type Seed<'a> = PhantomData<T>;
fn seed(_world: &World) -> Self::Seed<'_> {
PhantomData
}
}
#[cfg(feature = "reflect")]
mod reflect {
use bevy::prelude::*;
use crate::{
prelude::*,
reflect::{
SnapshotDeserializerArc,
SnapshotSerializerArc,
},
};
impl<P> CaptureInput<P> for Snapshot {
type Builder = Builder;
fn builder(_pathway: &P, _world: &World) -> Self::Builder {
Builder::new()
}
fn build(builder: Self::Builder, _pathway: &P, _world: &World) -> Self {
builder.build()
}
}
impl<P> CaptureOutput<P> for Snapshot {
type Builder = Applier<'static>;
type Error = Error;
fn builder(self, _pathway: &P, _world: &mut World) -> Self::Builder {
Applier::new(self)
}
fn build(
builder: Self::Builder,
_pathway: &P,
world: &mut World,
) -> Result<Self, Self::Error> {
let mut applier = ApplierRef::from_parts(world, builder);
applier.apply()?;
Ok(applier
.into_inner()
.snapshot
.try_into_owned()
.expect("Invalid input"))
}
}
impl CaptureSerialize for Snapshot {
type Value<'a>
= SnapshotSerializerArc<'a>
where
Self: 'a;
fn value<'a>(&'a self, world: &'a World) -> Self::Value<'a> {
SnapshotSerializerArc::new(self, world.resource::<AppTypeRegistry>().clone().0)
}
}
impl CaptureDeserialize for Snapshot {
type Seed<'a> = SnapshotDeserializerArc;
fn seed(world: &World) -> Self::Seed<'_> {
SnapshotDeserializerArc::new(world.resource::<AppTypeRegistry>().clone().0)
}
}
}