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: Reenable 512 bit variants of Xoshiro with remote reflected Seed512 #28

Merged
merged 1 commit into from
Nov 11, 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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn setup_npc_from_source(
- **`serialize`** - Enables `Serialize` and `Deserialize` derives. Enabled by default.
- **`rand_chacha`** - This enables the exporting of newtyped `ChaCha*Rng` structs, for those that want/need to use a CSPRNG level source.
- **`rand_pcg`** - This enables the exporting of newtyped `Pcg*` structs from `rand_pcg`.
- **`rand_xoshiro`** - This enables the exporting of newtyped `Xoshiro*` structs from `rand_xoshiro`.
- **`rand_xoshiro`** - This enables the exporting of newtyped `Xoshiro*` structs from `rand_xoshiro`. It also exports a remote-reflected version of `Seed512` so to allow setting up `Xoshiro512StarStar` and so forth.
- **`wyrand`** - This enables the exporting of newtyped `WyRand` from `wyrand`, the same algorithm in use within `fastrand`/`turborand`.

## Supported Versions & MSRV
Expand Down
16 changes: 9 additions & 7 deletions bevy_prng/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ By default, `bevy_prng` won't export anything _unless_ the feature/algorithm you

- **`rand_chacha`** - This enables the exporting of newtyped `ChaCha*Rng` structs, for those that want/need to use a CSPRNG level source.
- **`rand_pcg`** - This enables the exporting of newtyped `Pcg*` structs from `rand_pcg`.
- **`rand_xoshiro`** - This enables the exporting of newtyped `Xoshiro*` structs from `rand_xoshiro`.
- **`rand_xoshiro`** - This enables the exporting of newtyped `Xoshiro*` structs from `rand_xoshiro`. It also exports a remote-reflected version of `Seed512` so to allow setting up `Xoshiro512StarStar` and so forth.
- **`wyrand`** - This enables the exporting of newtyped `WyRand` from `wyrand`, the same algorithm in use within `fastrand`/`turborand`.

In addition to these feature flags to enable various supported algorithms, there's also **`serialize`** flag to provide `serde` support for `Serialize`/`Deserialize`, which is enabled by default.
Expand Down Expand Up @@ -44,17 +44,19 @@ All the below crates implement the necessary traits to be compatible with `bevy_

`bevy_prng` uses the same MSRV as `bevy`.

| `bevy` | `bevy_prng` |
| ------ | ----------- |
| v0.13 | v0.5 |
| v0.12 | v0.2 |
| v0.11 | v0.1 |
| `bevy` | `bevy_prng` |
| ------ | ------------ |
| v0.15 | v0.8 |
| v0.14 | v0.7 -> v0.8 |
| v0.13 | v0.5 -> v0.6 |
| v0.12 | v0.2 |
| v0.11 | v0.1 |

The versions of `rand_core`/`rand` that `bevy_prng` is compatible with is as follows:

| `bevy_prng` | `rand_core` | `rand` |
| ------------ | ----------- | ------ |
| v0.1 -> v0.5 | v0.6 | v0.8 |
| v0.1 -> v0.8 | v0.6 | v0.8 |

## License

Expand Down
83 changes: 83 additions & 0 deletions bevy_prng/src/newtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,88 @@ macro_rules! newtype_prng {
fn from_seed(seed: Self::Seed) -> Self {
Self::new(<$rng>::from_seed(seed))
}

#[inline]
fn from_rng<R: RngCore>(source: R) -> Result<Self, ::rand_core::Error> {
Ok(Self::new(<$rng>::from_rng(source)?))
}
}

impl From<$rng> for $newtype {
#[inline]
fn from(value: $rng) -> Self {
Self::new(value)
}
}

impl SeedableEntropySource for $newtype {}
};
}

macro_rules! newtype_prng_remote {
($newtype:tt, $rng:ty, $seed:ty, $doc:tt, $feature:tt) => {
#[doc = $doc]
#[derive(Debug, Clone, PartialEq, Reflect)]
#[cfg_attr(
feature = "serialize",
derive(::serde_derive::Serialize, ::serde_derive::Deserialize)
)]
#[cfg_attr(
all(feature = "serialize"),
reflect(opaque, Debug, PartialEq, FromReflect, Serialize, Deserialize)
)]
#[cfg_attr(
all(not(feature = "serialize")),
reflect(opaque, Debug, PartialEq, FromReflect)
)]
#[cfg_attr(docsrs, doc(cfg(feature = $feature)))]
#[type_path = "bevy_prng"]
#[repr(transparent)]
pub struct $newtype($rng);

impl $newtype {
/// Create a new instance.
#[inline(always)]
#[must_use]
pub fn new(rng: $rng) -> Self {
Self(rng)
}
}

impl RngCore for $newtype {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
self.0.next_u32()
}

#[inline(always)]
fn next_u64(&mut self) -> u64 {
self.0.next_u64()
}

#[inline]
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.0.fill_bytes(dest)
}

#[inline]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), ::rand_core::Error> {
self.0.try_fill_bytes(dest)
}
}

impl SeedableRng for $newtype {
type Seed = $seed;

#[inline]
fn from_seed(seed: Self::Seed) -> Self {
Self::new(<$rng>::from_seed(seed.0))
}

#[inline]
fn from_rng<R: RngCore>(source: R) -> Result<Self, ::rand_core::Error> {
Ok(Self::new(<$rng>::from_rng(source)?))
}
}

impl From<$rng> for $newtype {
Expand All @@ -71,3 +153,4 @@ macro_rules! newtype_prng {
}

pub(crate) use newtype_prng;
pub(crate) use newtype_prng_remote;
47 changes: 45 additions & 2 deletions bevy_prng/src/xoshiro.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,54 @@
use crate::{newtype::newtype_prng, SeedableEntropySource};
use crate::{
newtype::{newtype_prng, newtype_prng_remote},
SeedableEntropySource,
};

use bevy::prelude::{Reflect, ReflectFromReflect};
use bevy::{
prelude::{Reflect, ReflectDefault, ReflectFromReflect},
reflect::reflect_remote,
};
use rand_core::{RngCore, SeedableRng};

#[cfg(feature = "serialize")]
use bevy::prelude::{ReflectDeserialize, ReflectSerialize};

/// Remote reflected version of [`rand_xoshiro::Seed512`], needed to support
/// proper reflection for the 512 bit variants of the Xoshiro PRNG.
#[reflect_remote(::rand_xoshiro::Seed512)]
#[derive(Debug, Default, Clone)]
#[reflect(Debug, Default)]
pub struct Seed512(pub [u8; 64]);

impl AsMut<[u8]> for Seed512 {
fn as_mut(&mut self) -> &mut [u8] {
self.0.as_mut()
}
}

newtype_prng_remote!(
Xoshiro512StarStar,
::rand_xoshiro::Xoshiro512StarStar,
Seed512,
"A newtyped [`rand_xoshiro::Xoshiro512StarStar`] RNG",
"rand_xoshiro"
);

newtype_prng_remote!(
Xoshiro512PlusPlus,
::rand_xoshiro::Xoshiro512PlusPlus,
Seed512,
"A newtyped [`rand_xoshiro::Xoshiro512PlusPlus`] RNG",
"rand_xoshiro"
);

newtype_prng_remote!(
Xoshiro512Plus,
::rand_xoshiro::Xoshiro512Plus,
Seed512,
"A newtyped [`rand_xoshiro::Xoshiro512Plus`] RNG",
"rand_xoshiro"
);

newtype_prng!(
Xoshiro256StarStar,
::rand_xoshiro::Xoshiro256StarStar,
Expand Down
4 changes: 2 additions & 2 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use bevy_prng::{Pcg32, Pcg64, Pcg64Mcg};
#[cfg(feature = "rand_xoshiro")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_xoshiro")))]
pub use bevy_prng::{
Xoroshiro128Plus, Xoroshiro128PlusPlus, Xoroshiro128StarStar, Xoroshiro64Star,
Seed512, Xoroshiro128Plus, Xoroshiro128PlusPlus, Xoroshiro128StarStar, Xoroshiro64Star,
Xoroshiro64StarStar, Xoshiro128Plus, Xoshiro128PlusPlus, Xoshiro128StarStar, Xoshiro256Plus,
Xoshiro256PlusPlus, Xoshiro256StarStar,
Xoshiro256PlusPlus, Xoshiro256StarStar, Xoshiro512Plus, Xoshiro512PlusPlus, Xoshiro512StarStar,
};
2 changes: 1 addition & 1 deletion src/seed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ mod tests {

assert!(value.is_dynamic());
assert!(value.represents::<RngSeed<WyRand>>());
assert!(!value.try_downcast_ref::<RngSeed<WyRand>>().is_some());
assert!(value.try_downcast_ref::<RngSeed<WyRand>>().is_none());

let recreated = RngSeed::<WyRand>::from_reflect(value.as_ref()).unwrap();

Expand Down
2 changes: 1 addition & 1 deletion tutorial/01-choosing-prng.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn main() {
The current set of PRNG algorithms that are supported out of the box in `bevy_prng` are as follows:

- `wyrand`: This provides newtyped `WyRand` from `wyrand`, the same algorithm in use within `fastrand`/`turborand`.
- `rand_xoshiro`: This provides newtyped `Xoshiro*` structs from `rand_xoshiro`.
- `rand_xoshiro`: This provides newtyped `Xoshiro*` structs from `rand_xoshiro`. It also exports a remote-reflected version of `Seed512` so to allow setting up `Xoshiro512StarStar` and so forth.
- `rand_pcg`: This provides newtyped `Pcg*` structs from `rand_pcg`.
- `rand_chacha`: This provides newtyped `ChaCha*Rng` structs, for those that want/need to use a CSPRNG level source.

Expand Down
Loading