use std::fmt;
use std::marker::PhantomData;
use std::sync::{Arc, Mutex};
use crate::model::{Model, ModelRegistry, SchedulableId};
use crate::simulation::EventId;
use crate::simulation::queue_items::Event;
use crate::util::priority_queue::PriorityQueue;
use super::GLOBAL_ORIGIN_ID;
pub(crate) type InjectorQueue = PriorityQueue<usize, Event>;
#[derive(Clone)]
pub struct ModelInjector<M: Model> {
queue: Arc<Mutex<InjectorQueue>>,
origin_id: usize,
model_registry: Arc<ModelRegistry>,
_model: PhantomData<M>,
}
impl<M: Model> ModelInjector<M> {
pub(crate) fn new(
queue: Arc<Mutex<InjectorQueue>>,
origin_id: usize,
model_registry: Arc<ModelRegistry>,
) -> Self {
Self {
queue,
origin_id,
model_registry,
_model: PhantomData,
}
}
pub fn inject_event<T>(&self, schedulable_id: &SchedulableId<M, T>, arg: T)
where
T: Send + Clone + 'static,
{
let mut queue = self.queue.lock().unwrap();
let event = Event::new(&schedulable_id.source_id(&self.model_registry), arg);
queue.insert(self.origin_id, event);
}
}
impl<M: Model> fmt::Debug for ModelInjector<M> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ModelInjector")
.field("origin_id", &self.origin_id)
.finish_non_exhaustive()
}
}
#[derive(Clone)]
pub struct Injector {
queue: Arc<Mutex<InjectorQueue>>,
}
impl Injector {
pub(crate) fn new(queue: Arc<Mutex<InjectorQueue>>) -> Self {
Self { queue }
}
pub fn inject_event<T>(&self, event_id: &EventId<T>, arg: T)
where
T: Send + Clone + 'static,
{
let event = Event::new(event_id, arg);
self.inject_built_event(event);
}
pub(crate) fn inject_built_event(&self, event: Event) {
let mut queue = self.queue.lock().unwrap();
queue.insert(GLOBAL_ORIGIN_ID, event);
}
}
impl fmt::Debug for Injector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Injector").finish_non_exhaustive()
}
}