]> git.mxchange.org Git - simgear.git/blob - simgear/props/propertyObject.hxx
Melchior FRANZ: fix SGPropertyNode::LAST_USED_ATTRIBUTE
[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(const PropertyObjectBase& aOther);
32     
33   PropertyObjectBase(const char* aChild);
34   
35   PropertyObjectBase(SGPropertyNode* aNode, const char* aChild = NULL);
36   
37   SGPropertyNode* node(bool aCreate) const;
38
39   /**
40    * Resolve the property node, or throw an exception if it could not
41    * be resolved.
42    */
43   SGPropertyNode* getOrThrow() const;
44 protected:
45   mutable const char* _path;
46
47   /**
48    * Important - if _path is NULL, this is the actual prop.
49    * If path is non-NULL, this is the parent which path should be resolved
50    * against (or NULL, if _path is absolute). Use node() instead of accessing
51    * this directly, and the above is handled automatically. 
52    */
53   mutable SGPropertyNode* _prop;
54 };
55
56 template <typename T>
57 class PropertyObject : PropertyObjectBase
58 {
59 public:
60   /**
61    * Create from path relative to the default root, and option default value
62    */
63   PropertyObject(const char* aChild) :
64     PropertyObjectBase(aChild)
65   { }
66   
67   /**
68    * Create from a node, with optional relative path
69    */
70   PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
71     PropertyObjectBase(aNode, aChild)
72   {
73   
74   }
75   
76 // copy-constructor
77   PropertyObject(const PropertyObject<T>& aOther) :
78     PropertyObjectBase(aOther)
79   {
80   }
81
82 // create() form creates the property immediately
83   static PropertyObject<T> create(const char* aPath, T aValue)
84   {
85     PropertyObject<T> p(aPath);
86     p = aValue;
87     return p;
88   }
89   
90   static PropertyObject<T> create(SGPropertyNode* aNode, T aValue)
91   {
92     PropertyObject<T> p(aNode);
93     p = aValue;
94     return p;
95   }
96
97   static PropertyObject<T> create(SGPropertyNode* aNode, const char* aChild, T aValue)
98   {
99     PropertyObject<T> p(aNode, aChild);
100     p = aValue;
101     return p;
102   }
103   
104 // conversion operators
105   operator T () const
106   {
107     return getOrThrow()->getValue<T>();
108   }
109
110   T operator=(const T& aValue)
111   {
112     SGPropertyNode* n = PropertyObjectBase::node(true);
113     if (!n) {
114       return aValue;
115     }
116     
117     n->setValue<T>(aValue);
118     return aValue;
119   }
120
121   SGPropertyNode* node() const
122   {
123     return PropertyObjectBase::node(false);
124   }
125 }; // of template PropertyObject
126
127
128 // specialization for const char* / std::string
129
130 template <>
131 class PropertyObject<std::string> : PropertyObjectBase
132 {
133 public:
134   PropertyObject(const char* aChild) :
135     PropertyObjectBase(aChild)
136   { }
137   
138
139   
140   PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
141     PropertyObjectBase(aNode, aChild)
142   {
143   
144   }
145   
146 // copy-constructor
147   PropertyObject(const PropertyObject<std::string>& aOther) :
148     PropertyObjectBase(aOther)
149   {
150   }
151
152 // create form
153   static PropertyObject<std::string> create(const char* aPath, const std::string& aValue)
154   {
155     PropertyObject<std::string> p(aPath);
156     p = aValue;
157     return p;
158   }
159   
160   static PropertyObject<std::string> create(SGPropertyNode* aNode, const std::string& aValue)
161   {
162     PropertyObject<std::string> p(aNode);
163     p = aValue;
164     return p;
165   }
166
167   static PropertyObject<std::string> create(SGPropertyNode* aNode, const char* aChild, const std::string& aValue)
168   {
169     PropertyObject<std::string> p(aNode, aChild);
170     p = aValue;
171     return p;
172   }
173   
174   
175   operator std::string () const
176   {
177     return getOrThrow()->getStringValue();
178   }
179   
180   const char* operator=(const char* aValue)
181   {
182     SGPropertyNode* n = PropertyObjectBase::node(true);
183     if (!n) {
184       return aValue;
185     }
186     
187     n->setStringValue(aValue);
188     return aValue;
189   }
190   
191   std::string operator=(const std::string& aValue)
192   {
193     SGPropertyNode* n = PropertyObjectBase::node(true);
194     if (!n) {
195       return aValue;
196     }
197     
198     n->setStringValue(aValue);
199     return aValue;
200   }
201   
202   bool operator==(const char* value) const
203   {
204     std::string s(*this);
205     return (s == value);    
206   }
207
208   bool operator==(const std::string& value) const
209   {
210     std::string s(*this);
211     return (s == value);    
212   }
213
214   SGPropertyNode* node() const
215   {
216     return PropertyObjectBase::node(false);
217   }
218 private:
219 };
220
221 } // of namespace simgear
222
223 /*
224 typedef simgear::PropertyObject<double> SGPropObjDouble;
225 typedef simgear::PropertyObject<bool> SGPropObjBool;
226 typedef simgear::PropertyObject<std::string> SGPropObjString;
227 typedef simgear::PropertyObject<long> SGPropObjInt;
228 */
229
230 #endif