1
0
Fork 0

Support relative changes and wrapping for generic protocol input.

This commit is contained in:
Thomas Geymayer 2011-12-27 18:56:52 +01:00 committed by ThorstenB
parent 93a5765d08
commit 4ec6810c29
2 changed files with 69 additions and 27 deletions

View file

@ -41,8 +41,6 @@
#include <Main/util.hxx>
#include "generic.hxx"
FGGeneric::FGGeneric(vector<string> tokens) : exitOnError(false)
{
size_t configToken;
@ -288,10 +286,7 @@ bool FGGeneric::parse_message_binary(int length) {
} else {
tmp32 = *(int32_t *)p1;
}
val = _in_message[i].offset + (double)tmp32 * _in_message[i].factor;
_in_message[i].prop->setIntValue((int)val);
updateValue(_in_message[i], (int)tmp32);
p1 += sizeof(int32_t);
break;
@ -306,11 +301,7 @@ bool FGGeneric::parse_message_binary(int length) {
} else {
tmp32 = *(int32_t *)p1;
}
val = _in_message[i].offset +
((double)tmp32 / 65536.0f) * _in_message[i].factor;
_in_message[i].prop->setFloatValue(val);
updateValue(_in_message[i], (float)tmp32 / 65536.0f);
p1 += sizeof(int32_t);
break;
@ -321,11 +312,7 @@ bool FGGeneric::parse_message_binary(int length) {
} else {
tmpun32.floatVal = *(float *)p1;
}
val = _in_message[i].offset +
tmpun32.floatVal * _in_message[i].factor;
_in_message[i].prop->setFloatValue(val);
updateValue(_in_message[i], tmpun32.floatVal);
p1 += sizeof(int32_t);
break;
@ -336,11 +323,7 @@ bool FGGeneric::parse_message_binary(int length) {
} else {
tmpun64.doubleVal = *(double *)p1;
}
val = _in_message[i].offset +
tmpun64.doubleVal * _in_message[i].factor;
_in_message[i].prop->setDoubleValue(val);
updateValue(_in_message[i], tmpun64.doubleVal);
p1 += sizeof(int64_t);
break;
@ -378,8 +361,7 @@ bool FGGeneric::parse_message_ascii(int length) {
switch (_in_message[i].type) {
case FG_INT:
val = _in_message[i].offset + atoi(p1) * _in_message[i].factor;
_in_message[i].prop->setIntValue((int)val);
updateValue(_in_message[i], atoi(p1));
break;
case FG_BOOL:
@ -388,13 +370,11 @@ bool FGGeneric::parse_message_ascii(int length) {
case FG_FIXED:
case FG_FLOAT:
val = _in_message[i].offset + strtod(p1, 0) * _in_message[i].factor;
_in_message[i].prop->setFloatValue((float)val);
updateValue(_in_message[i], (float)strtod(p1, 0));
break;
case FG_DOUBLE:
val = _in_message[i].offset + strtod(p1, 0) * _in_message[i].factor;
_in_message[i].prop->setDoubleValue(val);
updateValue(_in_message[i], (double)strtod(p1, 0));
break;
default: // SG_STRING
@ -686,6 +666,10 @@ FGGeneric::read_config(SGPropertyNode *root, vector<_serial_prot> &msg)
chunk.format = fgUnescape(chunks[i]->getStringValue("format", "%d"));
chunk.offset = chunks[i]->getDoubleValue("offset");
chunk.factor = chunks[i]->getDoubleValue("factor", 1.0);
chunk.min = chunks[i]->getDoubleValue("min");
chunk.max = chunks[i]->getDoubleValue("max");
chunk.wrap = chunks[i]->getBoolValue("wrap");
chunk.rel = chunks[i]->getBoolValue("relative");
string node = chunks[i]->getStringValue("node", "/null");
chunk.prop = fgGetNode(node.c_str(), true);
@ -727,3 +711,24 @@ FGGeneric::read_config(SGPropertyNode *root, vector<_serial_prot> &msg)
}
}
}
/*
set/getValue: Implementations for supported datatypes
*/
#define DEF_DATA_ACCESS(type, method)\
template<>\
const type FGGeneric::getValue(SGPropertyNode_ptr& prop)\
{\
return prop->get##method##Value();\
}\
\
template<>\
void FGGeneric::setValue(SGPropertyNode_ptr& prop, const type& val)\
{\
prop->set##method##Value(val);\
}
DEF_DATA_ACCESS(int, Int)
DEF_DATA_ACCESS(float, Float)
DEF_DATA_ACCESS(double, Double)

View file

@ -67,6 +67,9 @@ protected:
e_type type;
double offset;
double factor;
double min, max;
bool wrap;
bool rel;
SGPropertyNode_ptr prop;
} _serial_prot;
@ -99,6 +102,40 @@ private:
bool parse_message_binary(int length);
void read_config(SGPropertyNode *root, vector<_serial_prot> &msg);
bool exitOnError;
template<class T>
static void updateValue(_serial_prot& prot, const T& val)
{
T new_val = (prot.rel ? getValue<T>(prot.prop) : 0)
+ prot.offset
+ prot.factor * val;
if( prot.max > prot.min )
{
if( prot.wrap )
{
T range = prot.max - prot.min + 1;
if( range > 0 )
{
while( new_val < prot.min )
new_val += range;
while( new_val > prot.max )
new_val -= range;
}
}
else
new_val = std::min<T>(prot.max, std::max<T>(prot.min, new_val));
}
setValue(prot.prop, new_val);
}
template<class T>
static const T getValue(SGPropertyNode_ptr& prop);
template<class T>
static void setValue(SGPropertyNode_ptr& prop, const T& val);
};