fmi_export/fmi3/instance/
get_set.rs1use fmi::fmi3::{Fmi3Error, Fmi3Res, GetSet, binding};
2
3use crate::fmi3::{
4 Model, UserModel,
5 traits::{Context, ModelGetSet},
6};
7
8macro_rules! instance_getter {
10 ($name:ident, $ty:ty) => {
11 paste::paste! {
12 fn [<get_ $name>](
13 &mut self,
14 vrs: &[binding::fmi3ValueReference],
15 values: &mut [$ty],
16 ) -> Result<Fmi3Res, Fmi3Error> {
17 if self.is_dirty_values {
18 self.model.calculate_values(&self.context)?;
19 self.is_dirty_values = false;
20 }
21 let mut value_index = 0;
22 for vr in vrs.iter() {
23 if *vr == 0 {
24 return Err(Fmi3Error::Error);
26 }
27 let elements_read = self.model.[<get_ $name>](*vr-1, &mut values[value_index..], &self.context)?;
28 value_index += elements_read;
29 }
30 Ok(Fmi3Res::OK)
31 }
32 }
33 };
34}
35
36macro_rules! instance_setter {
38 ($name:ident, $ty:ty) => {
39 paste::paste! {
40 fn [<set_ $name>](
41 &mut self,
42 vrs: &[binding::fmi3ValueReference],
43 values: &[$ty],
44 ) -> Result<Fmi3Res, Fmi3Error> {
45 let mut value_index = 0;
47 for vr in vrs.iter() {
48 if *vr == 0 {
49 return Err(Fmi3Error::Error);
51 }
52 self.validate_variable_setting(*vr - 1)?;
53 let elements_written = self.model.[<set_ $name>](*vr-1, &values[value_index..], &self.context)?;
54 value_index += elements_written;
55 }
56
57 self.is_dirty_values = true;
58 Ok(Fmi3Res::OK)
59 }
60 }
61 };
62}
63
64macro_rules! instance_getter_setter {
66 ($name:ident, $ty:ty) => {
67 instance_getter!($name, $ty);
68 instance_setter!($name, $ty);
69 };
70}
71
72impl<M, C> GetSet for super::ModelInstance<M, C>
82where
83 M: Model + UserModel + ModelGetSet<M>,
84 C: Context<M>,
85{
86 instance_getter_setter!(boolean, bool);
88 instance_getter_setter!(float32, f32);
89 instance_getter_setter!(int8, i8);
90 instance_getter_setter!(int16, i16);
91 instance_getter_setter!(int32, i32);
92 instance_getter_setter!(int64, i64);
93 instance_getter_setter!(uint8, u8);
94 instance_getter_setter!(uint16, u16);
95 instance_getter_setter!(uint32, u32);
96 instance_getter_setter!(uint64, u64);
97
98 fn get_float64(
99 &mut self,
100 vrs: &[binding::fmi3ValueReference],
101 values: &mut [f64],
102 ) -> Result<Fmi3Res, Fmi3Error> {
103 if self.is_dirty_values {
104 self.model.calculate_values(&self.context)?;
105 self.is_dirty_values = false;
106 }
107 let mut value_index = 0;
108 for vr in vrs.iter() {
109 if *vr == 0 && value_index < values.len() {
111 values[value_index] = self.context.time();
112 value_index += 1;
113 } else {
114 let elements_read =
115 self.model
116 .get_float64(*vr - 1, &mut values[value_index..], &self.context)?;
117 value_index += elements_read;
118 }
119 }
120 Ok(Fmi3Res::OK)
121 }
122 instance_setter!(float64, f64);
123
124 fn get_string(
125 &mut self,
126 vrs: &[binding::fmi3ValueReference],
127 values: &mut [std::ffi::CString],
128 ) -> Result<(), Fmi3Error> {
129 let mut value_index = 0;
130 for vr in vrs.iter() {
131 if *vr == 0 {
132 return Err(Fmi3Error::Error);
134 }
135 let elements_read =
136 self.model
137 .get_string(*vr - 1, &mut values[value_index..], &self.context)?;
138 value_index += elements_read;
139 }
140 Ok(())
141 }
142
143 fn set_string(
144 &mut self,
145 vrs: &[binding::fmi3ValueReference],
146 values: &[std::ffi::CString],
147 ) -> Result<(), Fmi3Error> {
148 let mut value_index = 0;
149 for vr in vrs.iter() {
150 if *vr == 0 {
151 return Err(Fmi3Error::Error);
153 }
154 self.validate_variable_setting(*vr)?;
155 let elements_written =
156 self.model
157 .set_string(*vr - 1, &values[value_index..], &self.context)?;
158 value_index += elements_written;
159 }
160 self.is_dirty_values = true;
161 Ok(())
162 }
163
164 fn get_binary(
165 &mut self,
166 vrs: &[binding::fmi3ValueReference],
167 values: &mut [&mut [u8]],
168 ) -> Result<Vec<usize>, Fmi3Error> {
169 let mut result_sizes = Vec::new();
170 let mut value_index = 0;
171 for vr in vrs.iter() {
172 if *vr == 0 {
173 return Err(Fmi3Error::Error);
175 }
176 let binary_sizes =
177 self.model
178 .get_binary(*vr - 1, &mut values[value_index..], &self.context)?;
179 result_sizes.extend(binary_sizes.iter());
180 value_index += binary_sizes.len();
181 }
182 Ok(result_sizes)
183 }
184
185 fn set_binary(
186 &mut self,
187 vrs: &[binding::fmi3ValueReference],
188 values: &[&[u8]],
189 ) -> Result<(), Fmi3Error> {
190 let mut value_index = 0;
191 for vr in vrs.iter() {
192 if *vr == 0 {
193 return Err(Fmi3Error::Error);
195 }
196 self.validate_variable_setting(*vr - 1)?;
197 let elements_written =
198 self.model
199 .set_binary(*vr - 1, &values[value_index..], &self.context)?;
200 value_index += elements_written;
201 }
202 self.is_dirty_values = true;
203 Ok(())
204 }
205
206 fn get_clock(
207 &mut self,
208 vrs: &[binding::fmi3ValueReference],
209 values: &mut [binding::fmi3Clock],
210 ) -> Result<Fmi3Res, Fmi3Error> {
211 for (vr, value) in vrs.iter().zip(values.iter_mut()) {
212 if *vr == 0 {
213 return Err(Fmi3Error::Error);
215 }
216 self.model.get_clock(*vr - 1, value, &self.context)?;
217 }
218 Ok(Fmi3Res::OK)
219 }
220
221 fn set_clock(
222 &mut self,
223 _vrs: &[binding::fmi3ValueReference],
224 _values: &[binding::fmi3Clock],
225 ) -> Result<Fmi3Res, Fmi3Error> {
226 for (vr, value) in _vrs.iter().zip(_values.iter()) {
227 if *vr == 0 {
228 return Err(Fmi3Error::Error);
230 }
231 self.validate_variable_setting(*vr - 1)?;
232 self.model.set_clock(*vr - 1, value, &self.context)?;
233 }
234 Ok(Fmi3Res::OK)
235 }
236}