use crate::{
codelet::{CodeletInstance, Vise},
prelude::{Codelet, Sequence},
};
use core::time::Duration;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ScheduleId(pub usize);
impl Into<usize> for ScheduleId {
fn into(self) -> usize {
self.0
}
}
pub struct ScheduleBuilder {
pub name: String,
pub thread_id: usize,
pub sequences: Vec<Sequence>,
pub max_step_count: Option<usize>,
pub period: Option<Duration>,
}
impl ScheduleBuilder {
#[must_use]
pub fn new() -> Self {
Self {
name: String::new(),
thread_id: 0,
sequences: Vec::new(),
max_step_count: None,
period: None,
}
}
#[must_use]
pub fn with_name<S: Into<String>>(mut self, name: S) -> Self {
self.name = name.into();
self
}
#[must_use]
pub fn with_thread_id(mut self, thread_id: usize) -> Self {
self.thread_id = thread_id;
self
}
#[must_use]
pub fn with_period(mut self, period: Duration) -> Self {
self.period = Some(period);
self
}
#[must_use]
pub fn with_max_step_count(mut self, max_step_count: usize) -> Self {
self.max_step_count = Some(max_step_count);
self
}
#[must_use]
pub fn with<A: Schedulable>(mut self, x: A) -> Self {
x.schedule(&mut self);
self
}
pub fn append<A: Schedulable>(&mut self, x: A) {
x.schedule(self);
}
}
pub trait Schedulable {
fn schedule(self, sched: &mut ScheduleBuilder);
}
impl<C: Codelet + 'static> Schedulable for CodeletInstance<C> {
fn schedule(self, sched: &mut ScheduleBuilder) {
sched.sequences.push(Sequence {
name: "".into(),
vises: vec![Vise::new(self)],
period: None,
});
}
}
impl Schedulable for Sequence {
fn schedule(self, sched: &mut ScheduleBuilder) {
sched.sequences.push(self);
}
}
impl<T1> Schedulable for (T1,)
where
T1: Schedulable,
{
fn schedule(self, sched: &mut ScheduleBuilder) {
self.0.schedule(sched);
}
}
impl<T1, T2> Schedulable for (T1, T2)
where
T1: Schedulable,
T2: Schedulable,
{
fn schedule(self, sched: &mut ScheduleBuilder) {
self.0.schedule(sched);
self.1.schedule(sched);
}
}
impl<T1, T2, T3> Schedulable for (T1, T2, T3)
where
T1: Schedulable,
T2: Schedulable,
T3: Schedulable,
{
fn schedule(self, sched: &mut ScheduleBuilder) {
self.0.schedule(sched);
self.1.schedule(sched);
self.2.schedule(sched);
}
}
impl<T1, T2, T3, T4> Schedulable for (T1, T2, T3, T4)
where
T1: Schedulable,
T2: Schedulable,
T3: Schedulable,
T4: Schedulable,
{
fn schedule(self, sched: &mut ScheduleBuilder) {
self.0.schedule(sched);
self.1.schedule(sched);
self.2.schedule(sched);
self.3.schedule(sched);
}
}
impl<A: Schedulable> Schedulable for Option<A> {
fn schedule(self, sched: &mut ScheduleBuilder) {
if let Some(a) = self {
a.schedule(sched);
}
}
}
impl<A: Schedulable> Schedulable for Box<A> {
fn schedule(self, sched: &mut ScheduleBuilder) {
(*self).schedule(sched);
}
}