use downcast_rs::{impl_downcast, Downcast};
use crate::world::World;
use super::{ParallelExecutor, SystemContainer};
pub trait SystemExecutor: Downcast + Send + Sync {
#[inline]
fn systems_changed(&mut self, _systems: &[SystemContainer]) {}
unsafe fn run_systems(&mut self, systems: &mut [SystemContainer], world: &mut World);
}
impl std::fmt::Debug for dyn SystemExecutor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(sequential_executor) = self.downcast_ref::<SequentialExecutor>() {
write!(f, "{sequential_executor:?}")
} else if let Some(parallel_executor) = self.downcast_ref::<ParallelExecutor>() {
write!(f, "{parallel_executor:?}")
} else {
write!(f, "{{Custom SystemExecutor}}")
}
}
}
impl_downcast!(SystemExecutor);
#[derive(Clone, Copy, Debug, Default)]
pub struct SequentialExecutor;
impl SystemExecutor for SequentialExecutor {
#[inline]
unsafe fn run_systems(&mut self, systems: &mut [SystemContainer], world: &mut World) {
for system in systems {
if system.should_run() {
#[cfg(feature = "tracing")]
let _ = tracing::info_span!("system", name = system.name()).entered();
unsafe { system.system_mut().run_unchecked((), world) };
}
}
}
}