game: Create more stages and generalize them

This commit is contained in:
SeanOMik 2024-01-06 16:49:36 -05:00
parent 4a42989098
commit 6242abb35b
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
4 changed files with 33 additions and 14 deletions

View File

@ -1,7 +1,7 @@
use instant::Instant;
use lyra_ecs::{Component, world::World};
use crate::plugin::Plugin;
use crate::{plugin::Plugin, game::GameStages};
#[derive(Clone, Component)]
pub struct DeltaTime(f32, Option<Instant>);
@ -20,7 +20,10 @@ impl std::ops::DerefMut for DeltaTime {
}
}
fn delta_time_system(world: &mut World) -> anyhow::Result<()> {
/// A system that updates the [`DeltaTime``] resource.
///
/// The resource is updated in the [`GameStages::First`] stage.
pub fn delta_time_system(world: &mut World) -> anyhow::Result<()> {
let now = Instant::now();
let mut delta = world.get_resource_mut::<DeltaTime>();
delta.0 = delta.1.unwrap_or(now).elapsed().as_secs_f32();
@ -34,6 +37,6 @@ pub struct DeltaTimePlugin;
impl Plugin for DeltaTimePlugin {
fn setup(&self, game: &mut crate::game::Game) {
game.world().add_resource(DeltaTime(0.0, None));
game.with_system("delta_time", delta_time_system, &[]);
game.add_system_to_stage(GameStages::First, "delta_time", delta_time_system, &[]);
}
}

View File

@ -17,8 +17,16 @@ use crate::{render::{renderer::{Renderer, BasicRenderer}, window::WindowOptions}
#[derive(Clone, Copy, Hash, Debug)]
pub enum GameStages {
Core,
User,
/// This stage runs before all other stages.
First,
/// This stage runs before `Update`.
PreUpdate,
/// This stage is where most game logic would be.
Update,
/// This stage is ran after `Update`.
PostUpdate,
/// This stage runs after all other stages.
Last,
}
impl Stage for GameStages {}
@ -217,8 +225,11 @@ pub struct Game {
impl Default for Game {
fn default() -> Self {
let mut staged = StagedExecutor::new();
staged.add_stage(GameStages::Core);
staged.add_stage_after(GameStages::Core, GameStages::User);
staged.add_stage(GameStages::First);
staged.add_stage_after(GameStages::First, GameStages::PreUpdate);
staged.add_stage_after(GameStages::PreUpdate, GameStages::Update);
staged.add_stage_after(GameStages::Update, GameStages::PostUpdate);
staged.add_stage_after(GameStages::PostUpdate, GameStages::Last);
Self {
world: Some(World::new()),
@ -247,7 +258,7 @@ impl Game {
<S as IntoSystem<A>>::System: 'static
{
let system_dispatcher = self.system_exec.as_mut().unwrap();
system_dispatcher.add_system_to_stage(GameStages::User, name, system.into_system(), depends);
system_dispatcher.add_system_to_stage(GameStages::Update, name, system.into_system(), depends);
self
}
@ -278,8 +289,13 @@ impl Game {
///
/// # Panics
/// Panics if the stage was not already added to the executor
pub fn add_system_to_stage<ST: Stage, I: IntoSystem<()> + 'static>(&mut self, stage: ST,
name: &str, system: I, depends: &[&str]) -> &mut Self {
pub fn add_system_to_stage<T, S, A>(&mut self, stage: T,
name: &str, system: S, depends: &[&str]) -> &mut Self
where
T: Stage,
S: IntoSystem<A>,
<S as IntoSystem<A>>::System: 'static
{
let system_dispatcher = self.system_exec.as_mut().unwrap();
system_dispatcher.add_system_to_stage(stage, name, system.into_system(), depends);

View File

@ -2,7 +2,7 @@ use std::{collections::HashMap, ops::Deref};
use lyra_ecs::world::World;
use crate::plugin::Plugin;
use crate::{plugin::Plugin, game::GameStages};
use super::{Button, KeyCode, InputButtons};
@ -392,6 +392,6 @@ pub struct InputActionPlugin;
impl Plugin for InputActionPlugin {
fn setup(&self, game: &mut crate::game::Game) {
game.with_system("input_actions", actions_system, &[]);
game.add_system_to_stage(GameStages::PreUpdate, "input_actions", actions_system, &[]);
}
}

View File

@ -4,7 +4,7 @@ use glam::Vec2;
use lyra_ecs::{world::World, system::IntoSystem};
use winit::event::MouseScrollDelta;
use crate::{EventQueue, plugin::Plugin};
use crate::{EventQueue, plugin::Plugin, game::GameStages};
use super::{events::*, InputButtons, InputEvent};
@ -136,6 +136,6 @@ pub struct InputPlugin;
impl Plugin for InputPlugin {
fn setup(&self, game: &mut crate::game::Game) {
game.with_system("input", InputSystem, &[]);
game.add_system_to_stage(GameStages::PreUpdate, "input", InputSystem, &[]);
}
}