Skip to main content

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}