Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(GlobalRng): Merge seed resource with rng source #24

Merged
merged 3 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading