use std::collections::HashMap;
use crate::core::{Entity, System, SystemId, SystemContext, SystemError, InputState};
use super::camera::Camera;
use super::asset::AssetManager;
pub struct SystemScheduler {
systems: HashMap<SystemId, Box<dyn System>>,
initialized: bool,
frame_number: u64,
total_time: f32,
}
impl SystemScheduler {
pub fn new() -> Self {
Self {
systems: HashMap::new(),
initialized: false,
frame_number: 0,
total_time: 0.0,
}
}
pub fn register_system<T: System + 'static>(&mut self, mut system: T) -> Result<(), SystemError> {
let id = system.id();
if self.initialized {
system.initialize().map_err(|e|
SystemError::InitializationFailed(format!("Failed to initialize {}: {}", system.name(), e))
)?;
}
self.systems.insert(id, Box::new(system));
Ok(())
}
pub fn initialize(&mut self) -> Result<(), SystemError> {
if self.initialized {
return Ok(());
}
for system in self.systems.values_mut() {
system.initialize().map_err(|e|
SystemError::InitializationFailed(format!("Failed to initialize {}: {}", system.name(), e))
)?;
}
self.initialized = true;
Ok(())
}
pub fn update(&mut self, delta_time: f32, entities: &mut Vec<Entity>, input: &InputState, camera: &Camera, asset_manager: &mut AssetManager) -> Result<(), SystemError> {
if !self.initialized {
return Err(SystemError::RuntimeError("Scheduler not initialized".to_string()));
}
self.frame_number += 1;
self.total_time += delta_time;
let mut context = SystemContext::new(
delta_time,
self.frame_number,
self.total_time,
entities,
input,
camera,
asset_manager,
);
for system in self.systems.values_mut() {
if system.is_enabled() {
system.update(&mut context).map_err(|e| {
SystemError::UpdateFailed(format!("System {} failed: {}", system.name(), e))
})?;
}
}
Ok(())
}
pub fn shutdown(&mut self) -> Result<(), SystemError> {
for system in self.systems.values_mut() {
system.shutdown().map_err(|e| {
SystemError::ShutdownFailed(format!("Failed to shutdown {}: {}", system.name(), e))
})?;
}
self.systems.clear();
self.initialized = false;
Ok(())
}
}
impl Default for SystemScheduler {
fn default() -> Self {
Self::new()
}
}