renderbug/src/task.rs

146 lines
3.2 KiB
Rust
Raw Normal View History

use std::fmt;
pub trait Task {
fn tick(&mut self) {}
fn start(&mut self) {}
fn stop(&mut self) {}
fn name(&self) -> &'static str;
}
trait ScheduledState: std::fmt::Debug {
fn start(self: Box<Self>) -> Box<dyn ScheduledState>;
fn stop(self: Box<Self>) -> Box<dyn ScheduledState>;
fn tick(self: Box<Self>, task: &mut dyn Task) -> Box<dyn ScheduledState>;
}
#[derive(Debug)]
struct Starting {}
impl ScheduledState for Starting {
fn start(self: Box<Self>) -> Box<dyn ScheduledState> {
self
}
fn stop(self: Box<Self>) -> Box<dyn ScheduledState> {
Box::new(Stopped {})
}
fn tick(self: Box<Self>, task: &mut dyn Task) -> Box<dyn ScheduledState> {
task.start();
Box::new(Running{})
}
}
#[derive(Debug)]
struct Running {}
impl ScheduledState for Running {
fn start(self: Box<Self>) -> Box<dyn ScheduledState> {
self
}
fn stop(self: Box<Self>) -> Box<dyn ScheduledState> {
Box::new(Stopping {})
}
fn tick(self: Box<Self>, task: &mut dyn Task) -> Box<dyn ScheduledState> {
task.tick();
self
}
}
#[derive(Debug)]
struct Stopping {}
impl ScheduledState for Stopping {
fn start(self: Box<Self>) -> Box<dyn ScheduledState> {
Box::new(Running {})
}
fn stop(self: Box<Self>) -> Box<dyn ScheduledState> {
self
}
fn tick(self: Box<Self>, task: &mut dyn Task) -> Box<dyn ScheduledState> {
task.stop();
Box::new(Stopped {})
}
}
#[derive(Debug)]
struct Stopped {}
impl ScheduledState for Stopped {
fn start(self: Box<Self>) -> Box<dyn ScheduledState> {
Box::new(Starting {})
}
fn stop(self: Box<Self>) -> Box<dyn ScheduledState> {
self
}
fn tick(self: Box<Self>, _task: &mut dyn Task) -> Box<dyn ScheduledState> {
self
}
}
struct ScheduledTask {
state: Option<Box<dyn ScheduledState>>,
task: Box<dyn Task>
}
impl std::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<dyn Task>) -> Self {
ScheduledTask {
state: Some(Box::new(Starting{})),
task: task
}
}
fn start(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.start());
}
}
fn stop(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.stop());
}
}
fn tick(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.tick(self.task.as_mut()));
}
}
}
pub struct Scheduler {
tasks: Vec<ScheduledTask>
}
impl Scheduler {
pub fn new(tasks: Vec<Box<dyn Task>>) -> Self {
let mut scheduled = Vec::new();
for task in tasks {
log::info!("Scheduling task {:?}", task.name());
scheduled.push(ScheduledTask::new(task));
}
Scheduler {
tasks: scheduled
}
}
pub fn tick(&mut self) {
for task in &mut self.tasks {
task.tick();
}
}
}