Skip to content
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
600 changes: 372 additions & 228 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,24 @@ fn main() {
}
```

### Bevy Butler
### Bevy Auto Plugin

If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/), you can also use the `bevy_butler` feature flag.
This automatically registers the required system(s) using the `add_component` attribute
or the existing `insert_resource` macro.
If you use [Bevy Auto Plugin](https://github.com/strikeforcezero/bevy_auto_plugin/), you can also use the `bevy_auto_plugin` feature flag.
This automatically registers the required system(s) by leveraging the existing `auto_component` and `auto_resource` macros.

```rust
fn main() {
App::new().add_plugins((ImmediateStatsPlugin, MyPlugin)).run();
}

#[butler_plugin]
#[derive(AutoPlugin)]
#[auto_plugin(impl_plugin_trait)]
struct MyPlugin;

// `StatContainer` derive adds the `add_component` attribute
// and hooks into the existing `insert_resource` macro.
// `StatContainer` derive hooks into the existing `auto_component` and `auto_resource` macros.
#[derive(StatContainer, Component, Resource)]
#[add_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
#[insert_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
#[auto_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
#[auto_init_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
struct Speed(Stat);
```

Expand Down
24 changes: 20 additions & 4 deletions immediate_stats/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "immediate_stats"
version = "0.1.3"
version = "0.2.0-beta.1"
edition = "2024"
description = "Game stats that reset every frame, inspired by immediate mode GUI."
categories = ["game-development", "data-structures"]
Expand All @@ -14,19 +14,30 @@ readme = "../README.md"
all-features = true

[features]
bevy = ["bevy_ecs", "bevy_app", "bevy_reflect", "immediate_stats_macros/bevy"]
bevy_butler = ["bevy", "bevy-butler", "immediate_stats_macros/bevy_butler"]
bevy = [
"dep:bevy_ecs",
"dep:bevy_app",
"dep:bevy_reflect",
"immediate_stats_macros/bevy",
]
bevy_butler = ["bevy", "dep:bevy-butler", "immediate_stats_macros/bevy_butler"]
bevy_auto_plugin = [
"bevy",
"dep:bevy_auto_plugin",
"immediate_stats_macros/bevy_auto_plugin",
]

[dependencies]
bevy_app = { version = "0.16.0", default-features = false, optional = true, features = [
"bevy_reflect",
] }
bevy-butler = { version = "0.6.1", optional = true }
bevy_auto_plugin = { version = "0.5.0", optional = true }
bevy_ecs = { version = "0.16.0", default-features = false, optional = true, features = [
"bevy_reflect",
] }
bevy_reflect = { version = "0.16.0", default-features = false, optional = true }
immediate_stats_macros = { path = "../immediate_stats_macros", version = "0.1.3", default-features = false }
immediate_stats_macros = { path = "../immediate_stats_macros", version = "0.2.0-beta.1", default-features = false }

[dev-dependencies]
bevy = { version = "0.16.0", default-features = false }
Expand All @@ -51,3 +62,8 @@ required-features = ["bevy"]
name = "simple_bevy_butler"
path = "examples/simple_bevy_butler.rs"
required-features = ["bevy_butler"]

[[example]]
name = "simple_bevy_auto_plugin"
path = "examples/simple_bevy_auto_plugin.rs"
required-features = ["bevy_auto_plugin"]
45 changes: 45 additions & 0 deletions immediate_stats/examples/simple_bevy_auto_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! A very simple example using Bevy Auto Plugin. Requires the `bevy_auto_plugin` 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_auto_plugin;
use bevy_auto_plugin::modes::global::prelude::{AutoPlugin, auto_component, auto_system};
use immediate_stats::*;

fn main() {
App::new()
.add_plugins((MinimalPlugins, ImmediateStatsPlugin, SpeedPlugin))
.run();
}

#[derive(AutoPlugin)]
#[auto_plugin(impl_plugin_trait)]
struct SpeedPlugin;

// Implements `reset_modifiers` by passing the call onto `Stat`.
// This will also add the `ResetComponentPlugin` to `SpeedPlugin`.
#[derive(StatContainer, Component)]
#[auto_component(plugin = SpeedPlugin)]
struct Speed(Stat);

#[auto_system(plugin = SpeedPlugin, schedule = Startup)]
fn init_speed(mut commands: Commands) {
commands.spawn(Speed(Stat::new(10))); // Set base speed to 10.
}

#[auto_system(plugin = SpeedPlugin, schedule = Update, config(in_set = StatSystems::Modify))]
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.
}
}

#[auto_system(plugin = SpeedPlugin, schedule = Update, config(in_set = StatSystems::Read))]
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
}
}
5 changes: 3 additions & 2 deletions immediate_stats/examples/simple_bevy_butler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! 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.
//! A very simple example using Bevy Butler. Requires the `bevy_butler` feature flag, which is *depreciated*.
//!
//! **Please see the Bevy Auto Plugin example instead.**

use bevy::prelude::*;
use bevy_butler::*;
Expand Down
2 changes: 1 addition & 1 deletion immediate_stats/examples/simple_main_loop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//! 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.
//! There are two other versions of this example, one using Bevy and the other using Bevy Auto Plugin.

use immediate_stats::*;

Expand Down
54 changes: 27 additions & 27 deletions immediate_stats/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,31 +48,30 @@
//! }
//! ```
//!
//! ### Bevy Butler
//! ### Bevy Auto Plugin
//!
//! If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/),
//! you can also use the `bevy_butler` feature flag.
//! This automatically registers the required system(s) using the `add_component` attribute
//! or the existing `insert_resource` macro.
//! If you use [Bevy Auto Plugin](https://github.com/strikeforcezero/bevy_auto_plugin/),
//! you can also use the `bevy_auto_plugin` feature flag. This automatically registers the required
//! system(s) by leveraging the existing `auto_component` and `auto_resource` macros.
//!
#![cfg_attr(not(feature = "bevy_butler"), doc = "```rust ignore")]
#![cfg_attr(feature = "bevy_butler", doc = "```rust")]
#![cfg_attr(not(feature = "bevy_auto_plugin"), doc = "```rust ignore")]
#![cfg_attr(feature = "bevy_auto_plugin", doc = "```rust")]
//! # use bevy_app::prelude::*;
//! # use bevy_ecs::prelude::*;
//! # use immediate_stats::*;
//! # use bevy_butler::*;
//! # use bevy_auto_plugin::modes::global::prelude::{AutoPlugin, auto_component, auto_resource};
//! fn main() {
//! App::new().add_plugins((ImmediateStatsPlugin, MyPlugin)).run();
//! }
//!
//! #[butler_plugin]
//! #[derive(AutoPlugin)]
//! #[auto_plugin(impl_plugin_trait)]
//! struct MyPlugin;
//!
//! // `StatContainer` derive adds the `add_component` attribute
//! // and hooks into the existing `insert_resource` macro.
//! #[derive(StatContainer, Component, Resource, Default)]
//! #[add_component(plugin = MyPlugin)] // Adds `ResetComponentPlugin`
//! #[insert_resource(plugin = MyPlugin)] // Adds `ResetResourcePlugin`
//! // `StatContainer` derive hooks into the existing `auto_component` and `auto_resource` macros.
//! #[derive(StatContainer, Component, Resource)]
//! #[auto_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
//! #[auto_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
//! struct Speed(Stat);
//! ```
//!
Expand Down Expand Up @@ -141,23 +140,24 @@ mod stat;
/// assert_eq!(partial.ignored, Stat::default().with_bonus(10));
/// }
/// ```
/// # Bevy Butler
/// If the `bevy_butler` feature flag is enabled, you may also use the `add_component` attribute
/// or the existing `insert_resource` macro to register [`reset_component_modifiers`]
/// and/or [`reset_resource_modifiers`] automatically.
#[cfg_attr(not(feature = "bevy_butler"), doc = "```rust ignore")]
#[cfg_attr(feature = "bevy_butler", doc = "```rust")]
/// # use bevy_butler::*;
/// # Bevy Auto Plugin
/// If the `bevy_auto_plugin` feature flag is enabled, the existing `auto_component` and
/// `auto_resource` macros will register [`reset_component_modifiers`] and/or
/// [`reset_resource_modifiers`] automatically.
#[cfg_attr(not(feature = "bevy_auto_plugin"), doc = "```rust ignore")]
#[cfg_attr(feature = "bevy_auto_plugin", doc = "```rust")]
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # use immediate_stats::*;
/// #[butler_plugin]
/// # use bevy_auto_plugin::modes::global::prelude::{AutoPlugin, auto_component, auto_resource};
/// #[derive(AutoPlugin)]
/// #[auto_plugin(impl_plugin_trait)]
/// struct MyPlugin;
///
/// // `StatContainer` derive adds the `add_component` attribute
/// // and hooks into the existing `insert_resource` macro.
/// #[derive(StatContainer, Component, Resource, Default)]
/// #[add_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
/// #[insert_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
/// // `StatContainer` derive hooks into the existing `auto_component` and `auto_resource` macros.
/// #[derive(StatContainer, Component, Resource)]
/// #[auto_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
/// #[auto_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
/// struct Speed(Stat);
/// ```
pub use immediate_stats_macros::StatContainer;
Expand Down
61 changes: 61 additions & 0 deletions immediate_stats/tests/bevy_auto_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//! Tests the `add_component` attribute for automatic system registration.
#![cfg(feature = "bevy_auto_plugin")]

