]> git.mxchange.org Git - simgear.git/blob - simgear/props/propertyObject.hxx
Update doxgen config and some comments.
[simgear.git] / simgear / props / propertyObject.hxx
1 // Copyright (C) 2010  James Turner - zakalawe@mac.com
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 //
17
18 #ifndef SG_PROPERTY_OBJECT
19 #define SG_PROPERTY_OBJECT
20
21 #include <simgear/props/props.hxx>
22
23 namespace simgear
24 {
25
26 class PropertyObjectBase
27 {
28 public:
29   static void setDefaultRoot(SGPropertyNode* aRoot);
30   
31   PropertyObjectBase();
32   
33   PropertyObjectBase(const PropertyObjectBase& aOther);
34     
35   PropertyObjectBase(const char* aChild);
36   
37   PropertyObjectBase(SGPropertyNode* aNode, const char* aChild = NULL);
38   
39   SGPropertyNode* node(bool aCreate) const;
40
41   /**
42    * Resolve the property node, or throw an exception if it could not
43    * be resolved.
44    */
45   SGPropertyNode* getOrThrow() const;
46 protected:
47   mutable const char* _path;
48
49   /**
50    * Important - if _path is NULL, this is the actual prop.
51    * If path is non-NULL, this is the parent which path should be resolved
52    * against (or NULL, if _path is absolute). Use node() instead of accessing
53    * this directly, and the above is handled automatically. 
54    */
55   mutable SGPropertyNode* _prop;
56 };
57
58 template <typename T>
59 class PropertyObject : PropertyObjectBase
60 {
61 public:
62   PropertyObject()
63   {}
64   
65   /**
66    * Create from path relative to the default root, and option default value
67    */
68   explicit PropertyObject(const char* aChild) :
69     PropertyObjectBase(aChild)
70   { }
71   
72   /**
73    * Create from a node, with optional relative path
74    */
75   explicit PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
76     PropertyObjectBase(aNode, aChild)
77   {
78   
79   }
80   
81 // copy-constructor
82   PropertyObject(const PropertyObject<T>& aOther) :
83     PropertyObjectBase(aOther)
84   {
85   }
86
87 // create() form creates the property immediately
88   static PropertyObject<T> create(const char* aPath, T aValue)
89   {
90     PropertyObject<T> p(aPath);
91     p = aValue;
92     return p;
93   }
94   
95   static PropertyObject<T> create(SGPropertyNode* aNode, T aValue)
96   {
97     PropertyObject<T> p(aNode);
98     p = aValue;
99     return p;
100   }
101
102   static PropertyObject<T> create(SGPropertyNode* aNode, const char* aChild, T aValue)
103   {
104     PropertyObject<T> p(aNode, aChild);
105     p = aValue;
106     return p;
107   }
108   
109 // conversion operators
110   operator T () const
111   {
112     return getOrThrow()->template getValue<T>();
113   }
114
115   T operator=(const T& aValue)
116   {
117     SGPropertyNode* n = PropertyObjectBase::node(true);
118     if( !n )
119       return aValue;
120
121     n->setValue<T>(aValue);
122     return aValue;
123   }
124
125 #define SG_DEF_ASSIGN_OP(op)\
126   T operator op##=(const T rhs)\
127   {\
128     SGPropertyNode* n = getOrThrow();\
129     T new_val = n->getValue<T>() op rhs;\
130     n->setValue<T>(new_val);\
131     return new_val;\
132   }
133
134   SG_DEF_ASSIGN_OP(+)
135   SG_DEF_ASSIGN_OP(-)
136   SG_DEF_ASSIGN_OP(*)
137   SG_DEF_ASSIGN_OP(/)
138   SG_DEF_ASSIGN_OP(%)
139   SG_DEF_ASSIGN_OP(>>)
140   SG_DEF_ASSIGN_OP(<<)
141   SG_DEF_ASSIGN_OP(&)
142   SG_DEF_ASSIGN_OP(^)
143   SG_DEF_ASSIGN_OP(|)
144
145 #undef SG_DEF_ASSIGN_OP
146
147   SGPropertyNode* node() const
148   {
149     return PropertyObjectBase::node(false);
150   }
151 }; // of template PropertyObject
152
153
154 // specialization for const char* / std::string
155
156 template <>
157 class PropertyObject<std::string> : PropertyObjectBase
158 {
159 public:
160   explicit PropertyObject(const char* aChild) :
161     PropertyObjectBase(aChild)
162   { }
163   
164
165   
166   explicit PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
167     PropertyObjectBase(aNode, aChild)
168   {
169   
170   }
171   
172 // copy-constructor
173   PropertyObject(const PropertyObject<std::string>& aOther) :
174     PropertyObjectBase(aOther)
175   {
176   }
177
178 // create form
179   static PropertyObject<std::string> create(const char* aPath, const std::string& aValue)
180   {
181     PropertyObject<std::string> p(aPath);
182     p = aValue;
183     return p;
184   }
185   
186   static PropertyObject<std::string> create(SGPropertyNode* aNode, const std::string& aValue)
187   {
188     PropertyObject<std::string> p(aNode);
189     p = aValue;
190     return p;
191   }
192
193   static PropertyObject<std::string> create(SGPropertyNode* aNode, const char* aChild, const std::string& aValue)
194   {
195     PropertyObject<std::string> p(aNode, aChild);
196     p = aValue;
197     return p;
198   }
199   
200   
201   operator std::string () const
202   {
203     return getOrThrow()->getStringValue();
204   }
205   
206   const char* operator=(const char* aValue)
207   {
208     SGPropertyNode* n = PropertyObjectBase::node(true);
209     if (!n) {
210       return aValue;
211     }
212     
213     n->setStringValue(aValue);
214     return aValue;
215   }
216   
217   std::string operator=(const std::string& aValue)
218   {
219     SGPropertyNode* n = PropertyObjectBase::node(true);
220     if (!n) {
221       return aValue;
222     }
223     
224     n->setStringValue(aValue);
225     return aValue;
226   }
227   
228   bool operator==(const char* value) const
229   {
230     std::string s(*this);
231     return (s == value);    
232   }
233
234   bool operator==(const std::string& value) const
235   {
236     std::string s(*this);
237     return (s == value);    
238   }
239
240   SGPropertyNode* node() const
241   {
242     return PropertyObjectBase::node(false);
243   }
244 private:
245 };
246
247 } // of namespace simgear
248
249 typedef simgear::PropertyObject<double> SGPropObjDouble;
250 typedef simgear::PropertyObject<bool> SGPropObjBool;
251 typedef simgear::PropertyObject<std::string> SGPropObjString;
252 typedef simgear::PropertyObject<long> SGPropObjInt;
253
254 #endif