use std::{collections::BTreeMap, path::PathBuf};
use fmi::fmi3::Fmi3Status;
use crate::fmi3::{
UserModel,
instance::{IntermediateUpdateClosure, LogMessageClosure},
traits::{Context, ModelLoggingCategory},
};
pub struct BasicContext<M: UserModel> {
logging_on: BTreeMap<M::LoggingCategory, bool>,
log_message: LogMessageClosure,
resource_path: PathBuf,
stop_time: Option<f64>,
time: f64,
early_return_allowed: bool,
intermediate_update: Option<IntermediateUpdateClosure>,
}
impl<M: UserModel> BasicContext<M> {
pub fn new(
logging_on: bool,
log_message: LogMessageClosure,
resource_path: PathBuf,
early_return_allowed: bool,
intermediate_update: Option<IntermediateUpdateClosure>,
) -> Self {
let logging_on = <M as UserModel>::LoggingCategory::all_categories()
.map(|category| (category, logging_on))
.collect();
Self {
logging_on,
log_message,
resource_path,
stop_time: None,
time: 0.0,
early_return_allowed,
intermediate_update,
}
}
pub fn intermediate_update(&self) -> Option<&IntermediateUpdateClosure> {
self.intermediate_update.as_ref()
}
}
impl<M> Context<M> for BasicContext<M>
where
M: UserModel + 'static,
{
fn logging_on(&self, category: <M as UserModel>::LoggingCategory) -> bool {
matches!(self.logging_on.get(&category), Some(true))
}
fn set_logging(&mut self, category: <M as UserModel>::LoggingCategory, enabled: bool) {
self.logging_on.insert(category, enabled);
}
fn log(&self, status: Fmi3Status, category: M::LoggingCategory, args: std::fmt::Arguments<'_>) {
if self.logging_on(category) {
(self.log_message)(status, &category.to_string(), args);
}
}
fn resource_path(&self) -> &PathBuf {
&self.resource_path
}
fn initialize(&mut self, start_time: f64, stop_time: Option<f64>) {
self.time = start_time;
self.stop_time = stop_time;
}
fn time(&self) -> f64 {
self.time
}
fn set_time(&mut self, time: f64) {
self.time = time;
}
fn stop_time(&self) -> Option<f64> {
self.stop_time
}
fn early_return_allowed(&self) -> bool {
self.early_return_allowed
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
}