use std::sync::Arc;
use qubit_function::Callable;
use super::{
TaskResult,
task_runner::TaskRunner,
task_state::TaskState,
};
pub struct TaskSlot<R, E> {
pub(crate) state: Arc<TaskState<R, E>>,
}
impl<R, E> TaskSlot<R, E> {
#[inline]
pub fn accept(&self) {
let _accepted_now = self.state.accept();
}
#[inline]
pub fn cancel_unstarted(self) -> bool {
self.state.try_cancel_pending()
}
pub(crate) fn start(&self) -> bool {
self.state.try_start(self.state.is_accepted())
}
#[inline]
pub(crate) fn complete(&self, result: TaskResult<R, E>) {
let _completed = self.state.try_complete(result, self.state.is_accepted());
}
#[inline]
pub(crate) fn start_and_complete<F>(&self, task: F) -> bool
where
F: FnOnce() -> TaskResult<R, E>,
{
if !self.start() {
return false;
}
self.complete(task());
true
}
#[inline]
pub fn run<C>(self, task: C) -> bool
where
C: Callable<R, E>,
{
self.start_and_complete(|| TaskRunner::new(task).call())
}
}
impl<R, E> Drop for TaskSlot<R, E> {
#[inline]
fn drop(&mut self) {
let _ignored = self.state.try_drop_unfinished(self.state.is_accepted());
}
}