use bevy_ecs::prelude::*;
use bevy_ecs::schedule::{ExecutorKind, ScheduleLabel};
#[derive(ScheduleLabel, Debug, Clone, PartialEq, Eq, Hash)]
pub struct Startup;
pub struct Engine {
world: World,
startup_schedule: Schedule,
stage_schedules: [Schedule; 5],
}
impl Engine {
#[must_use]
pub fn new() -> Self {
use crate::schedule::UpdateStage;
let parallel = {
#[cfg(target_arch = "wasm32")]
{
ExecutorKind::SingleThreaded
}
#[cfg(not(target_arch = "wasm32"))]
{
ExecutorKind::MultiThreaded
}
};
let mut startup = Schedule::new(Startup);
startup.set_executor_kind(ExecutorKind::SingleThreaded);
let make_stage = |label: UpdateStage| {
let mut s = Schedule::new(label);
s.set_executor_kind(parallel);
s
};
Self {
world: World::new(),
startup_schedule: startup,
stage_schedules: [
make_stage(UpdateStage::Input),
make_stage(UpdateStage::Physics),
make_stage(UpdateStage::Update),
make_stage(UpdateStage::Render),
make_stage(UpdateStage::PostUpdate),
],
}
}
pub const fn world_mut(&mut self) -> &mut World {
&mut self.world
}
pub const fn world(&self) -> &World {
&self.world
}
pub const fn startup_schedule_mut(&mut self) -> &mut Schedule {
&mut self.startup_schedule
}
pub const fn stage_schedule_mut(
&mut self,
stage: crate::schedule::UpdateStage,
) -> &mut Schedule {
&mut self.stage_schedules[stage as usize]
}
pub fn run_startup(&mut self) {
self.startup_schedule.run(&mut self.world);
}
pub fn run_stages(&mut self) {
const STAGE_COUNT: usize = 5;
for i in 0..STAGE_COUNT {
self.stage_schedules[i].run(&mut self.world);
if i < STAGE_COUNT - 1 {
self.world.flush();
}
}
}
pub fn run_stages_no_render(&mut self) {
const STAGE_COUNT: usize = 5;
const RENDER_IDX: usize = 3;
for i in 0..STAGE_COUNT {
if i == RENDER_IDX {
continue;
}
self.stage_schedules[i].run(&mut self.world);
if i < STAGE_COUNT - 1 {
self.world.flush();
}
}
}
pub fn run_logic_tick(&mut self) {
for i in 0..3usize {
self.stage_schedules[i].run(&mut self.world);
self.world.flush();
}
}
pub fn run_render_and_post(&mut self) {
self.stage_schedules[3].run(&mut self.world);
self.world.flush();
self.stage_schedules[4].run(&mut self.world);
}
}
impl Default for Engine {
fn default() -> Self {
Self::new()
}
}