1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#![no_std]

use core::i32;

use heapless::LinearMap;
use generic_array::GenericArray;
use generic_array::sequence::GenericSequence;
use typenum::marker_traits::PowerOfTwo;

pub const NAME_SZ : usize = 24;

#[derive(Clone,Copy,Debug,PartialEq)]
pub enum ValueType {
    Bool  = 0,
    Int   = 1,
    Float = 2,
}

#[derive(Clone)]
pub struct ValueRec<P> where P: generic_array::ArrayLength<i32> {
    pub is_active     : bool,
    pub is_only_front : bool,
    pub vtype : ValueType,
    pub vals : GenericArray<i32, P>,
}

impl<P> ValueRec<P> where P: generic_array::ArrayLength<i32> {
    pub fn new(vtype: ValueType) -> ValueRec<P> {
        ValueRec {
            is_active: false,
            is_only_front: false,
            vtype,
            vals: GenericArray::generate(|_| {0i32})
        }
    }
}

pub enum AddError {
    MapOverflow,
}

#[derive(Clone,Copy)]
pub struct SVstruct<M> {
    current: usize,
    pub map: M
}

pub type SV<N, P> = SVstruct<LinearMap<&'static [u8], ValueRec<P>, N>>;

pub trait AddValue {
    fn add_bool_value (&mut self, name: &'static [u8], value_in: bool, only_pos_front: bool
    ) -> Result<(), AddError> {
        Ok(self.add_value(name, ValueType::Bool, i32::from(value_in), only_pos_front)?)
    }
    
    fn add_int_value (&mut self, name: &'static [u8], value_in: i32
    ) -> Result<(), AddError> {
        Ok(self.add_value(name, ValueType::Int, value_in, false)?)
    }
    
    fn add_float_value (&mut self, name: &'static [u8], value_in: f32
    ) -> Result<(), AddError> {
        Ok(self.add_value(name, ValueType::Float, value_in.to_bits() as i32, false)?)
    }
    
    fn add_value (&mut self, name: &'static [u8], vtype: ValueType, val: i32, only_pos_front: bool
    ) -> Result<(), AddError>;
}

impl<N, P> SV<N, P>
where
    N: heapless::ArrayLength<(&'static [u8], ValueRec<P>)> + PowerOfTwo,
    P: generic_array::ArrayLength<i32> + typenum::marker_traits::Unsigned
{
    pub fn new() -> Self {
        Self {
            current: 0,
            map: LinearMap::new()
        }
    }
    
    pub fn next<F>(&mut self, f: F)
    where
        F: FnOnce(&Self) {
        let previous = self.current;
        self.current += 1;
        let packet_size = P::to_usize();
        if self.current >= packet_size {
            self.current -= packet_size;
            f(self);
        }
        for (_, v) in self.map.iter_mut() {
            v.vals[self.current] = v.vals[previous]
        }
    }
}

impl<N, P> AddValue for SV<N, P>
where
    N: heapless::ArrayLength<(&'static [u8], ValueRec<P>)>,
    P: generic_array::ArrayLength<i32>
{
    fn add_value(
        &mut self,
        name: &'static [u8],
        vtype: ValueType,
        val: i32,
        only_pos_front: bool
    ) -> Result<(), AddError> {
        if !self.map.contains_key(&name) {
            debug_assert!((name.len() > 0) && (name.len() <= NAME_SZ));
            debug_assert!((name != b"=end=") && (name != b"=begin="));
            if self.map.insert(name, ValueRec::new(vtype)).is_err() {
                return Err(AddError::MapOverflow);
            }
        }
        
        let vr = self.map.get_mut(name).unwrap();
        vr.vals[self.current] = val;
        vr.is_active = true;
        vr.is_only_front = only_pos_front;
        
        Ok(())
    }
}