Skip to content

Commit

Permalink
Implement step system
Browse files Browse the repository at this point in the history
  • Loading branch information
benfrankel committed Jul 21, 2024
1 parent 171fa4a commit 709234b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 4 deletions.
3 changes: 3 additions & 0 deletions assets/config/step.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(
duration_millis: 125,
)
6 changes: 3 additions & 3 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ pub(super) fn plugin(app: &mut App) {
/// Game logic system ordering in the [`Update`] schedule.
#[derive(SystemSet, Clone, Eq, PartialEq, Hash, Debug)]
pub enum UpdateSet {
/// Synchronize start-of-frame values.
SyncEarly,
/// Tick timers.
TickTimers,
/// Synchronize start-of-frame values.
SyncEarly,
/// Record player and AI input.
RecordInput,
/// Step game logic.
Expand All @@ -67,8 +67,8 @@ impl Configure for UpdateSet {
app.configure_sets(
Update,
(
Self::SyncEarly,
Self::TickTimers,
Self::SyncEarly,
Self::Update,
Self::RecordInput,
Self::HandleEvents,
Expand Down
4 changes: 3 additions & 1 deletion src/game.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
//! Game mechanics and content

mod step;

use bevy::prelude::*;

use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
app.configure::<GameRoot>();

app.add_plugins(());
app.add_plugins(step::plugin);
}

#[derive(Resource, Reflect)]
Expand Down
83 changes: 83 additions & 0 deletions src/game/step.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::time::Duration;

use bevy::prelude::*;
use serde::Deserialize;
use serde::Serialize;

use crate::core::UpdateSet;
use crate::util::prelude::*;

pub(super) fn plugin(app: &mut App) {
app.configure::<(ConfigHandle<StepConfig>, StepTimer, Step)>();
}

#[derive(Asset, Reflect, Serialize, Deserialize)]
struct StepConfig {
duration_millis: u64,
}

impl Config for StepConfig {
const PATH: &'static str = "config/step.ron";

const EXTENSION: &'static str = "step.ron";

fn apply(&self, world: &mut World) {
world
.resource_mut::<StepTimer>()
.0
.set_duration(Duration::from_millis(self.duration_millis));
}
}

#[derive(Resource, Reflect)]
#[reflect(Resource)]
pub struct StepTimer(pub Timer);

impl Configure for StepTimer {
fn configure(app: &mut App) {
app.register_type::<Self>();
app.init_resource::<Self>();
app.add_systems(Update, tick_step_timer.in_set(UpdateSet::TickTimers));
}
}

impl Default for StepTimer {
fn default() -> Self {
Self(Timer::new(Duration::from_millis(125), TimerMode::Repeating))
}
}

fn tick_step_timer(time: Res<Time>, mut step_timer: ResMut<StepTimer>) {
step_timer.0.tick(time.delta());
}

#[derive(Resource, Reflect, Default)]
#[reflect(Resource)]
pub struct Step(pub usize);

impl Configure for Step {
fn configure(app: &mut App) {
app.register_type::<Self>();
app.init_resource::<Self>();
app.add_systems(Update, update_step.in_set(UpdateSet::SyncEarly));
app.add_systems(
Update,
(|step: Res<Step>| println!("Step: {}", step.0))
.in_set(UpdateSet::Update)
.run_if(on_step(2)),
);
}
}

fn update_step(step_timer: Res<StepTimer>, mut step: ResMut<Step>) {
step.0 += step_timer.0.times_finished_this_tick() as usize;
}

/// A run condition to run a system every `n` steps.
pub fn on_step(n: usize) -> impl Fn(Res<StepTimer>, Res<Step>) -> bool {
move |step_timer, step| {
let hi = step.0;
let lo = hi - step_timer.0.times_finished_this_tick() as usize;
hi / n > lo / n
}
}

0 comments on commit 709234b

Please sign in to comment.