flowrs_std/nodes/
add.rs

1use std::any::Any;
2use std::ops::Add;
3use std::rc::Rc;
4
5use serde_json::Value;
6
7use flowrs::{
8    connection::{Input, Output, RuntimeConnectable},
9    node::{Context, Node, SequenceError, State, UpdateError},
10};
11use flowrs_derive::Connectable;
12
13#[derive(Clone)]
14enum AddNodeState<I1, I2> {
15    I1(I1),
16    I2(I2),
17    None,
18}
19
20#[derive(Connectable)]
21pub struct AddNode<I1, I2, O>
22where
23    I1: Clone,
24    I2: Clone,
25{
26    name: String,
27    state: State<AddNodeState<I1, I2>>,
28    _props: Value,
29    _context: State<Context>,
30
31    #[input]
32    pub input_1: Input<I1>,
33    #[input]
34    pub input_2: Input<I2>,
35    #[output]
36    pub output_1: Output<O>,
37}
38
39impl<I1, I2, O> AddNode<I1, I2, O>
40where
41    I1: Clone + Add<I2, Output = O> + Send + 'static,
42    I2: Clone + Send + 'static,
43    O: Clone + Send + 'static,
44{
45    pub fn new(name: &str, context: State<Context>, props: Value) -> Self {
46        Self {
47            name: name.into(),
48            state: State::new(AddNodeState::None),
49            _props: props,
50            _context: context.clone(),
51
52            input_1: Input::new(),
53            input_2: Input::new(),
54            output_1: Output::new(context.clone()),
55        }
56    }
57
58    fn handle_1(&self, v: I1) -> Result<(), UpdateError> {
59        let mut state = self.state.0.lock().unwrap();
60        match state.clone() {
61            AddNodeState::I1(_) => {
62                return Err(UpdateError::SequenceError(SequenceError {
63                    node: self.name().into(),
64                    message: "Addition should happen pairwise.".into(),
65                }))
66            }
67            AddNodeState::I2(i) => {
68                let out = v + i.clone();
69                *state = AddNodeState::None;
70                let _ = self.output_1.clone().send(out);
71            }
72            AddNodeState::None => *state = AddNodeState::I1(v),
73        }
74        Ok(())
75    }
76
77    fn handle_2(&self, v: I2) -> Result<(), UpdateError> {
78        let mut state = self.state.0.lock().unwrap();
79        match state.clone() {
80            AddNodeState::I2(_) => {
81                return Err(UpdateError::SequenceError(SequenceError {
82                    node: self.name().into(),
83                    message: "Addition should happen pairwise.".into(),
84                }))
85            }
86            AddNodeState::I1(i) => {
87                let out = i.clone() + v;
88                *state = AddNodeState::None;
89                let _ = self.output_1.clone().send(out);
90            }
91            AddNodeState::None => *state = AddNodeState::I2(v),
92        }
93        Ok(())
94    }
95}
96
97impl<I1, I2, O> Node for AddNode<I1, I2, O>
98where
99    I1: Add<I2, Output = O> + Clone + Send + 'static,
100    I2: Clone + Send + 'static,
101    O: Clone + Send + 'static,
102{
103    fn on_init(&self) {}
104
105    fn on_ready(&self) {}
106
107    fn on_shutdown(&self) {}
108
109    fn name(&self) -> &str {
110        &self.name
111    }
112
113    // To be replaced by macro
114    fn update(&self) -> Result<(), UpdateError> {
115        if let Ok(i1) = self.input_1.next_elem() {
116            println!("UPDATE1");
117            self.handle_1(i1)?;
118        }
119
120        if let Ok(i2) = self.input_2.next_elem() {
121            println!("UPDATE2");
122            self.handle_2(i2)?;
123        }
124        Ok(())
125    }
126}