cameleon_genapi/
float_reg.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use 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}