use std::sync::{Arc, Mutex};
use std::collections::HashSet;
#[cfg(feature = "async")]
use std::future::Future;
#[cfg(feature = "async")]
use std::pin::Pin;
pub type TaskId = usize;
pub enum TaskWork {
Static(Box<dyn FnOnce() + Send + 'static>),
Subflow(Box<dyn FnOnce(&mut crate::Subflow) + Send + 'static>),
Condition(Box<dyn FnOnce() -> usize + Send + 'static>),
#[cfg(feature = "async")]
Async(Box<dyn FnOnce() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + 'static>),
}
pub struct TaskNode {
pub id: TaskId,
pub name: String,
pub work: Option<TaskWork>,
pub successors: HashSet<TaskId>,
pub dependents: HashSet<TaskId>,
pub num_dependents: usize,
}
impl TaskNode {
pub fn new(id: TaskId, work: TaskWork) -> Self {
Self {
id,
name: format!("task_{}", id),
work: Some(work),
successors: HashSet::new(),
dependents: HashSet::new(),
num_dependents: 0,
}
}
}
#[derive(Clone)]
pub struct TaskHandle {
pub(crate) id: TaskId,
graph: Arc<Mutex<Vec<TaskNode>>>,
}
impl TaskHandle {
pub(crate) fn new(id: TaskId, graph: Arc<Mutex<Vec<TaskNode>>>) -> Self {
Self { id, graph }
}
pub fn name(self, name: &str) -> Self {
{
let mut graph = self.graph.lock().unwrap();
if let Some(node) = graph.iter_mut().find(|n| n.id == self.id) {
node.name = name.to_string();
}
} self
}
pub fn precede(&self, other: &TaskHandle) {
let mut graph = self.graph.lock().unwrap();
if let Some(node) = graph.iter_mut().find(|n| n.id == self.id) {
node.successors.insert(other.id);
}
if let Some(node) = graph.iter_mut().find(|n| n.id == other.id) {
if node.dependents.insert(self.id) {
node.num_dependents += 1;
}
}
}
pub fn succeed(&self, other: &TaskHandle) {
other.precede(self);
}
pub fn id(&self) -> TaskId {
self.id
}
#[allow(dead_code)]
pub(crate) fn get_id(&self) -> TaskId {
self.id
}
}
pub trait Task {
fn id(&self) -> TaskId;
}
impl Task for TaskHandle {
fn id(&self) -> TaskId {
self.id
}
}