use store::StoreBase;
use buffer::BufferBase;
use id_manager::PrimaryIdManager;
use subsystem::SubsystemBase;
use process::ProcessBase;
use ioc::{Ioc, IocBuilder};
use std::fmt::Debug;
use std::sync::RwLock;
pub struct Simulation<IdMgr, Key, SsysBase: ?Sized, StoBase: ?Sized, BufBase: ?Sized, ProcBase: ?Sized> {
ids: RwLock<IdMgr>,
subsystems: Ioc<Key, SsysBase>,
stores: Ioc<Key, StoBase>,
buffers: Ioc<Key, BufBase>,
pipeline: Vec<Ioc<Key, ProcBase>>,
paused: bool,
}
impl<IdMgr, Key, SsysBase: ?Sized, StoBase: ?Sized, BufBase: ?Sized, ProcBase: ?Sized> Simulation<IdMgr, Key, SsysBase, StoBase, BufBase, ProcBase>
where
IdMgr: PrimaryIdManager,
Key: Debug + Ord,
SsysBase: SubsystemBase,
StoBase: StoreBase<Id = IdMgr::Id>,
BufBase: BufferBase,
ProcBase: ProcessBase<IdMgr, Key, SsysBase, StoBase, BufBase>,
{
pub fn ids(&self) -> &RwLock<IdMgr> { &self.ids }
pub fn subsystems(&self) -> &Ioc<Key, SsysBase> { &self.subsystems }
pub fn stores(&self) -> &Ioc<Key, StoBase> { &self.stores }
pub fn buffers(&self) -> &Ioc<Key, BufBase> { &self.buffers }
pub fn update(&mut self){
if self.is_paused(){ self.unpause(); }
for (_, mut subsystem) in self.subsystems.write_all().unwrap() {
subsystem.on_before_frame();
}
for (_, mut buffer) in self.buffers.write_all().unwrap() {
buffer.clear();
}
for stage in &self.pipeline {
for (_, mut process) in stage.write_all().unwrap() {
process._update(&self.ids, &self.subsystems, &self.stores, &self.buffers);
}
}
for (_, mut subsystem) in self.subsystems.write_all().unwrap() {
subsystem.on_after_frame();
}
}
pub fn is_paused(&self) -> bool { self.paused }
pub fn pause(&mut self){
if self.is_paused() { return; }
self.paused = true;
for (_, mut subsystem) in self.subsystems.write_all().unwrap() {
subsystem.on_before_pause();
}
}
pub fn unpause(&mut self){
if !self.is_paused() { return; }
self.paused = false;
for (_, mut subsystem) in self.subsystems.write_all().unwrap() {
subsystem.on_after_pause();
}
}
}
pub struct SimulationBuilder<IdMgr, Key, SsysBase: ?Sized, StoBase: ?Sized, BufBase: ?Sized, ProcBase: ?Sized> {
ids: IdMgr,
subsystems: IocBuilder<Key, SsysBase>,
stores: IocBuilder<Key, StoBase>,
buffers: IocBuilder<Key, BufBase>,
pipeline: Vec<IocBuilder<Key, ProcBase>>,
}
impl<IdMgr, Key, SsysBase: ?Sized, StoBase: ?Sized, BufBase: ?Sized, ProcBase: ?Sized> SimulationBuilder<IdMgr, Key, SsysBase, StoBase, BufBase, ProcBase>
where
IdMgr: PrimaryIdManager,
Key: Debug + Ord,
SsysBase: SubsystemBase,
StoBase: StoreBase<Id = IdMgr::Id>,
BufBase: BufferBase,
ProcBase: ProcessBase<IdMgr, Key, SsysBase, StoBase, BufBase>,
{
pub fn new(ids: IdMgr) -> Self {
SimulationBuilder{
ids: ids,
subsystems: IocBuilder::new(),
stores: IocBuilder::new(),
buffers: IocBuilder::new(),
pipeline: Vec::new(),
}
}
pub fn stores(&mut self) -> &mut IocBuilder<Key, StoBase> { &mut self.stores }
pub fn buffers(&mut self) -> &mut IocBuilder<Key, BufBase> { &mut self.buffers }
pub fn subsystems(&mut self) -> &mut IocBuilder<Key, SsysBase> { &mut self.subsystems }
pub fn pipeline(&mut self) -> &mut Vec<IocBuilder<Key, ProcBase>> { &mut self.pipeline }
pub fn build(self) -> Simulation<IdMgr, Key, SsysBase, StoBase, BufBase, ProcBase> {
Simulation{
ids: RwLock::new(self.ids),
subsystems: self.subsystems.build(),
stores: self.stores.build(),
buffers: self.buffers.build(),
pipeline: self.pipeline.into_iter().map(|stage| stage.build()).collect(),
paused: false,
}
}
}
impl<IdMgr, Key, SsysBase: ?Sized, StoBase: ?Sized, BufBase: ?Sized, ProcBase: ?Sized> Default for SimulationBuilder<IdMgr, Key, SsysBase, StoBase, BufBase, ProcBase>
where
IdMgr: Default + PrimaryIdManager,
Key: Debug + Ord,
SsysBase: SubsystemBase,
StoBase: StoreBase<Id = IdMgr::Id>,
BufBase: BufferBase,
ProcBase: ProcessBase<IdMgr, Key, SsysBase, StoBase, BufBase>,
{
fn default() -> Self { Self::new(IdMgr::default()) }
}