task: move Scheduler into a trait, define static-sized scheduler implementation, expose as a system task runner in platform
This commit is contained in:
parent
132d7c0a33
commit
f789f6ded9
15
src/main.rs
15
src/main.rs
@ -10,7 +10,7 @@ mod mappings;
|
|||||||
mod buffers;
|
mod buffers;
|
||||||
|
|
||||||
use crate::platform::{DefaultBoard, Board};
|
use crate::platform::{DefaultBoard, Board};
|
||||||
use crate::task::{Task, Scheduler};
|
use crate::task::{FixedSizeScheduler, Scheduler};
|
||||||
use crate::render::{Surfaces, Renderer};
|
use crate::render::{Surfaces, Renderer};
|
||||||
use crate::geometry::Rectangle;
|
use crate::geometry::Rectangle;
|
||||||
|
|
||||||
@ -26,20 +26,17 @@ fn main() {
|
|||||||
log::info!("Surface implementation: {}", core::any::type_name_of_val(&output));
|
log::info!("Surface implementation: {}", core::any::type_name_of_val(&output));
|
||||||
|
|
||||||
log::info!("Creating animations");
|
log::info!("Creating animations");
|
||||||
let mut tasks: Vec<Box<dyn Task + 'static>> = vec![
|
let mut animations = FixedSizeScheduler::new([
|
||||||
Box::new(animations::IdleTask::new(&mut surfaces)),
|
Box::new(animations::IdleTask::new(&mut surfaces)),
|
||||||
Box::new(animations::TestPattern::new(surfaces.new_surface(&Rectangle::everything()).unwrap())),
|
Box::new(animations::TestPattern::new(surfaces.new_surface(&Rectangle::everything()).unwrap())),
|
||||||
];
|
];
|
||||||
|
|
||||||
tasks.append(&mut board.system_tasks());
|
let mut renderer = FixedSizeScheduler::new([Box::new(Renderer::new(output, surfaces))]);
|
||||||
tasks.push(Box::new(Renderer::new(output, surfaces)));
|
|
||||||
|
|
||||||
let mut runner = Scheduler::new(tasks);
|
|
||||||
|
|
||||||
log::info!("Runner ready: {:?}", runner);
|
|
||||||
|
|
||||||
log::info!("Ready to rock and roll");
|
log::info!("Ready to rock and roll");
|
||||||
loop {
|
loop {
|
||||||
runner.tick();
|
animations.tick();
|
||||||
|
system.tick();
|
||||||
|
renderer.tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ use rgb::Rgb;
|
|||||||
|
|
||||||
use super::Board;
|
use super::Board;
|
||||||
|
|
||||||
|
use crate::task::FixedSizeScheduler;
|
||||||
use crate::task::Task;
|
use crate::task::Task;
|
||||||
use crate::buffers::{Pixbuf, SurfacePool};
|
use crate::buffers::{Pixbuf, SurfacePool};
|
||||||
use crate::mappings::StrideMapping;
|
use crate::mappings::StrideMapping;
|
||||||
@ -34,12 +35,14 @@ use crate::buffers::SimpleSurface as SurfaceType;
|
|||||||
pub struct Esp32Board<'a> {
|
pub struct Esp32Board<'a> {
|
||||||
output: Option<<Self as Board>::Output>,
|
output: Option<<Self as Board>::Output>,
|
||||||
surfaces: Option<SurfacePool<SurfaceType>>,
|
surfaces: Option<SurfacePool<SurfaceType>>,
|
||||||
tasks: Option<Vec<Box<dyn Task>>>
|
sys_loop: EspSystemEventLoop,
|
||||||
|
modem: Option<Modem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Board for Esp32Board<'a> {
|
impl<'a> Board for Esp32Board<'a> {
|
||||||
type Output = StrideOutput<[Rgb<u8>; 310], FastWs2812Esp32Rmt<'a>>;
|
type Output = StrideOutput<[Rgb<u8>; 310], FastWs2812Esp32Rmt<'a>>;
|
||||||
type Surfaces = SurfacePool<SurfaceType>;
|
type Surfaces = SurfacePool<SurfaceType>;
|
||||||
|
type Scheduler = FixedSizeScheduler<2>;
|
||||||
|
|
||||||
fn take() -> Self {
|
fn take() -> Self {
|
||||||
// It is necessary to call this function once. Otherwise some patches to the runtime
|
// It is necessary to call this function once. Otherwise some patches to the runtime
|
||||||
@ -51,7 +54,6 @@ impl<'a> Board for Esp32Board<'a> {
|
|||||||
|
|
||||||
let peripherals = Peripherals::take().unwrap();
|
let peripherals = Peripherals::take().unwrap();
|
||||||
let sys_loop = EspSystemEventLoop::take().unwrap();
|
let sys_loop = EspSystemEventLoop::take().unwrap();
|
||||||
let nvs = EspDefaultNvsPartition::take().unwrap();
|
|
||||||
|
|
||||||
let channel = peripherals.rmt.channel0;
|
let channel = peripherals.rmt.channel0;
|
||||||
let pins = peripherals.pins;
|
let pins = peripherals.pins;
|
||||||
@ -74,10 +76,6 @@ impl<'a> Board for Esp32Board<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let tasks: Vec<Box<dyn Task>> = vec![
|
|
||||||
Box::new(WifiTask::new(peripherals.modem, sys_loop.clone(), &nvs)),
|
|
||||||
];
|
|
||||||
|
|
||||||
const POWER_VOLTS : u32 = 5;
|
const POWER_VOLTS : u32 = 5;
|
||||||
const POWER_MA : u32 = 500;
|
const POWER_MA : u32 = 500;
|
||||||
const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA;
|
const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA;
|
||||||
@ -92,7 +90,8 @@ impl<'a> Board for Esp32Board<'a> {
|
|||||||
Esp32Board {
|
Esp32Board {
|
||||||
surfaces: Some(SurfacePool::new()),
|
surfaces: Some(SurfacePool::new()),
|
||||||
output: Some(output),
|
output: Some(output),
|
||||||
tasks: Some(tasks),
|
modem: Some(peripherals.modem),
|
||||||
|
sys_loop: sys_loop.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,8 +103,11 @@ impl<'a> Board for Esp32Board<'a> {
|
|||||||
self.surfaces.take().unwrap()
|
self.surfaces.take().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_tasks(&mut self) -> Vec<Box<dyn Task>> {
|
fn system_tasks(&mut self) -> Self::Scheduler {
|
||||||
self.tasks.take().unwrap()
|
let nvs = EspDefaultNvsPartition::take().unwrap();
|
||||||
|
FixedSizeScheduler::new([
|
||||||
|
Box::new(WifiTask::new(self.modem.take().unwrap(), self.sys_loop.clone(), &nvs)),
|
||||||
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,14 +9,15 @@ pub mod esp32;
|
|||||||
pub type DefaultBoard = esp32::Esp32Board;
|
pub type DefaultBoard = esp32::Esp32Board;
|
||||||
|
|
||||||
use crate::render::{Output, Surfaces};
|
use crate::render::{Output, Surfaces};
|
||||||
use crate::task::Task;
|
use crate::task::Scheduler;
|
||||||
|
|
||||||
pub trait Board {
|
pub trait Board {
|
||||||
type Output: Output;
|
type Output: Output;
|
||||||
type Surfaces: Surfaces;
|
type Surfaces: Surfaces;
|
||||||
|
type Scheduler: Scheduler;
|
||||||
|
|
||||||
fn take() -> Self;
|
fn take() -> Self;
|
||||||
fn output(&mut self) -> Self::Output;
|
fn output(&mut self) -> Self::Output;
|
||||||
fn surfaces(&mut self) -> Self::Surfaces;
|
fn surfaces(&mut self) -> Self::Surfaces;
|
||||||
fn system_tasks(&mut self) -> Vec<Box<dyn Task>>;
|
fn system_tasks(&mut self) -> Self::Scheduler;
|
||||||
}
|
}
|
32
src/task.rs
32
src/task.rs
@ -77,25 +77,35 @@ impl ScheduledTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Scheduler {
|
pub struct FixedSizeScheduler<const TASK_COUNT: usize> {
|
||||||
tasks: Vec<ScheduledTask>,
|
tasks: [Option<ScheduledTask>; TASK_COUNT],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scheduler {
|
impl<const TASK_COUNT: usize> FixedSizeScheduler<TASK_COUNT> {
|
||||||
pub fn new(tasks: Vec<Box<dyn Task>>) -> Self {
|
pub fn new(tasks: [Box<dyn Task>; TASK_COUNT]) -> Self {
|
||||||
let mut scheduled = Vec::new();
|
let mut scheduled = [const { None }; TASK_COUNT];
|
||||||
|
let mut idx = 0;
|
||||||
for task in tasks {
|
for task in tasks {
|
||||||
log::info!("Scheduling task {} {:?}", task.name(), task);
|
scheduled[idx] = Some(ScheduledTask::new(task));
|
||||||
scheduled.push(ScheduledTask::new(task));
|
idx += 1;
|
||||||
}
|
}
|
||||||
Scheduler {
|
FixedSizeScheduler {
|
||||||
tasks: scheduled
|
tasks: scheduled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tick(&mut self) {
|
impl<const TASK_COUNT: usize> Scheduler for FixedSizeScheduler<TASK_COUNT> {
|
||||||
for task in &mut self.tasks {
|
fn tick(&mut self) {
|
||||||
task.tick();
|
for slot in &mut self.tasks {
|
||||||
|
match slot {
|
||||||
|
Some(task) => task.tick(),
|
||||||
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Scheduler {
|
||||||
|
fn tick(&mut self);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user