use fmi_schema::{
MajorVersion,
traits::{DefaultExperiment, FmiModelDescription},
};
use crate::{Error, EventFlags, InterfaceType};
pub trait FmiImport: Sized {
const MAJOR_VERSION: MajorVersion;
type ModelDescription: FmiModelDescription + DefaultExperiment;
type Binding;
type ValueRef;
fn new(dir: tempfile::TempDir, schema_xml: &str) -> Result<Self, Error>;
fn archive_path(&self) -> &std::path::Path;
fn shared_lib_path(&self, model_identifier: &str) -> Result<std::path::PathBuf, Error>;
fn resource_path(&self) -> std::path::PathBuf {
self.archive_path().join("resources")
}
fn canonical_resource_path_string(&self) -> String;
fn model_description(&self) -> &Self::ModelDescription;
fn binding(&self, model_identifier: &str) -> Result<Self::Binding, Error>;
}
pub trait FmiStatus {
type Res;
type Err: Into<Error> + std::fmt::Debug;
fn ok(self) -> Result<Self::Res, Self::Err>;
fn is_error(&self) -> bool;
}
pub trait InstanceTag {
const TYPE: InterfaceType;
}
pub type InstanceResult<S, R = <<S as FmiInstance>::Status as FmiStatus>::Res> =
Result<R, <<S as FmiInstance>::Status as FmiStatus>::Err>;
pub trait FmiInstance {
type ModelDescription: FmiModelDescription + DefaultExperiment;
type ValueRef: Copy + From<u32> + Into<u32>;
type Status: FmiStatus;
fn name(&self) -> &str;
fn get_version(&self) -> &str;
fn interface_type(&self) -> InterfaceType;
fn set_debug_logging(&mut self, logging_on: bool, categories: &[&str]) -> InstanceResult<Self>;
fn enter_initialization_mode(
&mut self,
tolerance: Option<f64>,
start_time: f64,
stop_time: Option<f64>,
) -> InstanceResult<Self>;
fn exit_initialization_mode(&mut self) -> InstanceResult<Self>;
fn terminate(&mut self) -> InstanceResult<Self>;
fn reset(&mut self) -> InstanceResult<Self>;
}
pub trait FmiModelExchange: FmiInstance {
fn enter_continuous_time_mode(&mut self) -> InstanceResult<Self>;
fn enter_event_mode(&mut self) -> InstanceResult<Self>;
fn update_discrete_states(&mut self, event_flags: &mut EventFlags) -> InstanceResult<Self>;
fn completed_integrator_step(
&mut self,
no_set_fmu_state_prior: bool,
enter_event_mode: &mut bool,
terminate_simulation: &mut bool,
) -> InstanceResult<Self>;
fn set_time(&mut self, time: f64) -> InstanceResult<Self>;
fn get_continuous_states(&mut self, continuous_states: &mut [f64]) -> InstanceResult<Self>;
fn set_continuous_states(&mut self, states: &[f64]) -> InstanceResult<Self>;
fn get_continuous_state_derivatives(&mut self, derivatives: &mut [f64])
-> InstanceResult<Self>;
fn get_nominals_of_continuous_states(&mut self, nominals: &mut [f64]) -> InstanceResult<Self>;
fn get_event_indicators(&mut self, event_indicators: &mut [f64]) -> InstanceResult<Self, bool>;
}
pub trait FmiEventHandler: FmiInstance {
fn enter_event_mode(&mut self) -> InstanceResult<Self>;
fn update_discrete_states(&mut self, event_flags: &mut EventFlags) -> InstanceResult<Self>;
}