Skip to content

Commit d280579

Browse files
authored
Clean up the properties code and Tie methods. (#1317)
1 parent f3f59eb commit d280579

File tree

4 files changed

+52
-133
lines changed

4 files changed

+52
-133
lines changed

src/input_output/FGPropertyManager.h

Lines changed: 18 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -56,35 +56,24 @@ INCLUDES
5656
FORWARD DECLARATIONS
5757
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
5858

59-
template<typename T> T getValue(const SGPropertyNode* node)
60-
{
61-
static_assert(std::is_enum_v<T>, "PropertyTraits specialization for enum types only");
62-
return static_cast<T>(node->getIntValue());
63-
}
64-
6559
template <class C, class T>
6660
class SGRawValueMethodsEnum : public SGRawValue<int>
6761
{
6862
public:
6963
typedef T(C::* getter_t)() const;
7064
typedef void (C::* setter_t)(T);
7165
SGRawValueMethodsEnum(C& obj,
72-
getter_t getter = 0, setter_t setter = 0)
73-
: _obj(obj), _getter(getter), _setter(setter) {
74-
}
75-
virtual ~SGRawValueMethodsEnum() {}
76-
virtual int getValue() const {
77-
if (_getter) { return (int)(_obj.*_getter)(); }
66+
getter_t getter = nullptr, setter_t setter = nullptr)
67+
: _obj(obj), _getter(getter), _setter(setter) {}
68+
int getValue() const override {
69+
if (_getter) { return static_cast<int>((_obj.*_getter)()); }
7870
else { return SGRawValue<int>::DefaultValue(); }
7971
}
80-
virtual bool setValue(int value) {
81-
return this->setValue((T)value);
82-
}
83-
bool setValue(T value) {
84-
if (_setter) { (_obj.*_setter)(value); return true; }
72+
bool setValue(int value) override {
73+
if (_setter) { (_obj.*_setter)(static_cast<T>(value)); return true; }
8574
else return false;
8675
}
87-
virtual SGRaw* clone() const {
76+
SGRaw* clone() const override {
8877
return new SGRawValueMethodsEnum(_obj, _getter, _setter);
8978
}
9079
private:
@@ -100,19 +89,17 @@ class SGRawValueMethodsIndexedEnum : public SGRawValue<T>
10089
typedef T(C::* getter_t)(U) const;
10190
typedef void (C::* setter_t)(U, T);
10291
SGRawValueMethodsIndexedEnum(C& obj, U index,
103-
getter_t getter = 0, setter_t setter = 0)
104-
: _obj(obj), _index(index), _getter(getter), _setter(setter) {
105-
}
106-
virtual ~SGRawValueMethodsIndexedEnum() {}
107-
virtual T getValue() const {
92+
getter_t getter = nullptr, setter_t setter = nullptr)
93+
: _obj(obj), _index(index), _getter(getter), _setter(setter) {}
94+
T getValue() const override {
10895
if (_getter) { return (_obj.*_getter)(_index); }
10996
else { return SGRawValue<T>::DefaultValue(); }
11097
}
111-
virtual bool setValue(T value) {
98+
bool setValue(T value) override {
11299
if (_setter) { (_obj.*_setter)(_index, value); return true; }
113100
else return false;
114101
}
115-
virtual SGRaw* clone() const {
102+
SGRaw* clone() const override {
116103
return new SGRawValueMethodsIndexedEnum(_obj, _index, _getter, _setter);
117104
}
118105
private:
@@ -249,77 +236,6 @@ class JSBSIM_API FGPropertyManager
249236
}
250237
}
251238

252-
/**
253-
* Tie a property to a pair of simple functions.
254-
*
255-
* Every time the property value is queried, the getter (if any) will
256-
* be invoked; every time the property value is modified, the setter
257-
* (if any) will be invoked. The getter can be 0 to make the property
258-
* unreadable, and the setter can be 0 to make the property
259-
* unmodifiable.
260-
*
261-
* @param name The property name to tie (full path).
262-
* @param getter The getter function, or 0 if the value is unreadable.
263-
* @param setter The setter function, or 0 if the value is unmodifiable.
264-
*/
265-
266-
template <typename T> void
267-
Tie (const std::string &name, T (*getter)(), void (*setter)(T) = nullptr)
268-
{
269-
SGPropertyNode* property = root->getNode(name.c_str(), true);
270-
if (!property) {
271-
std::cerr << "Could not get or create property " << name << std::endl;
272-
return;
273-
}
274-
275-
if (!property->tie(SGRawValueFunctions<T>(getter, setter), false))
276-
std::cerr << "Failed to tie property " << name << " to functions"
277-
<< std::endl;
278-
else {
279-
tied_properties.push_back(PropertyState(property, nullptr));
280-
if (!setter) property->setAttribute(SGPropertyNode::WRITE, false);
281-
if (!getter) property->setAttribute(SGPropertyNode::READ, false);
282-
if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
283-
}
284-
}
285-
286-
/**
287-
* Tie a property to a pair of indexed functions.
288-
*
289-
* Every time the property value is queried, the getter (if any) will
290-
* be invoked with the index provided; every time the property value
291-
* is modified, the setter (if any) will be invoked with the index
292-
* provided. The getter can be 0 to make the property unreadable, and
293-
* the setter can be 0 to make the property unmodifiable.
294-
*
295-
* @param name The property name to tie (full path).
296-
* @param index The integer argument to pass to the getter and
297-
* setter functions.
298-
* @param getter The getter function, or 0 if the value is unreadable.
299-
* @param setter The setter function, or 0 if the value is unmodifiable.
300-
*/
301-
template <typename T> void
302-
Tie (const std::string &name, int index, T (*getter)(int),
303-
void (*setter)(int, T) = nullptr)
304-
{
305-
SGPropertyNode* property = root->getNode(name.c_str(), true);
306-
if (!property) {
307-
std::cerr << "Could not get or create property " << name << std::endl;
308-
return;
309-
}
310-
311-
if (!property->tie(SGRawValueFunctionsIndexed<T>(index, getter, setter),
312-
false))
313-
std::cerr << "Failed to tie property " << name << " to indexed functions"
314-
<< std::endl;
315-
else {
316-
tied_properties.push_back(PropertyState(property, nullptr));
317-
if (!setter) property->setAttribute(SGPropertyNode::WRITE, false);
318-
if (!getter) property->setAttribute(SGPropertyNode::READ, false);
319-
if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
320-
}
321-
}
322-
323239
/**
324240
* Tie a property to a pair of object methods.
325241
*
@@ -337,7 +253,7 @@ class JSBSIM_API FGPropertyManager
337253
* unmodifiable.
338254
*/
339255
template <class T, class V>
340-
typename std::enable_if<std::is_enum_v<V>, void>::type
256+
typename std::enable_if_t<std::is_enum_v<V>, void>
341257
Tie (const std::string &name, T * obj, V (T::*getter)() const,
342258
void (T::*setter)(V) = nullptr)
343259
{
@@ -357,8 +273,9 @@ class JSBSIM_API FGPropertyManager
357273
if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
358274
}
359275
}
276+
360277
template <class T, class V>
361-
typename std::enable_if<!std::is_enum_v<V>, void>::type
278+
typename std::enable_if_t<!std::is_enum_v<V>, void>
362279
Tie (const std::string &name, T * obj, V (T::*getter)() const,
363280
void (T::*setter)(V) = nullptr)
364281
{
@@ -433,11 +350,11 @@ class JSBSIM_API FGPropertyManager
433350
* @param getter The getter method, or 0 if the value is unreadable.
434351
* @param setter The setter method, or 0 if the value is unmodifiable.
435352
*/
436-
template <class T, class V, class U> void
437-
Tie(const std::string& name, T* obj, U index, V(T::* getter)(U) const,
353+
template <class T, class V, class U>
354+
typename std::enable_if_t<std::is_enum_v<U>, void>
355+
Tie(const std::string& name, T* obj, U index, V(T::* getter)(U) const,
438356
void (T::* setter)(U, V) = nullptr)
439357
{
440-
static_assert(std::is_enum_v<U>, "Specialization for enum types only");
441358
SGPropertyNode* property = root->getNode(name.c_str(), true);
442359
if (!property) {
443360
std::cerr << "Could not get or create property " << name << std::endl;

src/models/FGPropagate.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,6 @@ INCLUDES
7474

7575
using namespace std;
7676

77-
// Property traits specialization to tie properties using FGPropagate enums.
78-
namespace simgear::props {
79-
template<> struct PropertyTraits<JSBSim::FGPropagate::eIntegrateType> : public PropertyTraits<int> {};
80-
};
81-
8277
namespace JSBSim {
8378

8479
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

src/models/atmosphere/FGWinds.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ INCLUDES
5050

5151
using namespace std;
5252

53-
// Property traits specialization to tie properties using FGWinds enums.
54-
namespace simgear::props {
55-
template<> struct PropertyTraits<JSBSim::FGWinds::tType> : public PropertyTraits<int> {};
56-
template<> struct PropertyTraits<JSBSim::FGWinds::eGustFrame> : public PropertyTraits<int> {};
57-
};
58-
5953
namespace JSBSim {
6054

6155
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

src/simgear/props/props.cxx

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <iterator>
2121
#include <stdio.h>
2222
#include <string.h>
23+
#include <cassert>
2324

2425
#if PROPS_STANDALONE
2526
# include <iostream>
@@ -555,11 +556,23 @@ find_node (SGPropertyNode * current,
555556
// Private methods from SGPropertyNode (may be inlined for speed).
556557
////////////////////////////////////////////////////////////////////////
557558

559+
template <typename T>
560+
inline T getValueFromRaw(SGRaw* value)
561+
{
562+
#ifdef NDEBUG
563+
return static_cast<SGRawValue<T>*>(value)->getValue();
564+
#else
565+
auto raw_value = dynamic_cast<SGRawValue<T>*>(value);
566+
assert(raw_value); // Intercepts casting errors in debug mode.
567+
return raw_value->getValue();
568+
#endif
569+
}
570+
558571
inline bool
559572
SGPropertyNode::get_bool () const
560573
{
561574
if (_tied)
562-
return static_cast<SGRawValue<bool>*>(_value.val)->getValue();
575+
return getValueFromRaw<bool>(_value.val);
563576
else
564577
return _local_val.bool_val;
565578
}
@@ -568,7 +581,7 @@ inline int
568581
SGPropertyNode::get_int () const
569582
{
570583
if (_tied)
571-
return (static_cast<SGRawValue<int>*>(_value.val))->getValue();
584+
return getValueFromRaw<int>(_value.val);
572585
else
573586
return _local_val.int_val;
574587
}
@@ -577,7 +590,7 @@ inline long
577590
SGPropertyNode::get_long () const
578591
{
579592
if (_tied)
580-
return static_cast<SGRawValue<long>*>(_value.val)->getValue();
593+
return getValueFromRaw<long>(_value.val);
581594
else
582595
return _local_val.long_val;
583596
}
@@ -586,7 +599,7 @@ inline float
586599
SGPropertyNode::get_float () const
587600
{
588601
if (_tied)
589-
return static_cast<SGRawValue<float>*>(_value.val)->getValue();
602+
return getValueFromRaw<float>(_value.val);
590603
else
591604
return _local_val.float_val;
592605
}
@@ -595,7 +608,7 @@ inline double
595608
SGPropertyNode::get_double () const
596609
{
597610
if (_tied)
598-
return static_cast<SGRawValue<double>*>(_value.val)->getValue();
611+
return getValueFromRaw<double>(_value.val);
599612
else
600613
return _local_val.double_val;
601614
}
@@ -604,7 +617,7 @@ inline const char *
604617
SGPropertyNode::get_string () const
605618
{
606619
if (_tied)
607-
return static_cast<SGRawValue<const char*>*>(_value.val)->getValue();
620+
return getValueFromRaw<const char*>(_value.val);
608621
else
609622
return _local_val.string_val;
610623
}
@@ -838,12 +851,12 @@ const int SGPropertyNode::LAST_USED_ATTRIBUTE = PRESERVE;
838851
* Default constructor: always creates a root node.
839852
*/
840853
SGPropertyNode::SGPropertyNode ()
841-
: _parent(nullptr),
842-
_listeners(nullptr),
843-
_index(0),
854+
: _index(0),
855+
_parent(nullptr),
844856
_type(props::NONE),
845857
_tied(false),
846-
_attr(READ|WRITE)
858+
_attr(READ|WRITE),
859+
_listeners(nullptr)
847860
{
848861
_local_val.string_val = 0;
849862
_value.val = 0;
@@ -855,13 +868,13 @@ SGPropertyNode::SGPropertyNode ()
855868
*/
856869
SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
857870
: SGReferenced(node),
858-
_parent(nullptr), // don't copy the parent
859-
_listeners(nullptr), // CHECK!!
860871
_index(node._index),
861872
_name(node._name),
873+
_parent(nullptr), // don't copy the parent
862874
_type(node._type),
863875
_tied(node._tied),
864-
_attr(node._attr)
876+
_attr(node._attr),
877+
_listeners(nullptr) // CHECK!!
865878
{
866879
_local_val.string_val = 0;
867880
_value.val = 0;
@@ -910,13 +923,13 @@ template<typename Itr>
910923
SGPropertyNode::SGPropertyNode (Itr begin, Itr end,
911924
int index,
912925
SGPropertyNode * parent)
913-
: _parent(parent),
914-
_listeners(nullptr),
915-
_index(index),
926+
: _index(index),
916927
_name(begin, end),
928+
_parent(parent),
917929
_type(props::NONE),
918930
_tied(false),
919-
_attr(READ|WRITE)
931+
_attr(READ|WRITE),
932+
_listeners(nullptr)
920933
{
921934
_local_val.string_val = 0;
922935
_value.val = 0;
@@ -927,13 +940,13 @@ SGPropertyNode::SGPropertyNode (Itr begin, Itr end,
927940
SGPropertyNode::SGPropertyNode( const std::string& name,
928941
int index,
929942
SGPropertyNode * parent)
930-
: _parent(parent),
931-
_listeners(nullptr),
932-
_index(index),
943+
: _index(index),
933944
_name(name),
945+
_parent(parent),
934946
_type(props::NONE),
935947
_tied(false),
936-
_attr(READ|WRITE)
948+
_attr(READ|WRITE),
949+
_listeners(nullptr)
937950
{
938951
_local_val.string_val = 0;
939952
_value.val = 0;

0 commit comments

Comments
 (0)