use crate::common::{ListenerId, TaskId};
use crate::events::AutomationEvent;
use tokio::sync::broadcast;
pub type LifecycleStep = Box<dyn FnMut() + Send + Sync>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RepetitionPolicy {
RunOnce,
RunNTimes(u32),
Repeat,
}
#[doc(hidden)]
pub(crate) struct LifecycleLoop {
pub id: TaskId,
pub listener_id: ListenerId,
steps: Vec<LifecycleStep>,
current_step: usize,
repetition_policy: RepetitionPolicy,
run_count: u32,
}
impl LifecycleLoop {
pub(crate) fn new(
id: TaskId,
listener_id: ListenerId,
steps: Vec<LifecycleStep>,
repetition_policy: RepetitionPolicy,
) -> Self {
Self {
id,
listener_id,
steps,
current_step: 0,
repetition_policy,
run_count: 0,
}
}
pub(crate) fn advance(
&mut self,
automation_event_sender: &broadcast::Sender<AutomationEvent>,
) -> bool {
if self.steps.is_empty() {
return true;
}
if let Some(step) = self.steps.get_mut(self.current_step) {
(step)();
}
automation_event_sender
.send(AutomationEvent::LifecycleStepAdvanced {
id: self.id,
step_index: self.current_step,
})
.ok();
self.current_step += 1;
if self.current_step >= self.steps.len() {
self.run_count += 1;
self.current_step = 0;
match self.repetition_policy {
RepetitionPolicy::RunOnce => {
automation_event_sender
.send(AutomationEvent::LifecycleCompleted { id: self.id })
.ok();
return true;
}
RepetitionPolicy::RunNTimes(n) => {
if self.run_count >= n {
automation_event_sender
.send(AutomationEvent::LifecycleCompleted { id: self.id })
.ok();
return true;
} else {
automation_event_sender
.send(AutomationEvent::LifecycleLooped { id: self.id })
.ok();
}
}
RepetitionPolicy::Repeat => {
automation_event_sender
.send(AutomationEvent::LifecycleLooped { id: self.id })
.ok();
}
}
}
false
}
}