use crate::error::{BeaverError, BeaverResult};
use crate::listener::WorkListener;
use crate::task::{Task, TaskId};
use crate::work::Work;
use crate::work_fn::BoxWork;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
pub struct TimeIntervalTask {
pub(crate) id: TaskId,
pub(crate) work: BoxWork,
pub(crate) intervals: Box<[u64]>,
pub(crate) tag: Option<String>,
pub(crate) listener: Option<Arc<dyn WorkListener>>,
pub(crate) interrupted: AtomicBool,
}
pub struct TimeIntervalBuilder {
work: Option<BoxWork>,
intervals: Vec<u64>,
tag: Option<String>,
listener: Option<Arc<dyn WorkListener>>,
}
impl TimeIntervalBuilder {
pub fn new<W>(work: W) -> Self
where
W: Work + Send + 'static,
{
TimeIntervalBuilder {
work: Some(Box::new(work)),
intervals: vec![1000],
tag: None,
listener: None,
}
}
pub fn intervals_millis(mut self, millis: impl Into<Vec<u64>>) -> Self {
self.intervals = millis.into();
self
}
pub fn tag(mut self, tag: impl Into<String>) -> Self {
self.tag = Some(tag.into());
self
}
pub fn listener(mut self, listener: Arc<dyn WorkListener>) -> Self {
self.listener = Some(listener);
self
}
pub fn build(self) -> BeaverResult<Arc<Task>> {
let work = self.work.ok_or(BeaverError::BuilderMissingField("work"))?;
let intervals: Box<[u64]> = if self.intervals.is_empty() {
[0].into()
} else {
self.intervals.into()
};
Ok(Arc::new(Task::TimeInterval(TimeIntervalTask {
id: TaskId::new(),
work,
intervals,
tag: self.tag,
listener: self.listener,
interrupted: AtomicBool::new(false),
})))
}
}