use std::sync::Arc;
use oneshot::Receiver;
use oneshot::channel;
use crate::hook::{
TaskHook,
next_task_id,
};
use super::task_execution_error::TaskResult;
use super::task_handle::TaskHandle;
use super::task_slot::TaskSlot;
use super::task_state::TaskState;
use super::tracked_task::TrackedTask;
pub struct TaskEndpointPair<R, E> {
receiver: Receiver<TaskResult<R, E>>,
state: Arc<TaskState<R, E>>,
}
impl<R, E> TaskEndpointPair<R, E> {
#[inline]
pub fn new() -> Self {
Self::with_optional_hook(None)
}
#[inline]
pub fn with_hook(hook: Arc<dyn TaskHook>) -> Self {
Self::with_optional_hook(Some(hook))
}
#[inline]
pub(crate) fn with_optional_hook(hook: Option<Arc<dyn TaskHook>>) -> Self {
let (sender, receiver) = channel();
Self {
receiver,
state: Arc::new(TaskState::new(next_task_id(), sender, hook)),
}
}
#[inline]
pub fn into_parts(self) -> (TaskHandle<R, E>, TaskSlot<R, E>) {
let handle = TaskHandle::new(Arc::clone(&self.state), self.receiver);
let slot = TaskSlot { state: self.state };
(handle, slot)
}
#[inline]
pub fn into_tracked_parts(self) -> (TrackedTask<R, E>, TaskSlot<R, E>) {
let handle = TaskHandle::new(Arc::clone(&self.state), self.receiver);
let tracked = TrackedTask::new(handle);
let slot = TaskSlot { state: self.state };
(tracked, slot)
}
}
impl<R, E> Default for TaskEndpointPair<R, E> {
#[inline]
fn default() -> Self {
Self::new()
}
}