]> git.mxchange.org Git - simgear.git/blob - simgear/props/propertyObject.hxx
Overload Rect::contains and add compound assignment operators to PropertyObject
[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    * Create from path relative to the default root, and option default value
66    */
67   PropertyObject(const char* aChild) :
68     PropertyObjectBase(aChild)
69   { }
70   
71   /**
72    * Create from a node, with optional relative path
73    */
74   PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
75     PropertyObjectBase(aNode, aChild)
76   {
77   
78   }
79   
80 // copy-constructor
81   PropertyObject(const PropertyObject<T>& aOther) :
82     PropertyObjectBase(aOther)
83   {
84   }
85
86 // create() form creates the property immediately
87   static PropertyObject<T> create(const char* aPath, T aValue)
88   {
89     PropertyObject<T> p(aPath);
90     p = aValue;
91     return p;
92   }
93   
94   static PropertyObject<T> create(SGPropertyNode* aNode, T aValue)
95   {
96     PropertyObject<T> p(aNode);
97     p = aValue;
98     return p;
99   }
100
101   static PropertyObject<T> create(SGPropertyNode* aNode, const char* aChild, T aValue)
102   {
103     PropertyObject<T> p(aNode, aChild);
104     p = aValue;
105     return p;
106   }
107   
108 // conversion operators
109   operator T () const
110   {
111     return getOrThrow()->template getValue<T>();
112   }
113
114   T operator=(const T& aValue)
115   {
116     SGPropertyNode* n = PropertyObjectBase::node(true);
117     if (!n) {
118       return aValue;
119     }
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     n->setValue<T>(n->getValue<T>() op rhs);\
130     return *this;\
131   }
132
133   SG_DEF_ASSIGN_OP(+)
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
144 #undef SG_DEF_ASSIGN_OP
145
146   SGPropertyNode* node() const
147   {
148     return PropertyObjectBase::node(false);
149   }
150 }; // of template PropertyObject
151
152
153 // specialization for const char* / std::string
154
155 template <>
156 class PropertyObject<std::string> : PropertyObjectBase
157 {
158 public:
159   PropertyObject(const char* aChild) :
160     PropertyObjectBase(aChild)
161   { }
162   
163
164   
165   PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
166     PropertyObjectBase(aNode, aChild)
167   {
168   
169   }
170   
171 // copy-constructor
172   PropertyObject(const PropertyObject<std::string>& aOther) :
173     PropertyObjectBase(aOther)
174   {
175   }
176
177 // create form
178   static PropertyObject<std::string> create(const char* aPath, const std::string& aValue)
179   {
180     PropertyObject<std::string> p(aPath);
181     p = aValue;
182     return p;
183   }
184   
185   static PropertyObject<std::string> create(SGPropertyNode* aNode, const std::string& aValue)
186   {
187     PropertyObject<std::string> p(aNode);
188     p = aValue;
189     return p;
190   }
191
192   static PropertyObject<std::string> create(SGPropertyNode* aNode, const char* aChild, const std::string& aValue)
193   {
194     PropertyObject<std::string> p(aNode, aChild);
195     p = aValue;
196     return p;
197   }
198   
199   
200   operator std::string () const
201   {
202     return getOrThrow()->getStringValue();
203   }
204   
205   const char* operator=(const char* aValue)
206   {
207     SGPropertyNode* n = PropertyObjectBase::node(true);
208     if (!n) {
209       return aValue;
210     }
211     
212     n->setStringValue(aValue);
213     return aValue;
214   }
215   
216   std::string operator=(const std::string& aValue)
217   {
218     SGPropertyNode* n = PropertyObjectBase::node(true);
219     if (!n) {
220       return aValue;
221     }
222     
223     n->setStringValue(aValue);
224     return aValue;
225   }
226   
227   bool operator==(const char* value) const
228   {
229     std::string s(*this);
230     return (s == value);    
231   }
232
233   bool operator==(const std::string& value) const
234   {
235     std::string s(*this);
236     return (s == value);    
237   }
238
239   SGPropertyNode* node() const
240   {
241     return PropertyObjectBase::node(false);
242   }
243 private:
244 };
245
246 } // of namespace simgear
247
248 typedef simgear::PropertyObject<double> SGPropObjDouble;
249 typedef simgear::PropertyObject<bool> SGPropObjBool;
250 typedef simgear::PropertyObject<std::string> SGPropObjString;
251 typedef simgear::PropertyObject<long> SGPropObjInt;
252
253 #endif