Skip to content

Commit

Permalink
Merge pull request #8 from Bluefinger/update-v0.11.1
Browse files Browse the repository at this point in the history
feat: Custom TypePath impl for component/resource
  • Loading branch information
Bluefinger authored Aug 16, 2023
2 parents a7c9104 + 772ec20 commit 3316c40
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 24 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ keywords = ["game", "bevy", "rand", "rng"]
categories = ["game-engines", "algorithms"]
exclude = ["/.*"]
resolver = "2"
rust-version = "1.67.0"
rust-version = "1.70.0"

[features]
default = ["serialize", "thread_local_entropy"]
Expand All @@ -19,7 +19,7 @@ serialize = ["dep:serde", "rand_core/serde1", "rand_chacha?/serde1"]

[dependencies]
# bevy
bevy = { version = "0.10", default-features = false }
bevy = { version = "0.11.1", default-features = false }

# others
serde = { version = "1.0", features = ["derive"], optional = true }
Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,20 @@ All recommended crates implement the necessary traits to be compatible with `bev
- **`thread_local_entropy`** - Enables `ThreadLocalEntropy`, overriding `SeedableRng::from_entropy` implementations to make use of thread local entropy sources for faster PRNG initialisation. Enabled by default.
- **`serialize`** - Enables [`Serialize`] and [`Deserialize`] derives. Enabled by default.

## Note about Reflection & `TypePath` stability.

All `rand` PRNGs do not implement `TypePath` in any form, even as an optional feature, due to lack of native support for reflection in Rust. As such, while the components/resource in this library are *stable* and implement a stable `TypePath` for themselves, PRNGs rely on `std::any::type_name` for returning the type's name/path, which is NOT guaranteed to be stable for all versions of the compiler. As such, there may be instabilities/compatibilities with different compiler versions and compilations, as this instability infects the overall `TypePath` via the generic portion of the type path.

If there arises problems with regards to stability for reflection purposes, please make an issue with regards to that in this repository, so I can track such occurrences. Tests are included in the crate anyway to hopefully detect such cases in the future.

## Supported Versions & MSRV

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

| `bevy_rand` | `bevy` |
| ----------- | ------ |
| v0.1 | v0.10 |
| `bevy_rand` | `bevy` |
| ----------- | ------- |
| v0.2 | v0.11.1 |
| v0.1 | v0.10 |

## License

Expand Down
9 changes: 6 additions & 3 deletions examples/turn_based_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,12 @@ struct Health {

fn main() {
App::new()
.add_plugin(EntropyPlugin::<ChaCha8Rng>::with_seed([1; 32]))
.add_startup_systems((setup_player, setup_enemies).chain())
.add_systems((determine_attack_order.pipe(attack_turn), buff_entities).chain())
.add_plugins(EntropyPlugin::<ChaCha8Rng>::with_seed([1; 32]))
.add_systems(Startup, (setup_player, setup_enemies).chain())
.add_systems(
Update,
(determine_attack_order.pipe(attack_turn), buff_entities).chain(),
)
.run();
}

Expand Down
49 changes: 46 additions & 3 deletions src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::fmt::Debug;

use crate::{resource::GlobalEntropy, traits::SeedableEntropySource};
use bevy::{
prelude::{Component, FromReflect, Mut, Reflect, ReflectComponent, ResMut},
reflect::ReflectFromReflect,
prelude::{Component, Mut, Reflect, ReflectComponent, ReflectFromReflect, ResMut},
reflect::{utility::GenericTypePathCell, TypePath},
};
use rand_core::{RngCore, SeedableRng};

Expand Down Expand Up @@ -89,7 +89,8 @@ use serde::{Deserialize, Serialize};
/// }
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Component, Reflect, FromReflect)]
#[derive(Debug, Clone, PartialEq, Eq, Component, Reflect)]
#[reflect_value(type_path = false)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serialize",
Expand Down Expand Up @@ -122,6 +123,35 @@ impl<R: SeedableEntropySource + 'static> EntropyComponent<R> {
}
}

impl<R: SeedableEntropySource + 'static> TypePath for EntropyComponent<R> {
fn type_path() -> &'static str {
static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| {
format!(
"bevy_rand::component::EntropyComponent<{}>",
std::any::type_name::<R>()
)
})
}

fn short_type_path() -> &'static str {
static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| bevy::utils::get_short_name(Self::type_path()))
}

fn type_ident() -> Option<&'static str> {
Some("EntropyComponent")
}

fn crate_name() -> Option<&'static str> {
Some("bevy_rand")
}

fn module_path() -> Option<&'static str> {
Some("bevy_rand::component")
}
}

impl<R: SeedableEntropySource + 'static> Default for EntropyComponent<R> {
fn default() -> Self {
Self::from_entropy()
Expand Down Expand Up @@ -225,6 +255,19 @@ mod tests {
);
}

#[test]
fn type_paths() {
assert_eq!(
"bevy_rand::component::EntropyComponent<rand_chacha::chacha::ChaCha8Rng>",
EntropyComponent::<ChaCha8Rng>::type_path()
);

assert_eq!(
"EntropyComponent<ChaCha8Rng>",
EntropyComponent::<ChaCha8Rng>::short_type_path()
);
}

#[cfg(feature = "serialize")]
#[test]
fn rng_reflection() {
Expand Down
55 changes: 50 additions & 5 deletions src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::fmt::Debug;

use crate::traits::SeedableEntropySource;
use bevy::{
prelude::{FromReflect, Reflect, ReflectResource, Resource},
reflect::ReflectFromReflect,
prelude::{Reflect, ReflectFromReflect, ReflectResource, Resource},
reflect::{utility::GenericTypePathCell, TypePath},
};
use rand_core::{RngCore, SeedableRng};

Expand Down Expand Up @@ -32,7 +32,8 @@ use serde::{Deserialize, Serialize};
/// println!("Random value: {}", rng.next_u32());
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq, Resource, Reflect, FromReflect)]
#[derive(Debug, Clone, PartialEq, Eq, Resource, Reflect)]
#[reflect_value(type_path = false)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serialize",
Expand Down Expand Up @@ -65,6 +66,35 @@ impl<R: SeedableEntropySource + 'static> GlobalEntropy<R> {
}
}

impl<R: SeedableEntropySource + 'static> TypePath for GlobalEntropy<R> {
fn type_path() -> &'static str {
static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| {
format!(
"bevy_rand::resource::GlobalEntropy<{}>",
std::any::type_name::<R>()
)
})
}

fn short_type_path() -> &'static str {
static CELL: GenericTypePathCell = GenericTypePathCell::new();
CELL.get_or_insert::<Self, _>(|| bevy::utils::get_short_name(Self::type_path()))
}

fn type_ident() -> Option<&'static str> {
Some("GlobalEntropy")
}

fn crate_name() -> Option<&'static str> {
Some("bevy_rand")
}

fn module_path() -> Option<&'static str> {
Some("bevy_rand::resource")
}
}

impl<R: SeedableEntropySource + 'static> Default for GlobalEntropy<R> {
fn default() -> Self {
Self::from_entropy()
Expand Down Expand Up @@ -136,15 +166,30 @@ impl<R: SeedableEntropySource + 'static> From<&mut R> for GlobalEntropy<R> {

#[cfg(test)]
mod tests {
use rand_chacha::ChaCha8Rng;

use super::*;

#[test]
fn type_paths() {
assert_eq!(
"bevy_rand::resource::GlobalEntropy<rand_chacha::chacha::ChaCha8Rng>",
GlobalEntropy::<ChaCha8Rng>::type_path()
);

assert_eq!(
"GlobalEntropy<ChaCha8Rng>",
GlobalEntropy::<ChaCha8Rng>::short_type_path()
);
}

#[cfg(feature = "serialize")]
#[test]
fn rng_reflection() {
use super::*;
use bevy::reflect::{
serde::{ReflectSerializer, UntypedReflectDeserializer},
TypeRegistryInternal,
};
use rand_chacha::ChaCha8Rng;
use ron::ser::to_string;
use serde::de::DeserializeSeed;

Expand Down
19 changes: 11 additions & 8 deletions tests/determinism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,16 @@ fn setup_sources(mut commands: Commands, mut rng: ResMut<GlobalEntropy<ChaCha8Rn
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
fn test_parallel_determinism() {
App::new()
.add_plugin(EntropyPlugin::<ChaCha8Rng>::with_seed([2; 32]))
.add_startup_system(setup_sources)
.add_systems((
random_output_a,
random_output_b,
random_output_c,
random_output_d,
))
.add_plugins(EntropyPlugin::<ChaCha8Rng>::with_seed([2; 32]))
.add_systems(Startup, setup_sources)
.add_systems(
Update,
(
random_output_a,
random_output_b,
random_output_c,
random_output_d,
),
)
.run();
}

0 comments on commit 3316c40

Please sign in to comment.