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>
83where
84 M: Model + UserModel + ModelGetSet<M>,
85 C: Context<M>,
86{
87 instance_getter_setter!(boolean, bool);
89 instance_getter_setter!(float32, f32);
90 instance_getter_setter!(int8, i8);
91 instance_getter_setter!(int16, i16);
92 instance_getter_setter!(int32, i32);
93 instance_getter_setter!(int64, i64);
94 instance_getter_setter!(uint8, u8);
95 instance_getter_setter!(uint16, u16);
96 instance_getter_setter!(uint32, u32);
97 instance_getter_setter!(uint64, u64);
98
99 fn get_float64(
100 &mut self,
101 vrs: &[binding::fmi3ValueReference],
102 values: &mut [f64],
103 ) -> Result<Fmi3Res, Fmi3Error> {
104 if self.is_dirty_values {
105 self.model.calculate_values(&self.context)?;
106 self.is_dirty_values = false;
107 }
108 let mut value_index = 0;
109 for vr in vrs.iter() {
110 if *vr == 0 && value_index < values.len() {
112 values[value_index] = self.context.time();
113 value_index += 1;
114 } else {
115 let elements_read =
116 self.model
117 .get_float64(*vr - 1, &mut values[value_index..], &self.context)?;
118 value_index += elements_read;
119 }
120 }
121 Ok(Fmi3Res::OK)
122 }
123 instance_setter!(float64, f64);
124
125 fn get_string(
126 &mut self,
127 vrs: &[binding::fmi3ValueReference],
128 values: &mut [std::ffi::CString],
129 ) -> Result<(), Fmi3Error> {
130 let mut value_index = 0;
131 for vr in vrs.iter() {
132 if *vr == 0 {
133 return Err(Fmi3Error::Error);
135 }
136 let elements_read =
137 self.model
138 .get_string(*vr - 1, &mut values[value_index..], &self.context)?;
139 value_index += elements_read;
140 }
141 Ok(())
142 }
143
144 fn set_string(
145 &mut self,
146 vrs: &[binding::fmi3ValueReference],
147 values: &[std::ffi::CString],
148 ) -> Result<(), Fmi3Error> {
149 let mut value_index = 0;
150 for vr in vrs.iter() {
151 if *vr == 0 {
152 return Err(Fmi3Error::Error);
154 }
155 self.validate_variable_setting(*vr)?;
156 let elements_written =
157 self.model
158 .set_string(*vr - 1, &values[value_index..], &self.context)?;
159 value_index += elements_written;
160 }
161 self.is_dirty_values = true;
162 Ok(())
163 }
164
165 fn get_binary(
166 &mut self,
167 vrs: &[binding::fmi3ValueReference],
168 values: &mut [&mut [u8]],
169 ) -> Result<Vec<usize>, Fmi3Error> {
170 let mut result_sizes = Vec::new();
171 let mut value_index = 0;
172 for vr in vrs.iter() {
173 if *vr == 0 {
174 return Err(Fmi3Error::Error);
176 }
177 let binary_sizes =
178 self.model
179 .get_binary(*vr - 1, &mut values[value_index..], &self.context)?;
180 result_sizes.extend(binary_sizes.iter());
181 value_index += binary_sizes.len();
182 }
183 Ok(result_sizes)
184 }
185
186 fn set_binary(
187 &mut self,
188 vrs: &[binding::fmi3ValueReference],
189 values: &[&[u8]],
190 ) -> Result<(), Fmi3Error> {
191 let mut value_index = 0;
192 for vr in vrs.iter() {
193 if *vr == 0 {
194 return Err(Fmi3Error::Error);
196 }
197 self.validate_variable_setting(*vr - 1)?;
198 let elements_written =
199 self.model
200 .set_binary(*vr - 1, &values[value_index..], &self.context)?;
201 value_index += elements_written;
202 }
203 self.is_dirty_values = true;
204 Ok(())
205 }
206
207 fn get_clock(
208 &mut self,
209 vrs: &[binding::fmi3ValueReference],
210 values: &mut [binding::fmi3Clock],
211 ) -> Result<Fmi3Res, Fmi3Error> {
212 for (vr, value) in vrs.iter().zip(values.iter_mut()) {
213 if *vr == 0 {
214 return Err(Fmi3Error::Error);
216 }
217 self.model.get_clock(*vr - 1, value, &self.context)?;
218 }
219 Ok(Fmi3Res::OK)
220 }
221
222 fn set_clock(
223 &mut self,
224 _vrs: &[binding::fmi3ValueReference],
225 _values: &[binding::fmi3Clock],
226 ) -> Result<Fmi3Res, Fmi3Error> {
227 for (vr, value) in _vrs.iter().zip(_values.iter()) {
228 if *vr == 0 {
229 return Err(Fmi3Error::Error);
231 }
232 self.validate_variable_setting(*vr - 1)?;
233 self.model.set_clock(*vr - 1, value, &self.context)?;
234 }
235 Ok(Fmi3Res::OK)
236 }
237}