Skip to content

Commit

Permalink
refactor(GlobalRng): Merge seed resource with rng source (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bluefinger committed Aug 16, 2024
1 parent abfd069 commit db7a4b7
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 243 deletions.
2 changes: 1 addition & 1 deletion MIGRATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ As the `wyrand` dependency has been updated and contains a breaking output chang

## Migrating from v0.7 to v0.8

`GlobalRngSeed` has been changed to make use of `SeedSource` trait, for things like instantiation: `new` is now `from_seed`. `get_seed` is now `clone_seed`. Most of these changes can be done easily by importing the `SeedSource` trait.
`GlobalRngSeed` has been removed, instead being rolled into `GlobalEntropy`. This will allow better reflection tracking of the global rng source, and will allow for automatic reseeding without any custom system needing to be provided. Use the `reseed` method to reinstantiate the internal RNG source with the new seed, and `get_seed` to return a reference to the initial starting seed for the source. The serialized format of `GlobalEntropy` has changed and previously serialized instances are no longer compatible.
71 changes: 71 additions & 0 deletions bevy_prng/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,43 @@ pub trait SeedableEntropySource:
{
}

/// Marker trait for a suitable seed for [`SeedableEntropySource`]. This is an auto trait which will
/// apply to all suitable types that meet the trait criteria.
#[cfg(feature = "serialize")]
pub trait EntropySeed:
Debug
+ Default
+ PartialEq
+ Clone
+ Sync
+ Send
+ Reflect
+ TypePath
+ FromReflect
+ GetTypeRegistration
+ Serialize
+ for<'a> Deserialize<'a>
{
}

#[cfg(feature = "serialize")]
impl<
T: Debug
+ Default
+ PartialEq
+ Clone
+ Sync
+ Send
+ Reflect
+ TypePath
+ FromReflect
+ GetTypeRegistration
+ Serialize
+ for<'a> Deserialize<'a>,
> EntropySeed for T
{
}

/// A marker trait to define the required trait bounds for a seedable PRNG to
/// integrate into `EntropyComponent` or `GlobalEntropy`. This is a sealed trait.
#[cfg(not(feature = "serialize"))]
Expand All @@ -81,6 +118,40 @@ pub trait SeedableEntropySource:
{
}

#[cfg(not(feature = "serialize"))]
/// Marker trait for a suitable seed for [`SeedableEntropySource`]. This is an auto trait which will
/// apply to all suitable types that meet the trait criteria.
pub trait EntropySeed:
Debug
+ Default
+ AsMut<u8>
+ PartialEq
+ Clone
+ Sync
+ Send
+ Reflect
+ TypePath
+ FromReflect
+ GetTypeRegistration //+ private::SealedSeed
{
}

#[cfg(not(feature = "serialize"))]
impl<
T: Debug
+ Default
+ PartialEq
+ Clone
+ Sync
+ Send
+ Reflect
+ TypePath
+ FromReflect
+ GetTypeRegistration,
> EntropySeed for T
{
}

mod private {
pub trait SealedSeedable {}

Expand Down
32 changes: 2 additions & 30 deletions src/component.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::fmt::Debug;

use crate::{
resource::GlobalEntropy,
seed::RngSeed,
traits::{
EcsEntropySource, ForkableAsRng, ForkableAsSeed, ForkableInnerRng, ForkableRng,
ForkableSeed,
},
};
use bevy::prelude::{Component, Mut, Reflect, ReflectComponent, ReflectFromReflect, ResMut};
use bevy::prelude::{Component, Reflect, ReflectComponent, ReflectFromReflect};
use bevy_prng::SeedableEntropySource;
use rand_core::{RngCore, SeedableRng};

Expand Down Expand Up @@ -129,6 +128,7 @@ impl<R: SeedableEntropySource + 'static> EntropyComponent<R> {
}

impl<R: SeedableEntropySource + 'static> Default for EntropyComponent<R> {
#[inline]
fn default() -> Self {
Self::from_entropy()
}
Expand Down Expand Up @@ -187,34 +187,6 @@ impl<R: SeedableEntropySource + 'static> SeedableRng for EntropyComponent<R> {

impl<R: SeedableEntropySource + 'static> EcsEntropySource for EntropyComponent<R> {}

impl<R: SeedableEntropySource + 'static> From<R> for EntropyComponent<R> {
fn from(value: R) -> Self {
Self::new(value)
}
}

