Skip to content

Commit

Permalink
Merge ScheduleRunnerSettings into ScheduleRunnerPlugin (#8585)
Browse files Browse the repository at this point in the history
# Objective

`ScheduleRunnerPlugin` was still configured via a resource, meaning
users would be able to change the settings while the app is running, but
the changes wouldn't have an effect.

## Solution

Configure plugin directly

---

## Changelog

- Changed: merged `ScheduleRunnerSettings` into `ScheduleRunnerPlugin` 

## Migration Guide

- instead of inserting the `ScheduleRunnerSettings` resource, configure
the `ScheduleRunnerPlugin`
  • Loading branch information
SpecificProtagonist committed May 10, 2023
1 parent f786ad4 commit 86aaad7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 44 deletions.
48 changes: 19 additions & 29 deletions crates/bevy_app/src/schedule_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::{
plugin::Plugin,
};
use bevy_ecs::event::{Events, ManualEventReader};
use bevy_ecs::prelude::Resource;
use bevy_utils::{Duration, Instant};

#[cfg(target_arch = "wasm32")]
Expand All @@ -13,7 +12,7 @@ use wasm_bindgen::{prelude::*, JsCast};

/// Determines the method used to run an [`App`]'s [`Schedule`](bevy_ecs::schedule::Schedule).
///
/// It is used in the [`ScheduleRunnerSettings`].
/// It is used in the [`ScheduleRunnerPlugin`].
#[derive(Copy, Clone, Debug)]
pub enum RunMode {
/// Indicates that the [`App`]'s schedule should run repeatedly.
Expand All @@ -32,57 +31,48 @@ impl Default for RunMode {
}
}

/// The configuration information for the [`ScheduleRunnerPlugin`].
/// Configures an [`App`] to run its [`Schedule`](bevy_ecs::schedule::Schedule) according to a given
/// [`RunMode`].
///
/// It gets added as a [`Resource`](bevy_ecs::system::Resource) inside of the [`ScheduleRunnerPlugin`].
#[derive(Copy, Clone, Default, Resource)]
pub struct ScheduleRunnerSettings {
/// [`ScheduleRunnerPlugin`] is included in the
/// [`MinimalPlugins`](https://docs.rs/bevy/latest/bevy/struct.MinimalPlugins.html) plugin group.
///
/// [`ScheduleRunnerPlugin`] is *not* included in the
/// [`DefaultPlugins`](https://docs.rs/bevy/latest/bevy/struct.DefaultPlugins.html) plugin group
/// which assumes that the [`Schedule`](bevy_ecs::schedule::Schedule) will be executed by other means:
/// typically, the `winit` event loop
/// (see [`WinitPlugin`](https://docs.rs/bevy/latest/bevy/winit/struct.WinitPlugin.html))
/// executes the schedule making [`ScheduleRunnerPlugin`] unnecessary.
#[derive(Default)]
pub struct ScheduleRunnerPlugin {
/// Determines whether the [`Schedule`](bevy_ecs::schedule::Schedule) is run once or repeatedly.
pub run_mode: RunMode,
}

impl ScheduleRunnerSettings {
impl ScheduleRunnerPlugin {
/// See [`RunMode::Once`].
pub fn run_once() -> Self {
ScheduleRunnerSettings {
ScheduleRunnerPlugin {
run_mode: RunMode::Once,
}
}

/// See [`RunMode::Loop`].
pub fn run_loop(wait_duration: Duration) -> Self {
ScheduleRunnerSettings {
ScheduleRunnerPlugin {
run_mode: RunMode::Loop {
wait: Some(wait_duration),
},
}
}
}

/// Configures an [`App`] to run its [`Schedule`](bevy_ecs::schedule::Schedule) according to a given
/// [`RunMode`].
///
/// [`ScheduleRunnerPlugin`] is included in the
/// [`MinimalPlugins`](https://docs.rs/bevy/latest/bevy/struct.MinimalPlugins.html) plugin group.
///
/// [`ScheduleRunnerPlugin`] is *not* included in the
/// [`DefaultPlugins`](https://docs.rs/bevy/latest/bevy/struct.DefaultPlugins.html) plugin group
/// which assumes that the [`Schedule`](bevy_ecs::schedule::Schedule) will be executed by other means:
/// typically, the `winit` event loop
/// (see [`WinitPlugin`](https://docs.rs/bevy/latest/bevy/winit/struct.WinitPlugin.html))
/// executes the schedule making [`ScheduleRunnerPlugin`] unnecessary.
#[derive(Default)]
pub struct ScheduleRunnerPlugin;

impl Plugin for ScheduleRunnerPlugin {
fn build(&self, app: &mut App) {
let settings = app
.world
.get_resource_or_insert_with(ScheduleRunnerSettings::default)
.to_owned();
let run_mode = self.run_mode;
app.set_runner(move |mut app: App| {
let mut app_exit_event_reader = ManualEventReader::<AppExit>::default();
match settings.run_mode {
match run_mode {
RunMode::Once => {
app.update();
}
Expand Down
18 changes: 9 additions & 9 deletions examples/app/headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
//! bevy = { version = "*", default-features = false }
//! # replace "*" with the most recent version of bevy

use bevy::{app::ScheduleRunnerSettings, prelude::*, utils::Duration};
use bevy::{app::ScheduleRunnerPlugin, prelude::*, utils::Duration};

fn main() {
// this app runs once
// This app runs once
App::new()
.insert_resource(ScheduleRunnerSettings::run_once())
.add_plugins(MinimalPlugins)
.add_plugins(MinimalPlugins.set(ScheduleRunnerPlugin::run_once()))
.add_systems(Update, hello_world_system)
.run();

// this app loops forever at 60 fps
// This app loops forever at 60 fps
App::new()
.insert_resource(ScheduleRunnerSettings::run_loop(Duration::from_secs_f64(
1.0 / 60.0,
)))
.add_plugins(MinimalPlugins)
.add_plugins(
MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(
1.0 / 60.0,
))),
)
.add_systems(Update, counter)
.run();
}
Expand Down
9 changes: 3 additions & 6 deletions examples/ecs/ecs_guide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
//! We will now make a simple "game" to illustrate what Bevy's ECS looks like in practice.

use bevy::{
app::{AppExit, ScheduleRunnerPlugin, ScheduleRunnerSettings},
app::{AppExit, ScheduleRunnerPlugin},
prelude::*,
utils::Duration,
};
Expand Down Expand Up @@ -253,13 +253,10 @@ fn main() {
App::new()
// Resources that implement the Default or FromWorld trait can be added like this:
.init_resource::<GameState>()
// Some systems are configured by adding their settings as a resource.
.insert_resource(ScheduleRunnerSettings::run_loop(Duration::from_secs(5)))
// Plugins are just a grouped set of app builder calls (just like we're doing here).
// We could easily turn our game into a plugin, but you can check out the plugin example for
// that :) The plugin below runs our app's "system schedule" once every 5 seconds
// (configured above).
.add_plugin(ScheduleRunnerPlugin::default())
// that :) The plugin below runs our app's "system schedule" once every 5 seconds.
.add_plugin(ScheduleRunnerPlugin::run_loop(Duration::from_secs(5)))
// `Startup` systems run exactly once BEFORE all other systems. These are generally used for
// app initialization code (ex: adding entities and resources)
.add_systems(Startup, startup_system)
Expand Down

0 comments on commit 86aaad7

Please sign in to comment.