#include <Main/util.hxx>
#include "generic.hxx"
-
-
FGGeneric::FGGeneric(vector<string> tokens) : exitOnError(false)
{
size_t configToken;
} 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;
} 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;
} 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;
} 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;
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:
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
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);
}
}
}
+
+/*
+ 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)
+
e_type type;
double offset;
double factor;
+ double min, max;
+ bool wrap;
+ bool rel;
SGPropertyNode_ptr prop;
} _serial_prot;
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);
};