ecs: fix BatchedSystem, implement ways for `Criteria`s to modify the world before and after execution
This commit is contained in:
parent
e2c6b557bb
commit
53837d469b
|
@ -1,9 +1,9 @@
|
|||
use lyra_ecs::World;
|
||||
use tracing::debug_span;
|
||||
use tracing::{debug_span, instrument};
|
||||
|
||||
use crate::Access;
|
||||
|
||||
use super::{System, Criteria, IntoSystem};
|
||||
use super::{Criteria, GraphExecutorError, IntoSystem, System};
|
||||
|
||||
/// A system that executes a batch of systems in order that they were given.
|
||||
/// You can optionally add criteria that must pass before the systems are
|
||||
|
@ -13,6 +13,7 @@ pub struct BatchedSystem {
|
|||
systems: Vec<Box<dyn System>>,
|
||||
criteria: Vec<Box<dyn Criteria>>,
|
||||
criteria_checks: u32,
|
||||
did_run: bool,
|
||||
}
|
||||
|
||||
impl BatchedSystem {
|
||||
|
@ -47,6 +48,7 @@ impl System for BatchedSystem {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, world))]
|
||||
fn execute(&mut self, world: std::ptr::NonNull<World>) -> anyhow::Result<()> {
|
||||
let mut can_run = true;
|
||||
let mut check_again = false;
|
||||
|
@ -69,13 +71,26 @@ impl System for BatchedSystem {
|
|||
}
|
||||
|
||||
if can_run {
|
||||
for criteria in self.criteria.iter_mut() {
|
||||
criteria.modify_world(world);
|
||||
}
|
||||
|
||||
for (idx, system) in self.systems.iter_mut().enumerate() {
|
||||
let sys_span = debug_span!("batch", system=tracing::field::Empty);
|
||||
sys_span.record("system", idx);
|
||||
let _e = sys_span.enter();
|
||||
let span = debug_span!("batch", system=idx);
|
||||
let _e = span.enter();
|
||||
|
||||
system.execute(world)?;
|
||||
|
||||
/* let deferred_span = debug_span!("deferred_exec");
|
||||
let _e = deferred_span.enter();
|
||||
|
||||
if let Err(e) = system.execute_deferred(world)
|
||||
.map_err(|e| GraphExecutorError::Command(e)) {
|
||||
return Err(e.into());
|
||||
} */
|
||||
}
|
||||
|
||||
self.did_run = true;
|
||||
}
|
||||
|
||||
if check_again {
|
||||
|
@ -87,9 +102,26 @@ impl System for BatchedSystem {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn execute_deferred(&mut self, _: std::ptr::NonNull<World>) -> anyhow::Result<()> {
|
||||
todo!()
|
||||
|
||||
#[instrument(skip(self, world))]
|
||||
fn execute_deferred(&mut self, world: std::ptr::NonNull<World>) -> anyhow::Result<()> {
|
||||
if self.did_run {
|
||||
for (idx, system) in self.systems.iter_mut().enumerate() {
|
||||
let span = debug_span!("batch", system=idx);
|
||||
let _e = span.enter();
|
||||
|
||||
system.execute_deferred(world)
|
||||
.map_err(|e| GraphExecutorError::Command(e))?;
|
||||
}
|
||||
|
||||
for criteria in self.criteria.iter_mut() {
|
||||
criteria.undo_world_modifications(world);
|
||||
}
|
||||
}
|
||||
|
||||
self.did_run = false;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,13 +26,17 @@ pub trait Criteria {
|
|||
/// * `world` - The ecs world.
|
||||
/// * `check_count` - The amount of times the Criteria has been checked this tick.
|
||||
fn can_run(&mut self, world: NonNull<World>, check_count: u32) -> CriteriaSchedule;
|
||||
}
|
||||
|
||||
impl<F> Criteria for F
|
||||
where F: FnMut(&mut World, u32) -> CriteriaSchedule
|
||||
{
|
||||
fn can_run(&mut self, mut world: NonNull<World>, check_count: u32) -> CriteriaSchedule {
|
||||
let world_mut = unsafe { world.as_mut() };
|
||||
self(world_mut, check_count)
|
||||
}
|
||||
/// Modify the world after the [`Criteria`] in the system batch allows the systems to run.
|
||||
///
|
||||
/// This can be great if this Criteria limits the execution of systems based off of resources.
|
||||
/// A `FixedTimestep` criteria would use this to replace the [`DeltaTime`] resource in the
|
||||
/// world to match the timestep time.
|
||||
fn modify_world(&mut self, world: NonNull<World>);
|
||||
|
||||
/// Undo modifications to the world after the systems in the batch have been executed.
|
||||
///
|
||||
/// The `FixedTimestep` criteria (see docs for [`Criteria::modify_world`]) uses this
|
||||
/// to replace the [`DeltaTime`] resource with its original value before it was replaced.
|
||||
fn undo_world_modifications(&mut self, world: NonNull<World>);
|
||||
}
|
Loading…
Reference in New Issue