unen_app 0.0.3

Application crate for UnnamedEngine
Documentation
use std::{
    sync::{
        atomic::{AtomicBool, Ordering},
        Arc,
    },
    thread,
    time::Duration,
};

use signal_hook::{
    consts::{SIGINT, SIGTERM},
    flag,
};

use crate::{
    app::AppState,
    command::CommandRegistry,
    stage::{StageContainer, START, STEP, STOP},
};

pub trait Runner: Send + Sync + 'static {
    fn run(&mut self, data: RunnerData) -> RunnerData;
}

pub struct RunnerData {
    pub stages: StageContainer,
    pub state: AppState,
    pub term: Arc<AtomicBool>,
    pub commands: CommandRegistry,
}

#[derive(Default)]
pub struct MininalRunner;

impl MininalRunner {
    pub fn new_boxed() -> Box<dyn Runner> {
        Box::new(Self {})
    }
}

impl Runner for MininalRunner {
    fn run(&mut self, data: RunnerData) -> RunnerData {
        let RunnerData {
            mut stages,
            mut state,
            term,
            mut commands,
        } = data;

        state = stages.get(START).execute_all(state, &mut commands);

        flag::register(SIGINT, Arc::clone(&term)).expect("Failed to register SIGINT flag.");
        flag::register(SIGTERM, Arc::clone(&term)).expect("Failed to register SIGTERM flag.");

        while !term.load(Ordering::Relaxed) {
            state = stages.get(STEP).execute_all(state, &mut commands);

            thread::sleep(Duration::from_millis(1));
        }

        state = stages.get(STOP).execute_all(state, &mut commands);

        RunnerData {
            stages,
            state,
            term,
            commands,
        }
    }
}