]> git.mxchange.org Git - simgear.git/blob - simgear/props/tiedpropertylist.hxx
Melchior FRANZ: fix SGPropertyNode::LAST_USED_ATTRIBUTE
[simgear.git] / simgear / props / tiedpropertylist.hxx
1 // tiedpropertylist.hxx -- Maintain tied properties
2 //
3 // Written by Torsten Dreyer started in 2010
4 //
5 // Copyright (C) 2010  Torsten Dreyer - torsten (at) t3r _dot_ de
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 #ifndef __TIEDPROPERTYLIST_HXX
22 #define  __TIEDPROPERTYLIST_HXX
23 #include <simgear/props/props.hxx>
24 #include <assert.h>
25
26 namespace simgear {
27
28 /** 
29  * @brief A list of tied properties that get automatically untied
30  * This helper class keeps track of tied properties and unties
31  * each tied property when this class gets destructed.
32 */
33 class TiedPropertyList : simgear::PropertyList {
34 public:
35     TiedPropertyList() {}
36     TiedPropertyList( SGPropertyNode_ptr root ) : _root(root) {}
37     virtual ~TiedPropertyList()
38     { 
39         _root = 0;
40         if (size()>0)
41         {
42             SG_LOG(SG_GENERAL, SG_ALERT, "Detected properties with dangling ties. Use 'Untie' before removing a TiedPropertyList.");
43             // running debug mode: go, fix it!
44             assert(size() == 0);
45         }
46     }
47
48     void setRoot( SGPropertyNode_ptr root ) { _root = root; }
49     SGPropertyNode_ptr getRoot() const { return _root; }
50
51     template<typename T> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, const SGRawValue<T> &rawValue, bool useDefault = true  ) {
52         bool success = node->tie( rawValue, useDefault );
53         if( success ) {
54             SG_LOG( SG_ALL, SG_INFO, "Tied " << node->getPath() );
55             push_back( node );
56         } else {
57 #if PROPS_STANDALONE
58             cerr << "Failed to tie property " << node->getPath() << endl;
59 #else
60             SG_LOG(SG_GENERAL, SG_WARN, "Failed to tie property " << node->getPath() );
61 #endif
62         }
63         return node;
64     }
65
66     template <class V> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, V * value, bool useDefault = true ) {
67         return Tie( node, SGRawValuePointer<V>(value), useDefault );
68     }
69
70     template <class V> SGPropertyNode_ptr Tie( const char * relative_path, V * value, bool useDefault = true ) {
71         return Tie( _root->getNode(relative_path,true), SGRawValuePointer<V>(value), useDefault );
72     }
73
74     template <class V> SGPropertyNode_ptr Tie( const char * relative_path, int prop_index, V * value, bool useDefault = true ) {
75         return Tie( _root->getNode(relative_path,prop_index,true), SGRawValuePointer<V>(value), useDefault );
76     }
77
78     template <class V> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true ) {
79         return Tie(node, SGRawValueFunctions<V>(getter, setter), useDefault );
80     }
81
82     template <class V> SGPropertyNode_ptr Tie( const char * relative_path, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true ) {
83         return Tie(_root->getNode(relative_path,true), SGRawValueFunctions<V>(getter, setter), useDefault );
84     }
85
86     template <class V> SGPropertyNode_ptr Tie( const char * relative_path, int prop_index, V (*getter)(), void (*setter)(V) = 0, bool useDefault = true ) {
87         return Tie(_root->getNode(relative_path,prop_index,true), SGRawValueFunctions<V>(getter, setter), useDefault );
88     }
89
90     template <class V> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) {
91         return Tie( node, SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault );
92     }
93
94     template <class V> SGPropertyNode_ptr Tie( const char * relative_path, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) {
95         return Tie( _root->getNode( relative_path, true ), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault );
96     }
97
98     template <class V> SGPropertyNode_ptr Tie( const char * relative_path, int prop_index, int index, V (*getter)(int), void (*setter)(int, V) = 0, bool useDefault = true) {
99         return Tie( _root->getNode( relative_path,prop_index,true ), SGRawValueFunctionsIndexed<V>(index, getter, setter), useDefault );
100     }
101
102     template <class T, class V> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) {
103         return Tie( node, SGRawValueMethods<T,V>(*obj, getter, setter), useDefault );
104     }
105
106     template <class T, class V> SGPropertyNode_ptr Tie( const char * relative_path, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) {
107         return Tie( _root->getNode( relative_path, true), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault );
108     }
109
110     template <class T, class V> SGPropertyNode_ptr Tie( const char * relative_path, int prop_index, T * obj, V (T::*getter)() const, void (T::*setter)(V) = 0, bool useDefault = true) {
111         return Tie( _root->getNode( relative_path,prop_index,true), SGRawValueMethods<T,V>(*obj, getter, setter), useDefault );
112     }
113
114     template <class T, class V> SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) {
115         return Tie( node, SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault);
116     }
117
118     template <class T, class V> SGPropertyNode_ptr Tie( const char * relative_path, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) {
119         return Tie( _root->getNode( relative_path, true ), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault);
120     }
121
122     template <class T, class V> SGPropertyNode_ptr Tie( const char * relative_path, int prop_index, T * obj, int index, V (T::*getter)(int) const, void (T::*setter)(int, V) = 0, bool useDefault = true) {
123         return Tie( _root->getNode( relative_path,prop_index,true ), SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter), useDefault);
124     }
125
126     void Untie() {
127         while( size() > 0 ) {
128             SG_LOG( SG_ALL, SG_INFO, "untie of " << back()->getPath() );
129             back()->untie();
130             pop_back();
131         }
132     }
133 private:
134     SGPropertyNode_ptr _root;
135 };
136
137 } // namespace
138 #endif