Skip to content

Commit

Permalink
Merge pull request #94 from johanhelsing/checksum-hasher
Browse files Browse the repository at this point in the history
Add `checksum_hasher`
  • Loading branch information
johanhelsing authored Dec 20, 2023
2 parents a590afb + 476d1a7 commit fa29e1d
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 19 deletions.
6 changes: 3 additions & 3 deletions examples/stress_tests/particles.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use bevy::{math::vec3, prelude::*, utils::HashMap, window::WindowResolution};
use bevy_ggrs::{prelude::*, LocalInputs, LocalPlayers};
use bevy_ggrs::{checksum_hasher, prelude::*, LocalInputs, LocalPlayers};
use clap::Parser;
use ggrs::{DesyncDetection, UdpNonBlockingSocket};
use rand::{Rng, SeedableRng};
use std::{
hash::{BuildHasher, Hash, Hasher},
hash::{Hash, Hasher},
net::SocketAddr,
};

Expand Down Expand Up @@ -201,7 +201,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.checksum_component_with_hash::<Velocity>()
// ...or you can provide a custom hashing process
.checksum_component::<Transform>(|transform| {
let mut hasher = bevy::utils::FixedState.build_hasher();
let mut hasher = checksum_hasher();

// In this demo we only translate particles, so only that value
// needs to be tracked.
Expand Down
8 changes: 4 additions & 4 deletions src/snapshot/checksum.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::{
hash::{BuildHasher, Hash, Hasher},
hash::{Hash, Hasher},
marker::PhantomData,
};

use bevy::prelude::*;

use crate::{SaveWorld, SaveWorldSet};
use crate::{checksum_hasher, SaveWorld, SaveWorldSet};

/// Flags an entity as containing a checksum for a type `T`
#[derive(Component)]
Expand All @@ -26,9 +26,9 @@ impl<T> Default for ChecksumFlag<T> {
pub struct ChecksumPart(pub u128);

impl ChecksumPart {
/// Converts a provided value `T` into a [Hash] using Bevy's [`FixedState`](`bevy::utils::FixedState`) hasher.
/// Converts a provided value `T` into a [Hash] using [`checksum_hasher`].
pub fn from_value<T: Hash>(value: &T) -> Self {
let mut hasher = bevy::utils::FixedState.build_hasher();
let mut hasher = checksum_hasher();

value.hash(&mut hasher);

Expand Down
10 changes: 6 additions & 4 deletions src/snapshot/component_checksum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::hash::{BuildHasher, Hash, Hasher};
use std::hash::{Hash, Hasher};

use bevy::prelude::*;

use crate::{ChecksumFlag, ChecksumPart, Rollback, RollbackOrdered, SaveWorld, SaveWorldSet};
use crate::{
checksum_hasher, ChecksumFlag, ChecksumPart, Rollback, RollbackOrdered, SaveWorld, SaveWorldSet,
};

/// A [`Plugin`] which will track the [`Component`] `C` on [`Rollback Entities`](`Rollback`) and ensure a
/// [`ChecksumPart`] is available and updated. This can be used to generate a [`Checksum`](`crate::Checksum`).
Expand Down Expand Up @@ -33,7 +35,7 @@ use crate::{ChecksumFlag, ChecksumPart, Rollback, RollbackOrdered, SaveWorld, Sa
pub struct ComponentChecksumPlugin<C: Component>(pub for<'a> fn(&'a C) -> u64);

fn default_hasher<C: Component + Hash>(component: &C) -> u64 {
let mut hasher = bevy::utils::FixedState.build_hasher();
let mut hasher = checksum_hasher();
component.hash(&mut hasher);
hasher.finish()
}
Expand Down Expand Up @@ -64,7 +66,7 @@ where
&mut ChecksumPart,
(Without<Rollback>, With<ChecksumFlag<C>>),
>| {
let mut hasher = bevy::utils::FixedState.build_hasher();
let mut hasher = checksum_hasher();

let mut result = 0;

Expand Down
8 changes: 5 additions & 3 deletions src/snapshot/entity_checksum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::hash::{BuildHasher, Hash, Hasher};
use std::hash::{Hash, Hasher};

use bevy::prelude::*;

use crate::{ChecksumFlag, ChecksumPart, Rollback, RollbackOrdered, SaveWorld, SaveWorldSet};
use crate::{
checksum_hasher, ChecksumFlag, ChecksumPart, Rollback, RollbackOrdered, SaveWorld, SaveWorldSet,
};

pub struct EntityChecksumPlugin;

Expand All @@ -14,7 +16,7 @@ impl EntityChecksumPlugin {
active_entities: Query<&Rollback, (With<Rollback>, Without<ChecksumFlag<Entity>>)>,
mut checksum: Query<&mut ChecksumPart, (Without<Rollback>, With<ChecksumFlag<Entity>>)>,
) {
let mut hasher = bevy::utils::FixedState.build_hasher();
let mut hasher = checksum_hasher();

// The quantity of active rollback entities must be synced.
active_entities.iter().len().hash(&mut hasher);
Expand Down
12 changes: 10 additions & 2 deletions src/snapshot/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{ConfirmedFrameCount, Rollback, DEFAULT_FPS};
use bevy::{prelude::*, utils::HashMap};
use std::{collections::VecDeque, marker::PhantomData};
use bevy::{
prelude::*,
utils::{AHasher, FixedState, HashMap},
};
use std::{collections::VecDeque, hash::BuildHasher, marker::PhantomData};

mod checksum;
mod component_checksum;
Expand Down Expand Up @@ -238,3 +241,8 @@ impl<For, As> GgrsComponentSnapshot<For, As> {
self.snapshot.iter()
}
}

/// Returns a hasher built using Bevy's [FixedState] appropriate for creating checksums
pub fn checksum_hasher() -> AHasher {
FixedState.build_hasher()
}
6 changes: 3 additions & 3 deletions src/snapshot/resource_checksum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::hash::{BuildHasher, Hash, Hasher};
use std::hash::{Hash, Hasher};

use bevy::prelude::*;

use crate::{ChecksumFlag, ChecksumPart, Rollback, SaveWorld, SaveWorldSet};
use crate::{checksum_hasher, ChecksumFlag, ChecksumPart, Rollback, SaveWorld, SaveWorldSet};

/// Plugin which will track the [`Resource`] `R` and ensure a [`ChecksumPart`] is
/// available and updated. This can be used to generate a [`Checksum`](`crate::Checksum`).
Expand Down Expand Up @@ -33,7 +33,7 @@ use crate::{ChecksumFlag, ChecksumPart, Rollback, SaveWorld, SaveWorldSet};
pub struct ResourceChecksumPlugin<R: Resource>(pub for<'a> fn(&'a R) -> u64);

fn default_hasher<R: Resource + Hash>(resource: &R) -> u64 {
let mut hasher = bevy::utils::FixedState.build_hasher();
let mut hasher = checksum_hasher();
resource.hash(&mut hasher);
hasher.finish()
}
Expand Down

0 comments on commit fa29e1d

Please sign in to comment.