use std::sync::{atomic::AtomicBool, Arc};
use crate::{
command::CommandRegistry,
runner::{MininalRunner, Runner, RunnerData},
stage::{Stage, StageContainer},
system::System,
};
pub fn create_app() -> App {
App::default()
}
#[derive(Debug, Default)]
pub struct AppState;
pub struct App {
state: AppState,
runner: Box<dyn Runner>,
stages: StageContainer,
commands: CommandRegistry,
}
impl Default for App {
fn default() -> Self {
Self {
runner: MininalRunner::new_boxed(),
state: AppState,
stages: StageContainer::default(),
commands: CommandRegistry::default(),
}
}
}
impl App {
pub fn run(self) {
let App {
state,
mut runner,
stages,
commands,
} = self;
let term = Arc::new(AtomicBool::new(false));
let data = RunnerData {
stages,
state,
term,
commands,
};
runner.as_mut().run(data);
println!();
tracing::info!("Successfully terminated engine.");
tracing::info!("See you later :D");
}
pub fn system<S: Stage, M: System>(&mut self, stage: S, system: M) -> &mut Self {
let system_name = system.name();
let stage_name = stage.name();
self.stages.get(stage).push(system);
tracing::info!("Attached {} system to {} stage.", system_name, stage_name);
self
}
pub fn stage<S: Stage>(&mut self, stage: S) -> &mut Self {
let stage_name = stage.name();
self.stages.insert(stage);
tracing::info!("Inserted '{}' stage.", stage_name);
self
}
pub fn runner<R: Runner>(&mut self, runner: R) -> &mut Self {
self.runner = Box::new(runner);
self
}
}