use service::ServiceBase;
use store::StoreBase;
use id_manager::PrimaryIdManager;
use buffer::BufferBase;
use process::ProcessBase;
use ioc::{Ioc, IocBuilder};
use std::fmt::Debug;
use std::sync::RwLock;
pub struct Simulation<IdMgr, Key, StoBase: ?Sized, BufBase: ?Sized, SerBase: ?Sized, ProcBase: ?Sized> {
ids: RwLock<IdMgr>,
stores: Ioc<Key, StoBase>,
buffers: Ioc<Key, BufBase>,
services: Ioc<Key, SerBase>,
pipeline: Vec<Ioc<Key, ProcBase>>,
}
impl<IdMgr, Key, StoBase: ?Sized, BufBase: ?Sized, SerBase: ?Sized, ProcBase: ?Sized> Simulation<IdMgr, Key, StoBase, BufBase, SerBase, ProcBase>
where
IdMgr: PrimaryIdManager,
Key: Debug + Ord,
StoBase: StoreBase<Id = IdMgr::Id>,
BufBase: BufferBase,
SerBase: ServiceBase,
ProcBase: ProcessBase<IdMgr, Key, StoBase, BufBase, SerBase>,
{
pub fn ids(&self) -> &RwLock<IdMgr> { &self.ids }
pub fn stores(&self) -> &Ioc<Key, StoBase> { &self.stores }
pub fn buffers(&self) -> &Ioc<Key, BufBase> { &self.buffers }
pub fn services(&self) -> &Ioc<Key, SerBase> { &self.services }
pub fn update(&mut self){
for (_, mut store) in self.stores.write_all().unwrap() {
store.on_before_frame();
}
for (_, mut buffer) in self.buffers.write_all().unwrap() {
buffer.on_before_frame();
}
for (_, mut service) in self.services.write_all().unwrap() {
service.on_before_frame();
}
for (_, mut prok) in self.pipeline.iter().flat_map(|p| p.write_all().unwrap()) {
prok.on_before_frame();
}
for stage in &self.pipeline {
for (_, mut process) in stage.write_all().unwrap() {
process._update(&self.ids, &self.stores, &self.buffers, &self.services);
}
}
for (_, mut store) in self.stores.write_all().unwrap() {
store.on_after_frame();
}
for (_, mut buffer) in self.buffers.write_all().unwrap() {
buffer.on_after_frame();
}
for (_, mut service) in self.services.write_all().unwrap() {
service.on_after_frame();
}
for (_, mut prok) in self.pipeline.iter().flat_map(|p| p.write_all().unwrap()) {
prok.on_after_frame();
}
}
}
pub struct SimulationBuilder<IdMgr, Key, StoBase: ?Sized, BufBase: ?Sized, SerBase: ?Sized, ProcBase: ?Sized> {
ids: IdMgr,
stores: IocBuilder<Key, StoBase>,
buffers: IocBuilder<Key, BufBase>,
services: IocBuilder<Key, SerBase>,
pipeline: Vec<IocBuilder<Key, ProcBase>>,
}
impl<IdMgr, Key, StoBase: ?Sized, BufBase: ?Sized, SerBase: ?Sized, ProcBase: ?Sized> SimulationBuilder<IdMgr, Key, StoBase, BufBase, SerBase, ProcBase>
where
IdMgr: PrimaryIdManager,
Key: Debug + Ord,
StoBase: StoreBase<Id = IdMgr::Id>,
BufBase: BufferBase,
SerBase: ServiceBase,
ProcBase: ProcessBase<IdMgr, Key, StoBase, BufBase, SerBase>,
{
pub fn new(ids: IdMgr) -> Self {
SimulationBuilder{
ids: ids,
stores: IocBuilder::new(),
buffers: IocBuilder::new(),
services: 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 services(&mut self) -> &mut IocBuilder<Key, SerBase> { &mut self.services }
pub fn pipeline(&mut self) -> &mut Vec<IocBuilder<Key, ProcBase>> { &mut self.pipeline }
pub fn build(self) -> Simulation<IdMgr, Key, StoBase, BufBase, SerBase, ProcBase> {
Simulation{
ids: RwLock::new(self.ids),
stores: self.stores.build(),
buffers: self.buffers.build(),
services: self.services.build(),
pipeline: self.pipeline.into_iter().map(|stage| stage.build()).collect(),
}
}
}
impl<IdMgr, Key, StoBase: ?Sized, BufBase: ?Sized, SerBase: ?Sized, ProcBase: ?Sized> Default for SimulationBuilder<IdMgr, Key, StoBase, BufBase, SerBase, ProcBase>
where
IdMgr: Default + PrimaryIdManager,
Key: Debug + Ord,
StoBase: StoreBase<Id = IdMgr::Id>,
BufBase: BufferBase,
SerBase: ServiceBase,
ProcBase: ProcessBase<IdMgr, Key, StoBase, BufBase, SerBase>,
{
fn default() -> Self { Self::new(IdMgr::default()) }
}