use std::{
any::{type_name, TypeId},
collections::HashMap,
};
use crate::{any::IntoAny, TaskExecutor};
use super::{
collection::{CollectionData, TasksCollection},
task::Task,
};
#[derive(Default)]
pub struct TaskManager {
collections: HashMap<TypeId, CollectionData>,
}
impl TaskManager {
#[cfg(feature = "egui")]
pub fn ui(&self, ui: &mut egui::Ui) {
for collection in self.collections.values() {
collection.ui(ui)
}
}
pub fn new() -> Self {
Self::default()
}
fn get_collection_mut<'c, C>(&mut self) -> &mut CollectionData
where
C: TasksCollection<'c> + 'static,
{
self.collections
.get_mut(&TypeId::of::<C>())
.unwrap_or_else(move || {
panic!(
"You must add `{}` collection to the `TaskManager` by calling `add_collection`",
type_name::<C>()
)
})
}
pub fn add_collection<'c, C>(&mut self, context: C::Context) -> &mut Self
where
C: TasksCollection<'c> + 'static,
C::Executor: TaskExecutor + 'static,
{
self.push_collection::<C>().handle_collection::<C>(context)
}
fn push_collection<'c, C>(&mut self) -> &mut Self
where
C: TasksCollection<'c> + 'static,
C::Executor: TaskExecutor + 'static,
{
let id = TypeId::of::<C>();
if self.collections.contains_key(&id) {
return self;
}
self.collections
.insert(id, CollectionData::from_collection::<C>());
self
}
fn handle_collection<'c, C>(&mut self, context: C::Context) -> &mut Self
where
C: TasksCollection<'c> + 'static,
{
let handle = C::handle(context).into_any();
self.get_collection_mut::<C>().handle_all(handle);
self
}
pub fn push_task<'c, C>(&mut self, task: Task<C::Target>)
where
C: TasksCollection<'c> + 'static,
C::Target: Send + 'static,
{
self.get_collection_mut::<C>().push_task(task.into_any());
}
}