use crate::MaskType;
use super::{
System, SystemOnce, SystemOnceRunner, SystemOnceThreadLocal, SystemOnceThreadLocalRunner,
SyncSystem, SystemThreadLocal, CreationSystem, Systems, CreationSystemOnce, CreationSystemOnceRunner,
SystemConditionElse,
container::{ Priority, SystemInfo },
};
#[cfg(feature="debug_parameters")]
use super::SystemDebug;
use std::slice;
use std::any::TypeId;
#[cfg(not(components_bigint))]
use num_traits::Zero;
pub trait AnySystem<TraitObject>{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<TraitObject>>;
fn into_trait_object(self) -> TraitObject
where Self: Sized;
fn insert_trait_object(self,
checks: Option<SystemConditionElse<TraitObject>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
where Self: Sized;
}
impl<S: System + 'static> AnySystem<SyncSystem> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<SyncSystem>>{
systems.systems.iter()
}
fn into_trait_object(self) -> SyncSystem
where Self: Sized,
{
SyncSystem::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<SyncSystem>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::Send(systems.systems.len());
let (checks, els) = checks
.map(|checks| checks.condition_else())
.unwrap_or((None, None));
systems.systems.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: self.into_trait_object(),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
needs: needs.unwrap_or_else(|| S::needs()),
updates: updates.unwrap_or_else(|| S::updates()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: vec![],
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}
impl<S: SystemOnce + 'static> AnySystem<SystemOnceRunner> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<SystemOnceRunner>>{
systems.systems_once.iter()
}
fn into_trait_object(self) -> SystemOnceRunner
where Self: Sized
{
SystemOnceRunner::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<SystemOnceRunner>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::SendOnce(systems.systems_once.len());
let (checks, els) = checks.map(|checks| checks.condition_else()).unwrap_or((None, None));
systems.systems_once.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: SystemOnceRunner::new(self),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
updates: updates.unwrap_or_else(|| S::updates()),
needs: needs.unwrap_or_else(|| S::needs()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: vec![],
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}
impl<S: SystemOnceThreadLocal + 'static> AnySystem<SystemOnceThreadLocalRunner> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<SystemOnceThreadLocalRunner>>{
systems.systems_once_thread_local.iter()
}
fn into_trait_object(self) -> SystemOnceThreadLocalRunner
where Self: Sized
{
SystemOnceThreadLocalRunner::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<SystemOnceThreadLocalRunner>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::ThreadLocalOnce(systems.systems_once_thread_local.len());
let (checks, els) = checks.map(|checks| checks.condition_else()).unwrap_or((None, None));
systems.systems_once_thread_local.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: SystemOnceThreadLocalRunner::new(self),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
updates: updates.unwrap_or_else(|| S::updates()),
needs: needs.unwrap_or_else(|| S::needs()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: vec![],
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}
impl<S: SystemThreadLocal + 'static> AnySystem<Box<dyn SystemThreadLocal>> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<Box<dyn SystemThreadLocal>>>{
systems.systems_thread_local.iter()
}
fn into_trait_object(self) -> Box<dyn SystemThreadLocal>
where Self: Sized
{
Box::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<Box<dyn SystemThreadLocal>>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::ThreadLocal(systems.systems_thread_local.len());
let (checks, els) = checks.map(|checks| checks.condition_else()).unwrap_or((None, None));
systems.systems_thread_local.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: Box::new(self),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
updates: updates.unwrap_or_else(|| S::updates()),
needs: needs.unwrap_or_else(|| S::needs()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: vec![],
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}
impl<S: CreationSystem + 'static> AnySystem<Box<dyn CreationSystem>> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<Box<dyn CreationSystem>>>{
systems.systems_creation.iter()
}
fn into_trait_object(self) -> Box<dyn CreationSystem>
where Self: Sized
{
Box::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<Box<dyn CreationSystem>>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::Creation(systems.systems_creation.len());
let (checks, els) = checks.map(|checks| checks.condition_else()).unwrap_or((None, None));
systems.systems_creation.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: Box::new(self),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
updates: updates.unwrap_or_else(|| S::updates()),
needs: needs.unwrap_or_else(|| S::needs()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: Self::creates(),
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}
impl<S: CreationSystemOnce + 'static> AnySystem<CreationSystemOnceRunner> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<CreationSystemOnceRunner>>{
systems.systems_creation_once.iter()
}
fn into_trait_object(self) -> CreationSystemOnceRunner
where Self: Sized
{
CreationSystemOnceRunner::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<CreationSystemOnceRunner>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::Creation(systems.systems_creation.len());
let (checks, els) = checks.map(|checks| checks.condition_else()).unwrap_or((None, None));
systems.systems_creation_once.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: CreationSystemOnceRunner::new(self),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
updates: updates.unwrap_or_else(|| S::updates()),
needs: needs.unwrap_or_else(|| S::needs()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: Self::creates(),
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}
#[cfg(feature = "debug_parameters")]
impl<S: SystemDebug + 'static> AnySystem<Box<dyn SystemDebug>> for S{
fn iter(systems: &mut Systems) -> slice::Iter<SystemInfo<Box<dyn SystemDebug>>>{
systems.systems_debug.iter()
}
fn into_trait_object(self) -> Box<dyn SystemDebug>
where Self: Sized
{
Box::new(self)
}
fn insert_trait_object(self,
checks: Option<SystemConditionElse<Box<dyn SystemDebug>>>,
needs: Option<Vec<TypeId>>,
updates: Option<Vec<TypeId>>,
reads: Option<Vec<TypeId>>,
writes: Option<Vec<TypeId>>,
systems: &mut Systems) -> Priority
{
let priority = Priority::Debug(systems.systems_debug.len());
let (checks, els) = checks.map(|checks| checks.condition_else()).unwrap_or((None, None));
systems.systems_debug.push(SystemInfo{
#[cfg(feature = "debug_systems_permissions")]
system_info: self.file_line_info(),
#[cfg(not(feature = "debug_systems_permissions"))]
system_info: Self::name().unwrap_or(""),
system: Box::new(self),
name: S::name(),
checks,
els,
before: S::before(),
after: S::after(),
updates: updates.unwrap_or_else(|| S::updates()),
needs: needs.unwrap_or_else(|| S::needs()),
reads: reads.unwrap_or_else(|| S::reads()),
writes: writes.unwrap_or_else(|| S::writes()),
creates: vec![],
successors: vec![],
predecessors: vec![],
resource_mask_r: MaskType::zero(),
resource_mask_w: MaskType::zero(),
});
priority
}
}