use crate::{
common::{error::Result, log::thread::LogThread},
host::{
configuration::{PluginConfiguration, SimulatorConfiguration},
plugin::Plugin,
reproduction::Reproduction,
simulation::Simulation,
},
trace, warn,
};
#[derive(Debug)]
pub struct Simulator {
log_thread: LogThread,
pub simulation: Simulation,
}
impl Simulator {
pub fn new(mut configuration: SimulatorConfiguration) -> Result<Simulator> {
configuration.check_plugin_list()?;
configuration.optimize_loglevels();
let reproduction = configuration
.reproduction_path_style
.map(|_| Reproduction::new_logger(&configuration));
let log_thread = LogThread::spawn(
"dqcsim",
configuration.dqcsim_level,
configuration.stderr_level,
configuration.log_callback,
configuration.tee_files,
)?;
let reproduction = match reproduction {
Some(Ok(r)) => Some(r),
Some(Err(e)) => {
warn!("Failed to construct reproduction logger: {}", e.to_string());
warn!("Therefore, you will not be able to reproduce this run on the command line later.");
None
}
None => None,
};
let pipeline: Vec<Box<dyn Plugin>> = configuration
.plugins
.into_iter()
.map(PluginConfiguration::instantiate)
.collect();
let simulation = Simulation::new(pipeline, configuration.seed, reproduction, &log_thread)?;
Ok(Simulator {
log_thread,
simulation,
})
}
}
impl Drop for Simulator {
fn drop(&mut self) {
trace!("Dropping Simulator");
self.simulation.drop_plugins();
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
common::{
log::LoglevelFilter,
types::{PluginMetadata, PluginType},
},
host::configuration::{
PluginLogConfiguration, PluginThreadConfiguration, SimulatorConfiguration,
},
plugin::definition::PluginDefinition,
};
#[test]
fn debug() {
let configuration = SimulatorConfiguration::default()
.without_reproduction()
.without_logging()
.with_plugin(PluginThreadConfiguration::new(
PluginDefinition::new(PluginType::Frontend, PluginMetadata::new("", "", "")),
PluginLogConfiguration::new("", LoglevelFilter::Off),
))
.with_plugin(PluginThreadConfiguration::new(
PluginDefinition::new(PluginType::Backend, PluginMetadata::new("", "", "")),
PluginLogConfiguration::new("", LoglevelFilter::Off),
));
let simulator = Simulator::new(configuration);
assert!(simulator.is_ok());
let simulator = simulator.unwrap();
assert_eq!(
format!("{:?}", simulator).find("imulator { log_thread"),
Some(1)
);
assert_eq!(
format!("{:?}", simulator.simulation).find("imulation { pipeline"),
Some(1)
);
}
}