use core::fmt; pub trait Task: Send { fn tick(&mut self) {} fn start(&mut self) {} fn stop(&mut self) {} fn name(&self) -> &'static str { core::any::type_name::() } } #[derive(Debug, Copy, Clone)] enum ScheduledState { Stopped, Start, Running, Stop } struct ScheduledTask { state: ScheduledState, task: Box, } impl core::fmt::Debug for ScheduledTask { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ScheduledTask") .field("task", &self.task.name()) .field("state", &self.state) .finish() } } impl ScheduledTask { fn new(task: Box) -> Self { ScheduledTask { state: ScheduledState::Start, task: task, } } fn start(&mut self) { self.state = match self.state { ScheduledState::Stopped => ScheduledState::Start, ScheduledState::Stop => ScheduledState::Running, _ => self.state } } fn stop(&mut self) { self.state = match self.state { ScheduledState::Running => ScheduledState::Stop, ScheduledState::Start => ScheduledState::Stopped, _ => self.state } } fn tick(&mut self) { self.state = match self.state { ScheduledState::Start => { log::info!("Starting task {}", self.task.name()); self.task.start(); ScheduledState::Running }, ScheduledState::Running => { self.task.tick(); ScheduledState::Running }, ScheduledState::Stop => { log::info!("Stopping task {}", self.task.name()); self.task.stop(); ScheduledState::Stopped }, ScheduledState::Stopped => ScheduledState::Stopped } } } #[derive(Debug)] pub struct FixedSizeScheduler { tasks: [Option; TASK_COUNT], } impl FixedSizeScheduler { pub fn new(tasks: [Box; TASK_COUNT]) -> Self { let mut scheduled = [const { None }; TASK_COUNT]; let mut idx = 0; for task in tasks { scheduled[idx] = Some(ScheduledTask::new(task)); idx += 1; } FixedSizeScheduler { tasks: scheduled } } } impl Scheduler for FixedSizeScheduler { fn tick(&mut self) { for slot in &mut self.tasks { match slot { Some(task) => task.tick(), _ => () } } } } pub trait Scheduler { fn tick(&mut self); }