2020-07-17 01:47:51 +00:00
|
|
|
use super::{App, AppBuilder};
|
2020-07-26 19:10:18 +00:00
|
|
|
use crate::{
|
|
|
|
app::AppExit,
|
|
|
|
event::{EventReader, Events},
|
2020-08-08 03:22:17 +00:00
|
|
|
plugin::Plugin,
|
2020-07-26 19:10:18 +00:00
|
|
|
};
|
2020-08-22 02:31:46 +00:00
|
|
|
use std::{
|
|
|
|
thread,
|
|
|
|
time::{Duration, Instant},
|
|
|
|
};
|
2020-03-30 18:52:33 +00:00
|
|
|
|
2020-08-09 23:13:04 +00:00
|
|
|
/// Determines the method used to run an [App]'s `Schedule`
|
2020-03-30 18:52:33 +00:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub enum RunMode {
|
2020-04-04 19:43:16 +00:00
|
|
|
Loop { wait: Option<Duration> },
|
2020-03-30 18:52:33 +00:00
|
|
|
Once,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for RunMode {
|
|
|
|
fn default() -> Self {
|
2020-04-04 19:43:16 +00:00
|
|
|
RunMode::Loop { wait: None }
|
2020-03-30 18:52:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-09 23:13:04 +00:00
|
|
|
/// Configures an App to run its [Schedule](bevy_ecs::Schedule) according to a given [RunMode]
|
2020-03-30 18:52:33 +00:00
|
|
|
#[derive(Default)]
|
2020-04-04 20:00:52 +00:00
|
|
|
pub struct ScheduleRunnerPlugin {
|
2020-03-30 18:52:33 +00:00
|
|
|
pub run_mode: RunMode,
|
|
|
|
}
|
|
|
|
|
2020-05-01 20:12:47 +00:00
|
|
|
impl ScheduleRunnerPlugin {
|
|
|
|
pub fn run_once() -> Self {
|
|
|
|
ScheduleRunnerPlugin {
|
|
|
|
run_mode: RunMode::Once,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn run_loop(wait_duration: Duration) -> Self {
|
|
|
|
ScheduleRunnerPlugin {
|
2020-05-06 01:44:32 +00:00
|
|
|
run_mode: RunMode::Loop {
|
|
|
|
wait: Some(wait_duration),
|
|
|
|
},
|
2020-05-01 20:12:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-08 03:22:17 +00:00
|
|
|
impl Plugin for ScheduleRunnerPlugin {
|
2020-04-06 03:19:02 +00:00
|
|
|
fn build(&self, app: &mut AppBuilder) {
|
2020-03-30 18:52:33 +00:00
|
|
|
let run_mode = self.run_mode;
|
2020-04-19 19:13:04 +00:00
|
|
|
app.set_runner(move |mut app: App| {
|
2020-06-04 06:53:00 +00:00
|
|
|
let mut app_exit_event_reader = EventReader::<AppExit>::default();
|
2020-04-19 19:13:04 +00:00
|
|
|
match run_mode {
|
|
|
|
RunMode::Once => {
|
2020-07-10 04:18:35 +00:00
|
|
|
app.schedule.run(&mut app.world, &mut app.resources);
|
2020-04-06 03:19:02 +00:00
|
|
|
}
|
2020-04-19 19:13:04 +00:00
|
|
|
RunMode::Loop { wait } => loop {
|
2020-08-22 02:31:46 +00:00
|
|
|
let start_time = Instant::now();
|
|
|
|
|
2020-07-19 21:23:06 +00:00
|
|
|
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
|
2020-04-28 17:59:42 +00:00
|
|
|
if app_exit_event_reader.latest(&app_exit_events).is_some() {
|
2020-04-19 19:13:04 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-10 04:18:35 +00:00
|
|
|
app.schedule.run(&mut app.world, &mut app.resources);
|
2020-05-03 07:21:32 +00:00
|
|
|
|
2020-07-19 21:23:06 +00:00
|
|
|
if let Some(app_exit_events) = app.resources.get_mut::<Events<AppExit>>() {
|
2020-05-03 07:21:32 +00:00
|
|
|
if app_exit_event_reader.latest(&app_exit_events).is_some() {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-22 02:31:46 +00:00
|
|
|
let end_time = Instant::now();
|
|
|
|
|
2020-04-19 19:13:04 +00:00
|
|
|
if let Some(wait) = wait {
|
2020-08-22 02:31:46 +00:00
|
|
|
let exe_time = end_time - start_time;
|
|
|
|
if exe_time < wait {
|
|
|
|
thread::sleep(wait - exe_time);
|
|
|
|
}
|
2020-04-19 19:13:04 +00:00
|
|
|
}
|
|
|
|
},
|
2020-03-30 18:52:33 +00:00
|
|
|
}
|
2020-04-06 03:19:02 +00:00
|
|
|
});
|
2020-03-30 18:52:33 +00:00
|
|
|
}
|
|
|
|
}
|