Skip to content

Commit

Permalink
Added Copy Snapshot Plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
bushrat011899 committed Oct 21, 2023
1 parent b8358bb commit b4f86c7
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 0 deletions.
84 changes: 84 additions & 0 deletions src/snapshot/component_copy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use crate::{
GgrsComponentSnapshot, GgrsSnapshots, LoadWorld, LoadWorldSet, Rollback, RollbackFrameCount,
SaveWorld, SaveWorldSet,
};
use bevy::prelude::*;
use std::marker::PhantomData;

/// A [`Plugin`] which manages snapshots for a [`Component`] `C` using [`Copy`].
pub struct GgrsComponentSnapshotCopyPlugin<C>
where
C: Component + Copy,
{
_phantom: PhantomData<C>,
}

type Snapshots<C> = GgrsSnapshots<C, GgrsComponentSnapshot<C>>;

impl<C> Default for GgrsComponentSnapshotCopyPlugin<C>
where
C: Component + Copy,
{
fn default() -> Self {
Self {
_phantom: Default::default(),
}
}
}

impl<C> GgrsComponentSnapshotCopyPlugin<C>
where
C: Component + Copy,
{
pub fn save(
mut snapshots: ResMut<Snapshots<C>>,
frame: Res<RollbackFrameCount>,
query: Query<(&Rollback, &C)>,
) {
let components = query
.iter()
.map(|(&rollback, &component)| (rollback, component));
let snapshot = GgrsComponentSnapshot::new(components);
snapshots.push(frame.0, snapshot);
}

pub fn load(
mut commands: Commands,
mut snapshots: ResMut<Snapshots<C>>,
frame: Res<RollbackFrameCount>,
mut query: Query<(Entity, &Rollback, Option<&mut C>)>,
) {
let snapshot = snapshots.rollback(frame.0).get();

for (entity, rollback, component) in query.iter_mut() {
let snapshot = snapshot.get(rollback);

match (component, snapshot) {
(Some(mut component), Some(snapshot)) => *component = *snapshot,
(Some(_), None) => {
commands.entity(entity).remove::<C>();
}
(None, Some(snapshot)) => {
commands.entity(entity).insert(*snapshot);
}
(None, None) => {}
}
}
}
}

impl<C> Plugin for GgrsComponentSnapshotCopyPlugin<C>
where
C: Component + Copy,
{
fn build(&self, app: &mut App) {
app.init_resource::<Snapshots<C>>()
.add_systems(
SaveWorld,
(Snapshots::<C>::discard_old_snapshots, Self::save)
.chain()
.in_set(SaveWorldSet::Snapshot),
)
.add_systems(LoadWorld, Self::load.in_set(LoadWorldSet::Data));
}
}
4 changes: 4 additions & 0 deletions src/snapshot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@ use std::{collections::VecDeque, marker::PhantomData};
mod checksum;
mod component_checksum_hash;
mod component_clone;
mod component_copy;
mod component_map;
mod component_reflect;
mod entity;
mod plumbing;
mod resource_checksum_hash;
mod resource_clone;
mod resource_copy;
mod resource_map;
mod resource_reflect;
mod rollback_entity_map;

pub use checksum::*;
pub use component_checksum_hash::*;
pub use component_clone::*;
pub use component_copy::*;
pub use component_map::*;
pub use component_reflect::*;
pub use entity::*;
pub use plumbing::*;
pub use resource_checksum_hash::*;
pub use resource_clone::*;
pub use resource_copy::*;
pub use resource_map::*;
pub use resource_reflect::*;
pub use rollback_entity_map::*;
Expand Down
69 changes: 69 additions & 0 deletions src/snapshot/resource_copy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use crate::{GgrsSnapshots, LoadWorld, LoadWorldSet, RollbackFrameCount, SaveWorld, SaveWorldSet};
use bevy::prelude::*;
use std::marker::PhantomData;

/// A [`Plugin`] which manages snapshots for a [`Resource`] `R` using [`Copy`].
pub struct GgrsResourceSnapshotCopyPlugin<R>
where
R: Resource + Copy,
{
_phantom: PhantomData<R>,
}

type Snapshots<R> = GgrsSnapshots<R, Option<R>>;

impl<R> Default for GgrsResourceSnapshotCopyPlugin<R>
where
R: Resource + Copy,
{
fn default() -> Self {
Self {
_phantom: Default::default(),
}
}
}

impl<R> GgrsResourceSnapshotCopyPlugin<R>
where
R: Resource + Copy,
{
pub fn save(
mut snapshots: ResMut<Snapshots<R>>,
frame: Res<RollbackFrameCount>,
resource: Option<Res<R>>,
) {
snapshots.push(frame.0, resource.map(|res| *res));
}

pub fn load(
mut commands: Commands,
mut snapshots: ResMut<Snapshots<R>>,
frame: Res<RollbackFrameCount>,
resource: Option<ResMut<R>>,
) {
let snapshot = snapshots.rollback(frame.0).get();

match (resource, snapshot) {
(Some(mut resource), Some(snapshot)) => *resource = *snapshot,
(Some(_), None) => commands.remove_resource::<R>(),
(None, Some(snapshot)) => commands.insert_resource(*snapshot),
(None, None) => {}
}
}
}

impl<R> Plugin for GgrsResourceSnapshotCopyPlugin<R>
where
R: Resource + Copy,
{
fn build(&self, app: &mut App) {
app.init_resource::<Snapshots<R>>()
.add_systems(
SaveWorld,
(Snapshots::<R>::discard_old_snapshots, Self::save)
.chain()
.in_set(SaveWorldSet::Snapshot),
)
.add_systems(LoadWorld, Self::load.in_set(LoadWorldSet::Data));
}
}

0 comments on commit b4f86c7

Please sign in to comment.