extern crate immediate_stats;
use crate::{Stat, StatContainer};
use bevy_app::App;
use bevy_auto_plugin::modes::global::prelude::{AutoPlugin, auto_component, auto_init_resource};
use bevy_ecs::prelude::*;
use immediate_stats::*;

#[derive(AutoPlugin)]
#[auto_plugin(impl_plugin_trait)]
struct MyPlugin;

#[derive(Resource, Component, StatContainer, Default, PartialEq, Debug)]
#[auto_component(plugin = MyPlugin)]
#[auto_init_resource(plugin = MyPlugin)]
struct Health(Stat);

#[test]
fn reset_component_auto() {
let mut app = App::new();

app.add_plugins(MyPlugin);

let entity = app
.world_mut()
.spawn(Health(Stat {
base: 100,
bonus: 50,
multiplier: 2.0,
}))
.id();

app.update();

assert_eq!(
app.world().get::<Health>(entity),
Some(Health(Stat::new(100))).as_ref()
);
}

#[test]
fn reset_resource_auto() {
let mut app = App::new();

app.add_plugins(MyPlugin);

app.insert_resource(Health(Stat {
base: 100,
bonus: 50,
multiplier: 2.0,
}));

app.update();

assert_eq!(
app.world().get_resource::<Health>(),
Some(Health(Stat::new(100))).as_ref()
);
}
5 changes: 3 additions & 2 deletions immediate_stats_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "immediate_stats_macros"
version = "0.1.3"
version = "0.2.0-beta.1"
edition = "2024"
description = "Game stats that reset every frame, inspired by immediate mode GUI."
categories = ["game-development", "data-structures"]
Expand All @@ -19,9 +19,10 @@ proc-macro = true
[features]
bevy = []
bevy_butler = ["bevy"]
bevy_auto_plugin = ["bevy"]

[dependencies]
darling = "0.20.11"
darling = "0.21.3"
proc-macro2 = "1.0"
proc-macro-error = "1.0"
quote = "1.0"
Expand Down
Loading