-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvariable.h
134 lines (115 loc) · 2.86 KB
/
variable.h
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
126
127
128
129
130
131
132
133
134
/**
* @file MMAP Variables
*/
#ifndef BASE_H
#define BASE_H
#include "data_serialization.h"
namespace MMap
{
/**
* @brief Saturation function
*
* @param a Variable
* @tparam min Min value
* @tparam max Max value
*/
template<typename T, typename min, typename max>
inline void saturation(T& a)
{
a = a > max::value ? max::value : ( a < min::value ? min::value : a );
}
/**
* @brief Access class for read and write permission check
* Implementation try to emulate scoped enumerations behavior
*/
struct Access
{
enum type
{
RW = 0U,
R = 1U
};
Access(type t) : value_(t) {}
operator type() const { return value_; }
private:
type value_;
};
//------------------------------------------------------------------------------
/**
* @brief Storage class for RAM or EEPROM check
* Implementation try to emulate scoped enumerations behavior
*/
struct Storage
{
enum type
{
RAM = 0U,
EEPROM = 1U
};
Storage(type t) : value_(t) {}
operator type() const { return value_; }
private:
type value_;
};
//------------------------------------------------------------------------------
/**
* @class ContainerBase
* @brief Virtual base class for MMap variables.
*/
class VariableBase
{
public:
VariableBase(Access access, Storage storage):
access_(access),
storage_(storage) {};
virtual uint8_t serialize(uint8_t *outbuffer) const = 0;
virtual uint8_t deserialize(uint8_t *inbuffer, bool overrride = false) = 0;
virtual void setDefault();
virtual uint8_t size() = 0;
public:
const Access access_; ///< Access type
const Storage storage_; ///< Storage type
};
typedef VariableBase* VariableBasePtr;
template <typename MessageT, typename min, typename max, typename def>
class Variable : public VariableBase, public MessageT
{
public:
Variable(Access access, Storage storage):
VariableBase(access, storage)
{}
typedef typename MessageT::type DataType;
uint8_t serialize(uint8_t *outbuffer) const
{
return MessageT::serialize(outbuffer);
}
uint8_t deserialize(uint8_t *inbuffer, bool overrride = false)
{
// Check for read only
if (access_ == Access::R && !overrride)
return sizeof(MessageT::data);
uint8_t size = MessageT::deserialize(inbuffer);
saturation<DataType, min, max>(MessageT::data);
return size;
}
void setDefault()
{
MessageT::data = def::value;
}
inline uint8_t size()
{
return sizeof(MessageT::data);
}
};
template <typename T, typename T::type min, typename T::type max, typename T::type def>
struct Integer
{
typedef Variable<T, ConstInt<typename T::type, min>, ConstInt<typename T::type, max>, ConstInt<typename T::type, def> > type;
};
template <typename min, typename max, typename def>
struct Float
{
typedef Variable<Float32, min, max, def> type;
};
}
#endif