cameleon_genapi/
command.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::ImmOrPNode,
7    interface::{ICommand, INode},
8    ivalue::IValue,
9    node_base::{NodeAttributeBase, NodeBase, NodeElementBase},
10    store::{CacheStore, IntegerId, NodeStore, ValueStore},
11    Device, GenApiResult, ValueCtxt,
12};
13
14#[derive(Debug, Clone)]
15pub struct CommandNode {
16    pub(crate) attr_base: NodeAttributeBase,
17    pub(crate) elem_base: NodeElementBase,
18
19    pub(crate) value: ImmOrPNode<IntegerId>,
20    pub(crate) command_value: ImmOrPNode<IntegerId>,
21    pub(crate) polling_time: Option<u64>,
22}
23
24impl CommandNode {
25    #[must_use]
26    pub fn value_elem(&self) -> ImmOrPNode<IntegerId> {
27        self.value
28    }
29
30    #[must_use]
31    pub fn command_value_elem(&self) -> ImmOrPNode<IntegerId> {
32        self.command_value
33    }
34
35    #[must_use]
36    pub fn polling_time(&self) -> Option<u64> {
37        self.polling_time
38    }
39}
40
41impl INode for CommandNode {
42    fn node_base(&self) -> NodeBase {
43        NodeBase::new(&self.attr_base, &self.elem_base)
44    }
45
46    fn streamable(&self) -> bool {
47        false
48    }
49}
50
51impl ICommand for CommandNode {
52    #[tracing::instrument(skip(self, device, store, cx),
53                          fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
54    fn execute<T: ValueStore, U: CacheStore>(
55        &self,
56        device: &mut impl Device,
57        store: &impl NodeStore,
58        cx: &mut ValueCtxt<T, U>,
59    ) -> GenApiResult<()> {
60        cx.invalidate_cache_by(self.node_base().id());
61
62        let value: i64 = self.command_value.value(device, store, cx)?;
63        self.value.set_value(value, device, store, cx)
64    }
65
66    #[tracing::instrument(skip(self, device, store, cx),
67                          fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
68    fn is_done<T: ValueStore, U: CacheStore>(
69        &self,
70        device: &mut impl Device,
71        store: &impl NodeStore,
72        cx: &mut ValueCtxt<T, U>,
73    ) -> GenApiResult<bool> {
74        let node = match self.value {
75            ImmOrPNode::Imm(..) => return Ok(true),
76            ImmOrPNode::PNode(nid) => nid,
77        };
78
79        cx.invalidate_cache_of(node);
80        if IValue::<i64>::is_readable(&node, device, store, cx)? {
81            let command_value: i64 = self.command_value.value(device, store, cx)?;
82            let reg_value = node.value(device, store, cx)?;
83            Ok(command_value != reg_value)
84        } else {
85            Ok(true)
86        }
87    }
88
89    #[tracing::instrument(skip(self, device, store, cx),
90                          level = "trace",
91                          fields(node = store.name_by_id(self.node_base().id()).unwrap()))]
92    fn is_writable<T: ValueStore, U: CacheStore>(
93        &self,
94        device: &mut impl Device,
95        store: &impl NodeStore,
96        cx: &mut ValueCtxt<T, U>,
97    ) -> GenApiResult<bool> {
98        Ok(self.elem_base.is_writable(device, store, cx)?
99            && IValue::<i64>::is_writable(&self.value, device, store, cx)?)
100    }
101}