diff --git a/Cargo.lock b/Cargo.lock index 7d6f528..31e02ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,6 +82,15 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bevy" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a5cd3b24a5adb7c7378da7b3eea47639877643d11b6b087fc8a8094f2528615" +dependencies = [ + "bevy_internal", +] + [[package]] name = "bevy-butler" version = "0.6.1-alpha.1" @@ -142,6 +151,22 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "bevy_diagnostic" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048a1ff3944a534b8472516866284181eef0a75b6dd4d39b6e5925715e350766" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_platform", + "bevy_tasks", + "bevy_time", + "bevy_utils", + "const-fnv1a-hash", + "log", +] + [[package]] name = "bevy_ecs" version = "0.16.0" @@ -182,6 +207,44 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "bevy_input" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763410715714f3d4d2dcdf077af276e2e4ea93fd8081b183d446d060ea95baaa" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_math", + "bevy_platform", + "bevy_reflect", + "bevy_utils", + "derive_more", + "log", + "thiserror", +] + +[[package]] +name = "bevy_internal" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "526ffd64c58004cb97308826e896c07d0e23dc056c243b97492e31cdf72e2830" +dependencies = [ + "bevy_app", + "bevy_derive", + "bevy_diagnostic", + "bevy_ecs", + "bevy_input", + "bevy_math", + "bevy_platform", + "bevy_ptr", + "bevy_reflect", + "bevy_tasks", + "bevy_time", + "bevy_transform", + "bevy_utils", +] + [[package]] name = "bevy_log" version = "0.16.0" @@ -212,6 +275,25 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "bevy_math" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a3a926d02dc501c6156a047510bdb538dcb1fa744eeba13c824b73ba88de55" +dependencies = [ + "bevy_reflect", + "derive_more", + "glam", + "itertools 0.14.0", + "libm", + "rand", + "rand_distr", + "serde", + "smallvec", + "thiserror", + "variadics_please", +] + [[package]] name = "bevy_platform" version = "0.16.0" @@ -295,6 +377,35 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "bevy_time" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456369ca10f8e039aaf273332744674844827854833ee29e28f9e161702f2f55" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_platform", + "bevy_reflect", + "log", +] + +[[package]] +name = "bevy_transform" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8479cdd5461246943956a7c8347e4e5d6ff857e57add889fb50eee0b5c26ab48" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_math", + "bevy_reflect", + "bevy_tasks", + "derive_more", + "serde", + "thiserror", +] + [[package]] name = "bevy_utils" version = "0.16.0" @@ -314,7 +425,7 @@ dependencies = [ "bitflags", "cexpr", "clang-sys", - "itertools", + "itertools 0.13.0", "log", "prettyplease", "proc-macro2", @@ -349,6 +460,12 @@ version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +[[package]] +name = "bytemuck" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" + [[package]] name = "byteorder" version = "1.5.0" @@ -422,6 +539,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-fnv1a-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -671,6 +794,8 @@ version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee" dependencies = [ + "bytemuck", + "libm", "serde", ] @@ -726,6 +851,7 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" name = "immediate_stats" version = "0.1.0" dependencies = [ + "bevy", "bevy-butler", "bevy_app", "bevy_ecs", @@ -772,6 +898,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -804,6 +939,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "libm" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" + [[package]] name = "linkme" version = "0.3.32" @@ -899,6 +1040,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -981,6 +1132,15 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "prettyplease" version = "0.2.32" @@ -1039,6 +1199,46 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "redox_syscall" version = "0.5.11" @@ -1658,3 +1858,23 @@ checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] + +[[package]] +name = "zerocopy" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] diff --git a/README.md b/README.md index 7c98289..27f1c64 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,9 @@ Includes a derive macro which propagates stat resets to any stat fields. struct Speed(Stat); fn main() { + let mut speed = Speed(Stat::new(10)); // Set base speed to 10. + loop { - let mut speed = Speed(Stat::new(10)); // Set base speed to 10. - speed.0 *= 2.0; // Applies a multiplier to the final result. speed.0 += 5; // Adds a bonus to the final result. // The order does not matter. Bonuses are always applied before multipliers. diff --git a/immediate_stats/Cargo.toml b/immediate_stats/Cargo.toml index e972a0f..60d53c2 100644 --- a/immediate_stats/Cargo.toml +++ b/immediate_stats/Cargo.toml @@ -24,9 +24,26 @@ bevy_ecs = { version = "0.16.0", default-features = false, optional = true, feat bevy_reflect = { version = "0.16.0", default-features = false, optional = true } immediate_stats_macros = { path = "../immediate_stats_macros", default-features = false } +[dev-dependencies] +bevy = { version = "0.16.0", default-features = false } + [lints.rust] missing_docs = "warn" unexpected_cfgs = { level = "warn", check-cfg = ['cfg(docsrs_dep)'] } unsafe_code = "deny" unsafe_op_in_unsafe_fn = "warn" unused_qualifications = "warn" + +[[example]] +name = "simple_main_loop" +path = "examples/simple_main_loop.rs" + +[[example]] +name = "simple_bevy" +path = "examples/simple_bevy.rs" +required-features = ["bevy"] + +[[example]] +name = "simple_bevy_butler" +path = "examples/simple_bevy_butler.rs" +required-features = ["bevy_butler"] diff --git a/immediate_stats/examples/simple_bevy.rs b/immediate_stats/examples/simple_bevy.rs new file mode 100644 index 0000000..377eaf2 --- /dev/null +++ b/immediate_stats/examples/simple_bevy.rs @@ -0,0 +1,37 @@ +//! A very simple example using Bevy. Requires the `bevy` feature flag. +//! There are two other versions of this example, one using a simple main loop and the other using Bevy Butler. + +use bevy::prelude::*; +use immediate_stats::{Stat, StatContainer, reset_component_modifiers}; + +#[derive(StatContainer, Component)] +struct Speed(Stat); + +fn main() { + App::new() + .add_plugins(MinimalPlugins) + .add_systems(Startup, init_speed) + .add_systems(PreUpdate, reset_component_modifiers::) + // Modifiers must be applied before the speed can be read. + .add_systems(Update, (apply_modifiers, read_speed).chain()) + .run(); +} + +fn init_speed(mut commands: Commands) { + commands.spawn(Speed(Stat::new(10))); // Set base speed to 10. +} + +fn apply_modifiers(mut speeds: Query<&mut Speed>) { + for mut speed in &mut speeds { + speed.0 *= 2.0; // Applies a multiplier to the final result. + speed.0 += 5; // Adds a bonus to the final result. + // The order does not matter. Bonuses are always applied before multipliers. + } +} + +fn read_speed(speeds: Query<&Speed>) { + for speed in &speeds { + println!("The current speed is {}.", speed.0.total()); + assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30 + } +} diff --git a/immediate_stats/examples/simple_bevy_butler.rs b/immediate_stats/examples/simple_bevy_butler.rs new file mode 100644 index 0000000..1a6c095 --- /dev/null +++ b/immediate_stats/examples/simple_bevy_butler.rs @@ -0,0 +1,40 @@ +//! A very simple example using Bevy Butler. Requires the `bevy_butler` feature flag. +//! There are two other versions of this example, one using a simple main loop and the other using Bevy. + +use bevy::prelude::*; +use bevy_butler::{add_system, butler_plugin}; +use immediate_stats::{Stat, StatContainer}; + +#[butler_plugin] +struct SpeedPlugin; + +#[derive(StatContainer, Component)] +#[add_component(plugin = SpeedPlugin)] +struct Speed(Stat); + +fn main() { + App::new().add_plugins((MinimalPlugins, SpeedPlugin)).run(); +} + +#[add_system(plugin = SpeedPlugin, schedule = Startup)] +fn init_speed(mut commands: Commands) { + commands.spawn(Speed(Stat::new(10))); // Set base speed to 10. +} + +#[add_system(plugin = SpeedPlugin, schedule = Update)] +fn apply_modifiers(mut speeds: Query<&mut Speed>) { + for mut speed in &mut speeds { + speed.0 *= 2.0; // Applies a multiplier to the final result. + speed.0 += 5; // Adds a bonus to the final result. + // The order does not matter. Bonuses are always applied before multipliers. + } +} + +// Modifiers must be applied before the speed can be read. +#[add_system(plugin = SpeedPlugin, schedule = Update, after = apply_modifiers)] +fn read_speed(speeds: Query<&Speed>) { + for speed in &speeds { + println!("The current speed is {}.", speed.0.total()); + assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30 + } +} diff --git a/immediate_stats/examples/simple_main_loop.rs b/immediate_stats/examples/simple_main_loop.rs new file mode 100644 index 0000000..0c5bbb3 --- /dev/null +++ b/immediate_stats/examples/simple_main_loop.rs @@ -0,0 +1,25 @@ +//! A very simple example using a main loop. +//! There are two other versions of this example, one using Bevy and the other using Bevy Butler. + +use immediate_stats::*; + +#[derive(StatContainer)] +struct Speed(Stat); + +fn main() { + let mut speed = Speed(Stat::new(10)); // Set base speed to 10. + + loop { + // 1. Apply modifiers: + speed.0 *= 2.0; // Applies a multiplier to the final result. + speed.0 += 5; // Adds a bonus to the final result. + // The order does not matter. Bonuses are always applied before multipliers. + + // 2. Read total: + println!("The current speed is {}.", speed.0.total()); + assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30 + + // 3. Reset modifiers: + speed.reset_modifiers(); // Reset bonus and multiplier, so speed is back to 10. + } +} diff --git a/immediate_stats_macros/src/lib.rs b/immediate_stats_macros/src/lib.rs index 1916c2a..9cb128b 100644 --- a/immediate_stats_macros/src/lib.rs +++ b/immediate_stats_macros/src/lib.rs @@ -3,7 +3,6 @@ mod bevy_butler; mod derive_enum; mod derive_struct; -use darling::Error; use proc_macro_error::{emit_call_site_error, emit_warning, proc_macro_error}; use quote::{ToTokens, quote}; use syn::spanned::Spanned; @@ -34,7 +33,8 @@ pub fn stat_container_derive(item: proc_macro::TokenStream) -> proc_macro::Token #[cfg(feature = "bevy_butler")] { - let systems = bevy_butler::register_systems(tree).unwrap_or_else(Error::write_errors); + let systems = + bevy_butler::register_systems(tree).unwrap_or_else(darling::Error::write_errors); quote! { #trait_impl #systems }.into() }