fmi_export/fmi3/instance/
mod.rs1use fmi::fmi3::{Fmi3Error, Fmi3Status, binding};
2
3use crate::fmi3::{
4 ModelState, UserModel,
5 traits::{Context, Model},
6};
7
8mod common;
9pub mod context;
10mod get_set;
11mod impl_cs;
12mod impl_me;
13mod impl_se;
14
15pub type LogMessageClosure = Box<dyn Fn(Fmi3Status, &str, std::fmt::Arguments<'_>) + Send + Sync>;
16pub type IntermediateUpdateClosure =
17 Box<dyn Fn(f64, bool, bool, bool, bool) -> Option<f64> + Send + Sync>;
18
19#[repr(C)]
21pub struct ModelInstance<M, C>
22where
23 M: UserModel,
24 C: Context<M>,
25{
26 pub(crate) instance_type: fmi::InterfaceType,
28 instance_name: String,
30 context: C,
32 state: ModelState,
34 is_dirty_values: bool,
36 model: M,
38}
39
40impl<M, C> ModelInstance<M, C>
41where
42 M: Model + UserModel,
43 C: Context<M>,
44{
45 pub fn new(
46 name: String,
47 instantiation_token: &str,
48 context: C,
49 instance_type: fmi::InterfaceType,
50 ) -> Result<Self, Fmi3Error> {
51 if instantiation_token != M::INSTANTIATION_TOKEN {
53 eprintln!(
54 "Instantiation token mismatch. Expected: '{}', got: '{}'",
55 M::INSTANTIATION_TOKEN,
56 instantiation_token
57 );
58 return Err(Fmi3Error::Error);
59 }
60
61 let mut instance = Self {
62 instance_name: name,
63 context,
64 state: ModelState::Instantiated,
65 instance_type,
66 is_dirty_values: true,
67 model: M::default(),
68 };
69
70 instance.model.set_start_values();
72
73 Ok(instance)
74 }
75
76 pub fn instance_name(&self) -> &str {
77 &self.instance_name
78 }
79
80 pub fn instance_type(&self) -> fmi::InterfaceType {
81 self.instance_type
82 }
83
84 pub fn context(&self) -> &C {
85 &self.context
86 }
87
88 #[inline]
89 pub fn assert_instance_type(&self, expected: fmi::InterfaceType) -> Result<(), Fmi3Error> {
90 if self.instance_type != expected {
91 self.context.log(
92 Fmi3Error::Error.into(),
93 M::LoggingCategory::default(),
94 format_args!(
95 "Instance type mismatch. Expected: {:?}, got: {:?}",
96 expected, self.instance_type
97 ),
98 );
99 return Err(Fmi3Error::Error);
100 }
101 Ok(())
102 }
103
104 fn validate_variable_setting(&self, vr: binding::fmi3ValueReference) -> Result<(), Fmi3Error> {
106 match M::validate_variable_setting(vr, &self.state) {
107 Ok(()) => Ok(()),
108 Err(message) => {
109 self.context.log(
110 Fmi3Error::Error.into(),
111 M::LoggingCategory::default(),
112 format_args!("Variable setting error for VR {vr}: {message}"),
113 );
114 Err(Fmi3Error::Error)
115 }
116 }
117 }
118}