task: rewrite event handling as a step towards event-based subscriptions
This commit is contained in:
85
src/task.rs
85
src/task.rs
@@ -1,17 +1,20 @@
|
||||
use core::fmt;
|
||||
|
||||
use crate::events::{Event, EventBus};
|
||||
use crate::events::{Event, EventBus, Variant};
|
||||
|
||||
pub trait Task: Send {
|
||||
fn tick(&mut self, event: &Event, bus: &mut EventBus) {}
|
||||
fn start(&mut self) {}
|
||||
fn stop(&mut self) {}
|
||||
fn on_ready(&mut self, bus: &mut EventBus) {}
|
||||
fn on_tick(&mut self, bus: &mut EventBus) {}
|
||||
fn on_property_change(&mut self, key: &'static str, value: &Variant, bus: &mut EventBus) {}
|
||||
|
||||
fn start(&mut self, bus: &mut EventBus) {}
|
||||
fn stop(&mut self, bus: &mut EventBus) {}
|
||||
fn name(&self) -> &'static str {
|
||||
core::any::type_name::<Self>()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
enum ScheduledState {
|
||||
Stopped,
|
||||
Start,
|
||||
@@ -36,7 +39,7 @@ impl core::fmt::Debug for ScheduledTask {
|
||||
impl ScheduledTask {
|
||||
fn new(task: Box<dyn Task>) -> Self {
|
||||
ScheduledTask {
|
||||
state: ScheduledState::Start,
|
||||
state: ScheduledState::Stopped,
|
||||
task: task,
|
||||
}
|
||||
}
|
||||
@@ -58,53 +61,87 @@ impl ScheduledTask {
|
||||
}
|
||||
|
||||
fn tick(&mut self, event: &Event, bus: &mut EventBus) {
|
||||
self.state = match self.state {
|
||||
match self.state {
|
||||
ScheduledState::Start => {
|
||||
log::info!("Starting task {}", self.task.name());
|
||||
self.task.start();
|
||||
ScheduledState::Running
|
||||
},
|
||||
ScheduledState::Running => {
|
||||
self.task.tick(event, bus);
|
||||
ScheduledState::Running
|
||||
self.task.start(bus);
|
||||
self.state = ScheduledState::Running
|
||||
},
|
||||
ScheduledState::Stop => {
|
||||
log::info!("Stopping task {}", self.task.name());
|
||||
self.task.stop();
|
||||
ScheduledState::Stopped
|
||||
self.task.stop(bus);
|
||||
self.state = ScheduledState::Stopped
|
||||
},
|
||||
ScheduledState::Stopped => ScheduledState::Stopped
|
||||
_ => ()
|
||||
};
|
||||
|
||||
match self.state {
|
||||
ScheduledState::Running => {
|
||||
match event {
|
||||
Event::Tick => self.task.on_tick(bus),
|
||||
Event::ReadyToRock => self.task.on_ready(bus),
|
||||
Event::PropertyChange(key, value) => self.task.on_property_change(key, value, bus),
|
||||
_ => ()
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FixedSizeScheduler<const TASK_COUNT: usize> {
|
||||
tasks: [Option<ScheduledTask>; TASK_COUNT],
|
||||
tasks: [ScheduledTask; TASK_COUNT],
|
||||
}
|
||||
|
||||
impl<const TASK_COUNT: usize> FixedSizeScheduler<TASK_COUNT> {
|
||||
pub fn new(tasks: [Box<dyn Task>; TASK_COUNT]) -> Self {
|
||||
let mut scheduled = [const { None }; TASK_COUNT];
|
||||
pub fn new(tasks: [Box<dyn Task>; TASK_COUNT]) -> Self {
|
||||
let mut scheduled: [ScheduledTask; TASK_COUNT] = unsafe { std::mem::MaybeUninit::zeroed().assume_init() };
|
||||
let mut idx = 0;
|
||||
for task in tasks {
|
||||
scheduled[idx] = Some(ScheduledTask::new(task));
|
||||
log::info!("Scheduling task {}", task.name());
|
||||
let slot = &mut scheduled[idx];
|
||||
unsafe { std::ptr::write(slot, ScheduledTask::new(task)) };
|
||||
idx += 1;
|
||||
}
|
||||
FixedSizeScheduler {
|
||||
tasks: scheduled
|
||||
}
|
||||
}
|
||||
|
||||
fn find_task(&mut self, name: &str) -> Option<&mut ScheduledTask> {
|
||||
for slot in &mut self.tasks {
|
||||
if slot.task.name() == name {
|
||||
return Some(slot);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<const TASK_COUNT: usize> Scheduler for FixedSizeScheduler<TASK_COUNT> {
|
||||
fn tick(&mut self, event: &Event, bus: &mut EventBus) {
|
||||
for slot in &mut self.tasks {
|
||||
match slot {
|
||||
Some(task) => task.tick(event, bus),
|
||||
_ => ()
|
||||
match event {
|
||||
Event::StartThing(task_name) => {
|
||||
if let Some(slot) = self.find_task(task_name) {
|
||||
log::debug!("Starting {}", task_name);
|
||||
slot.start();
|
||||
}
|
||||
},
|
||||
Event::StopThing(task_name) => {
|
||||
if let Some(slot) = self.find_task(task_name) {
|
||||
log::debug!("Stopping {}", task_name);
|
||||
slot.stop();
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
for slot in &mut self.tasks {
|
||||
slot.tick(event, bus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user