sac_base/network/node.rs
1use alloc::vec::Vec;
2use alloc::boxed::Box;
3use core::any::Any;
4
5pub struct Node<T>
6 where T: Copy + Clone
7{
8 /// Stores data required to process the functions. This data can be specified the operations
9 /// themselves. Allowing the operations to specify their own data containers, requires the
10 /// use of boxed trait objects. This unfortunately induces a bit over runtime overhead.
11 /// There might be a faster way to do this.
12 pub data_container: Box<dyn Any>,
13
14 /// Stores the data of the operation. This is the data that will be polled. This value is public
15 /// to allow others to change the value without having to call a function. Which is supped to
16 /// help speed up the setting and polling of data
17 pub data: Vec<T>,
18
19 /// A function pointer that will be called when the operation has to process its data.
20 /// All operations have to specify a function to process its data. This can as example contain
21 /// the functionality to add two values. Here they can mutate the value of self.data and access
22 /// the data contained in data_container.
23 /// The &Vec<T> acts an input from other operations. The length of the vector is dependant
24 /// on how many operations are connected to it.
25 /// Some operations can handle mutliple inputs (Add, Sub,...) while others like Diff can only
26 /// handle one inputs and will ignore the others.
27 pub clk: fn((Vec<&[T]>, usize), &mut Box<dyn Any>, &mut Vec<T>),
28}
29
30impl<T> Node<T>
31 where T: Copy + Clone
32{
33 /// Generates a new node. This is done by all the operations. A operation has to specify a
34 /// function according to which its data will be processed.
35 /// Additionally the node requires a value according to which it can initialize its data field.
36 /// If this wouldn't be provided, the network (and value) would be in a uninitialized state.
37 /// Each operation can choose to specify a container to store data in it.
38 /// Currently, all operations have to box a value and use it to init the node. This causes
39 /// some unnecessary RAM usage. Maybe this could be avoided with Box::new_uninit();
40 /// But this would put us into a undefined state which is to be avoided...
41 ///
42 /// ## Example
43 /// ```rust
44 /// use sac_base::network::node::Node;
45 /// use std::any::Any;
46 /// use core::ops;
47 ///
48 /// // Example code of the differentiation which uses an additional buffered value to safe the
49 /// // last state. Instead of just one value, a whole struct could be allocated and moved into
50 /// // the node as storage
51 /// fn new<T>() -> Node<T>
52 /// where T: Copy + ops::Sub<Output=T> + 'static + Default
53 /// {
54 /// let storage = Box::new(T::default()) as Box<dyn Any>;
55 /// let mut node = Node::new(storage, |data_input, data_buffer, output| {
56 /// let (inputs, max_len) = data_input;
57 /// let last_val: &mut T = data_buffer.downcast_mut::<T>().unwrap();
58 /// inputs.into_iter().take(1).into_iter().for_each(|data| {
59 /// data.into_iter().take(max_len).into_iter().for_each(|v| {
60 /// let diff_result = *v - *last_val;
61 /// output.insert(0, diff_result);
62 /// *last_val = *v;
63 /// })
64 /// })
65 /// });
66 /// // Make sure we got a default value in location 0 of the vector
67 /// node.data.push(T::default());
68 /// return node;
69 /// }
70 /// ```
71 pub fn new(container: Box<dyn Any>, clk: fn((Vec<&[T]>, usize),
72 &mut Box<dyn Any>, &mut Vec<T>)) -> Self {
73 Node {
74 data_container: container,
75 data: Vec::new(),
76 clk: clk,
77 }
78 }
79
80 /// Triggers the execution of the provided callback
81 pub fn process(&mut self, inputs: (Vec<&[T]>, usize)){
82 (self.clk)(inputs, &mut self.data_container, &mut self.data);
83 }
84
85 /// Sets the input value. Not necessarily needed since data is public.
86 pub fn feed(&mut self, input: &[T]) {
87 self.data = Vec::from(input);
88 }
89
90 /// Polls the value. Not necessarily needed since data is public.
91 /// Currently the data is copied when polled.
92 pub fn poll(&self) -> &[T] {
93 // Copy the vector to allow the next client to work with it.
94 // This is not ideal for performance and should be replace with a reference
95 return &self.data[..];
96 }
97}