use std::any::Any;
use bevy::prelude::*;
use crate::{
prelude::*,
reflect::checkpoint::{
CheckpointRegistry,
Checkpoints,
},
};
pub trait AppCheckpointExt {
fn allow_checkpoint<T: Any>(&mut self) -> &mut Self;
fn deny_checkpoint<T: Any>(&mut self) -> &mut Self;
}
impl AppCheckpointExt for App {
fn allow_checkpoint<T: Any>(&mut self) -> &mut Self {
self.world_mut()
.resource_mut::<CheckpointRegistry>()
.allow::<T>();
self
}
fn deny_checkpoint<T: Any>(&mut self) -> &mut Self {
self.world_mut()
.resource_mut::<CheckpointRegistry>()
.deny::<T>();
self
}
}
pub trait WorldCheckpointExt {
fn checkpoint<P>(&mut self, pathway: &P)
where
P: Pathway<
Capture: CaptureInput<P, Builder: Into<Builder> + From<Builder>> + Into<Snapshot>,
>;
fn rollback<P>(&mut self, pathway: &P, checkpoints: isize) -> Result<(), Error>
where
P: Pathway<Capture: CaptureOutput<P> + From<Snapshot>>;
}
impl WorldCheckpointExt for World {
fn checkpoint<P>(&mut self, pathway: &P)
where
P: Pathway<
Capture: CaptureInput<P, Builder: Into<Builder> + From<Builder>> + Into<Snapshot>,
>,
{
let builder = P::Capture::builder(pathway, self).into().into_checkpoint();
let rollback = self.capture_with(pathway, builder.into());
self.resource_mut::<Checkpoints>()
.checkpoint(rollback.into());
}
fn rollback<P>(&mut self, pathway: &P, checkpoints: isize) -> Result<(), Error>
where
P: Pathway<Capture: CaptureOutput<P> + From<Snapshot>>,
{
if let Some(rollback) = self
.resource_mut::<Checkpoints>()
.rollback(checkpoints)
.cloned()
{
self.apply(pathway, rollback.into()).map(|_| ())
} else {
Ok(())
}
}
}