impl<R: SeedableEntropySource + 'static> From<&mut EntropyComponent<R>> for EntropyComponent<R> {
fn from(rng: &mut EntropyComponent<R>) -> Self {
Self::from_rng(rng).unwrap()
}
}

impl<R: SeedableEntropySource + 'static> From<&mut Mut<'_, EntropyComponent<R>>>
for EntropyComponent<R>
{
fn from(rng: &mut Mut<'_, EntropyComponent<R>>) -> Self {
Self::from(rng.as_mut())
}
}

impl<R: SeedableEntropySource + 'static> From<&mut ResMut<'_, GlobalEntropy<R>>>
for EntropyComponent<R>
{
fn from(rng: &mut ResMut<'_, GlobalEntropy<R>>) -> Self {
Self::from_rng(rng.as_mut()).unwrap()
}
}

impl<R> ForkableRng for EntropyComponent<R>
where
R: SeedableEntropySource + 'static,
Expand Down
26 changes: 8 additions & 18 deletions src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
use crate::{
component::EntropyComponent,
resource::GlobalEntropy,
seed::{GlobalRngSeed, RngSeed},
traits::SeedSource,
};
use bevy::{
prelude::{App, Plugin},
reflect::{FromReflect, GetTypeRegistration, Reflect, TypePath},
};
use bevy_prng::SeedableEntropySource;
use crate::{component::EntropyComponent, resource::GlobalEntropy, seed::RngSeed};
use bevy::prelude::{App, Plugin};
use bevy_prng::{EntropySeed, SeedableEntropySource};
use rand_core::SeedableRng;

/// Plugin for integrating a PRNG that implements `RngCore` into
/// the bevy engine, registering types for a global resource and
Expand Down Expand Up @@ -69,22 +62,19 @@ where

impl<R: SeedableEntropySource + 'static> Plugin for EntropyPlugin<R>
where
R::Seed: Send + Sync + Clone + Reflect + FromReflect + GetTypeRegistration + TypePath,
R::Seed: EntropySeed,
{
fn build(&self, app: &mut App) {
app.register_type::<GlobalEntropy<R>>()
.register_type::<EntropyComponent<R>>()
.register_type::<GlobalRngSeed<R>>()
.register_type::<R::Seed>();

if let Some(seed) = self.seed.as_ref() {
app.insert_resource(GlobalRngSeed::<R>::from_seed(seed.clone()));
app.insert_resource(GlobalEntropy::<R>::from_seed(seed.clone()));
} else {
app.init_resource::<GlobalRngSeed<R>>();
app.init_resource::<GlobalEntropy<R>>();
}

app.init_resource::<GlobalEntropy<R>>()
.world_mut()
.register_component_hooks::<RngSeed<R>>();
app.world_mut().register_component_hooks::<RngSeed<R>>();
}
}
4 changes: 2 additions & 2 deletions src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pub use crate::component::EntropyComponent;
pub use crate::plugin::EntropyPlugin;
pub use crate::resource::GlobalEntropy;
pub use crate::seed::{GlobalRngSeed, RngSeed};
pub use crate::seed::RngSeed;
pub use crate::traits::{
ForkableAsRng, ForkableAsSeed, ForkableInnerRng, ForkableRng, ForkableSeed, SeedSource
ForkableAsRng, ForkableAsSeed, ForkableInnerRng, ForkableRng, ForkableSeed, SeedSource,
};
#[cfg(feature = "wyrand")]
#[cfg_attr(docsrs, doc(cfg(feature = "wyrand")))]
Expand Down
Loading

0 comments on commit db7a4b7

Please sign in to comment.