task: use a faster enum instead of fancy heap allocations for task states

This commit is contained in:
Victoria Fischer 2024-12-01 21:07:09 +01:00
parent 9af4af6269
commit d6d4d5b76b

View File

@ -9,81 +9,16 @@ pub trait Task: core::fmt::Debug {
} }
} }
trait ScheduledState: std::fmt::Debug { #[derive(Debug, Copy, Clone)]
fn start(self: Box<Self>) -> Box<dyn ScheduledState>; enum ScheduledState {
fn stop(self: Box<Self>) -> Box<dyn ScheduledState>; Stopped,
fn tick(self: Box<Self>, task: &mut dyn Task) -> Box<dyn ScheduledState>; Start,
} Running,
Stop
#[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 { struct ScheduledTask {
state: Option<Box<dyn ScheduledState>>, state: ScheduledState,
task: Box<dyn Task>, task: Box<dyn Task>,
} }
@ -99,26 +34,44 @@ impl std::fmt::Debug for ScheduledTask {
impl ScheduledTask { impl ScheduledTask {
fn new(task: Box<dyn Task>) -> Self { fn new(task: Box<dyn Task>) -> Self {
ScheduledTask { ScheduledTask {
state: Some(Box::new(Starting{})), state: ScheduledState::Start,
task: task, task: task,
} }
} }
fn start(&mut self) { fn start(&mut self) {
if let Some(s) = self.state.take() { self.state = match self.state {
self.state = Some(s.start()); ScheduledState::Stopped => ScheduledState::Start,
ScheduledState::Stop => ScheduledState::Running,
_ => self.state
} }
} }
fn stop(&mut self) { fn stop(&mut self) {
if let Some(s) = self.state.take() { self.state = match self.state {
self.state = Some(s.stop()); ScheduledState::Running => ScheduledState::Stop,
ScheduledState::Start => ScheduledState::Stopped,
_ => self.state
} }
} }
fn tick(&mut self) { fn tick(&mut self) {
if let Some(s) = self.state.take() { self.state = match self.state {
self.state = Some(s.tick(self.task.as_mut())); 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
} }
} }
} }