1use super::{
6 elem_type::{DisplayNotation, Endianness, FloatRepresentation},
7 interface::{IFloat, INode, IRegister, IncrementMode},
8 node_base::{NodeAttributeBase, NodeBase},
9 store::{CacheStore, NodeStore, ValueStore},
10 utils, Device, GenApiError, GenApiResult, RegisterBase, ValueCtxt,
11};
12
13#[derive(Debug, Clone)]
14pub struct FloatRegNode {
15 pub(crate) attr_base: NodeAttributeBase,
16 pub(crate) register_base: RegisterBase,
17
18 pub(crate) endianness: Endianness,
19 pub(crate) unit: Option<String>,
20 pub(crate) representation: FloatRepresentation,
21 pub(crate) display_notation: DisplayNotation,
22 pub(crate) display_precision: i64,
23}
24
25impl FloatRegNode {
26 #[must_use]
27 pub fn register_base(&self) -> &RegisterBase {
28 &self.register_base
29 }
30
31 #[must_use]
32 pub fn endianness(&self) -> Endianness {
33 self.endianness
34 }
35
36 #[must_use]
37 pub fn unit_elem(&self) -> Option<&str> {
38 self.unit.as_deref()
39 }
40
41 #[must_use]
42 pub fn representation_elem(&self) -> FloatRepresentation {
43 self.representation
44 }
45
46 #[must_use]
47 pub fn display_notation_elem(&self) -> DisplayNotation {
48 self.display_notation
49 }
50
51 #[must_use]
52 pub fn display_precision_elem(&self) -> i64 {
53 self.display_precision
54 }
55}
56
57impl INode for FloatRegNode {
58 fn node_base(&self) -> NodeBase {
59 let elem_base = &self.register_base.elem_base;
60 NodeBase::new(&self.attr_base, elem_base)
61 }
62
63 fn streamable(&self) -> bool {
64 self.register_base().streamable()
65 }
66}
67
68impl IFloat for FloatRegNode {
69 #[tracing::instrument(skip(self, device, store, cx),
70 level = "trace",
71 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
72 fn value<T: ValueStore, U: CacheStore>(
73 &self,
74 device: &mut impl Device,
75 store: &impl NodeStore,
76 cx: &mut ValueCtxt<T, U>,
77 ) -> GenApiResult<f64> {
78 let nid = self.node_base().id();
79 let reg = self.register_base();
80
81 reg.with_cache_or_read(nid, device, store, cx, |data| {
82 utils::float_from_slice(data, self.endianness)
83 })
84 }
85
86 #[tracing::instrument(skip(self, device, store, cx),
87 level = "trace",
88 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
89 fn set_value<T: ValueStore, U: CacheStore>(
90 &self,
91 value: f64,
92 device: &mut impl Device,
93 store: &impl NodeStore,
94 cx: &mut ValueCtxt<T, U>,
95 ) -> GenApiResult<()> {
96 let nid = self.node_base().id();
97 cx.invalidate_cache_by(nid);
98
99 let reg = self.register_base();
100 let len = reg.length(device, store, cx)?;
101 let mut buf = vec![0; len as usize];
102 utils::bytes_from_float(value, &mut buf, self.endianness)?;
103 reg.write_and_cache(nid, &buf, device, store, cx)?;
104 Ok(())
105 }
106
107 fn min<T: ValueStore, U: CacheStore>(
108 &self,
109 _: &mut impl Device,
110 _: &impl NodeStore,
111 _: &mut ValueCtxt<T, U>,
112 ) -> GenApiResult<f64> {
113 Ok(f64::MIN)
114 }
115
116 fn max<T: ValueStore, U: CacheStore>(
117 &self,
118 _: &mut impl Device,
119 _: &impl NodeStore,
120 _: &mut ValueCtxt<T, U>,
121 ) -> GenApiResult<f64> {
122 Ok(f64::MAX)
123 }
124
125 fn inc_mode(&self, _: &impl NodeStore) -> Option<IncrementMode> {
126 None
127 }
128
129 fn inc<T: ValueStore, U: CacheStore>(
130 &self,
131 _: &mut impl Device,
132 _: &impl NodeStore,
133 _: &mut ValueCtxt<T, U>,
134 ) -> GenApiResult<Option<f64>> {
135 Ok(None)
136 }
137
138 fn representation(&self, _: &impl NodeStore) -> FloatRepresentation {
139 self.representation
140 }
141
142 fn unit(&self, _: &impl NodeStore) -> Option<&str> {
143 self.unit_elem()
144 }
145
146 fn display_notation(&self, _: &impl NodeStore) -> DisplayNotation {
147 self.display_notation
148 }
149
150 fn display_precision(&self, _: &impl NodeStore) -> i64 {
151 self.display_precision
152 }
153
154 #[tracing::instrument(skip(self, store),
155 level = "trace",
156 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
157 fn set_min<T: ValueStore, U: CacheStore>(
158 &self,
159 _: f64,
160 _: &mut impl Device,
161 store: &impl NodeStore,
162 _: &mut ValueCtxt<T, U>,
163 ) -> GenApiResult<()> {
164 Err(GenApiError::not_writable())
165 }
166
167 #[tracing::instrument(skip(self, store),
168 level = "trace",
169 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
170 fn set_max<T: ValueStore, U: CacheStore>(
171 &self,
172 _: f64,
173 _: &mut impl Device,
174 store: &impl NodeStore,
175 _: &mut ValueCtxt<T, U>,
176 ) -> GenApiResult<()> {
177 Err(GenApiError::not_writable())
178 }
179
180 #[tracing::instrument(skip(self, device, store, cx),
181 level = "trace",
182 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
183 fn is_readable<T: ValueStore, U: CacheStore>(
184 &self,
185 device: &mut impl Device,
186 store: &impl NodeStore,
187 cx: &mut ValueCtxt<T, U>,
188 ) -> GenApiResult<bool> {
189 self.register_base().is_readable(device, store, cx)
190 }
191
192 #[tracing::instrument(skip(self, device, store, cx),
193 level = "trace",
194 fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
195 fn is_writable<T: ValueStore, U: CacheStore>(
196 &self,
197 device: &mut impl Device,
198 store: &impl NodeStore,
199 cx: &mut ValueCtxt<T, U>,
200 ) -> GenApiResult<bool> {
201 self.register_base().is_writable(device, store, cx)
202 }
203}
204
205impl IRegister for FloatRegNode {
206 fn read<T: ValueStore, U: CacheStore>(
207 &self,
208 buf: &mut [u8],
209 device: &mut impl Device,
210 store: &impl NodeStore,
211 cx: &mut ValueCtxt<T, U>,
212 ) -> GenApiResult<()> {
213 let address = self.address(device, store, cx)?;
214 let length = self.length(device, store, cx)?;
215 self.register_base().read_and_cache(
216 self.node_base().id(),
217 address,
218 length,
219 buf,
220 device,
221 store,
222 cx,
223 )
224 }
225
226 fn write<T: ValueStore, U: CacheStore>(
227 &self,
228 buf: &[u8],
229 device: &mut impl Device,
230 store: &impl NodeStore,
231 cx: &mut ValueCtxt<T, U>,
232 ) -> GenApiResult<()> {
233 self.register_base()
234 .write_and_cache(self.node_base().id(), buf, device, store, cx)
235 }
236
237 fn address<T: ValueStore, U: CacheStore>(
238 &self,
239 device: &mut impl Device,
240 store: &impl NodeStore,
241 cx: &mut ValueCtxt<T, U>,
242 ) -> GenApiResult<i64> {
243 self.register_base().address(device, store, cx)
244 }
245
246 fn length<T: ValueStore, U: CacheStore>(
247 &self,
248 device: &mut impl Device,
249 store: &impl NodeStore,
250 cx: &mut ValueCtxt<T, U>,
251 ) -> GenApiResult<i64> {
252 self.register_base().length(device, store, cx)
253 }
254}