]> git.mxchange.org Git - simgear.git/blob - simgear/props/propertyObject.hxx
PropertyObject enhancements, unit-test for make check
[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 #include <simgear/structure/exception.hxx>
23
24 namespace simgear
25 {
26
27 class PropertyObjectBase
28 {
29 public:
30   static void setDefaultRoot(SGPropertyNode* aRoot);
31   
32   PropertyObjectBase(const PropertyObjectBase& aOther);
33     
34   PropertyObjectBase(const char* aChild);
35   
36   PropertyObjectBase(SGPropertyNode* aNode, const char* aChild = NULL);
37   
38   SGPropertyNode* node(bool aCreate) const;
39
40 protected:
41   SGPropertyNode* _base;
42   const char* _path;
43   mutable SGPropertyNode* _prop;
44 };
45
46 template <typename T>
47 class PropertyObject : PropertyObjectBase
48 {
49 public:
50   /**
51    * Create from path relative to the default root, and option default value
52    */
53   PropertyObject(const char* aChild) :
54     PropertyObjectBase(aChild)
55   { }
56   
57   /**
58    * Create from a node, with optional relative path
59    */
60   PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
61     PropertyObjectBase(aNode, aChild)
62   {
63   
64   }
65   
66 // copy-constructor
67   PropertyObject(const PropertyObject<T>& aOther) :
68     PropertyObjectBase(aOther)
69   {
70   }
71
72 // create() form creates the property immediately
73   static PropertyObject<T> create(const char* aPath, T aValue)
74   {
75     PropertyObject<T> p(aPath);
76     p = aValue;
77     return p;
78   }
79   
80   static PropertyObject<T> create(SGPropertyNode* aNode, T aValue)
81   {
82     PropertyObject<T> p(aNode);
83     p = aValue;
84     return p;
85   }
86
87   static PropertyObject<T> create(SGPropertyNode* aNode, const char* aChild, T aValue)
88   {
89     PropertyObject<T> p(aNode, aChild);
90     p = aValue;
91     return p;
92   }
93   
94 // conversion operators
95   operator T () const
96   {
97     SGPropertyNode* n = node();
98     if (!n) {
99       throw sg_exception("read of undefined property:", _path);
100     }
101     
102     return n->getValue<T>();
103   }
104
105   T operator=(const T& aValue)
106   {
107     SGPropertyNode* n = PropertyObjectBase::node(true);
108     if (!n) {
109       return aValue;
110     }
111     
112     n->setValue<T>(aValue);
113     return aValue;
114   }
115
116   SGPropertyNode* node() const
117   {
118     return PropertyObjectBase::node(false);
119   }
120 }; // of template PropertyObject
121
122
123 // specialization for const char* / std::string
124
125 template <>
126 class PropertyObject<std::string> : PropertyObjectBase
127 {
128 public:
129   PropertyObject(const char* aChild) :
130     PropertyObjectBase(aChild)
131   { }
132   
133
134   
135   PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
136     PropertyObjectBase(aNode, aChild)
137   {
138   
139   }
140   
141
142   
143   operator std::string () const
144   {
145     SGPropertyNode* n = node();
146     if (!n) {
147       throw sg_exception("read of undefined property:", _path);
148     }
149     
150     return n->getStringValue();
151   }
152   
153   const char* operator=(const char* aValue)
154   {
155     SGPropertyNode* n = PropertyObjectBase::node(true);
156     if (!n) {
157       return aValue;
158     }
159     
160     n->setStringValue(aValue);
161     return aValue;
162   }
163   
164   std::string operator=(const std::string& aValue)
165   {
166     SGPropertyNode* n = PropertyObjectBase::node(true);
167     if (!n) {
168       return aValue;
169     }
170     
171     n->setStringValue(aValue);
172     return aValue;
173   }
174   
175   bool operator==(const char* value) const
176   {
177     std::string s(*this);
178     return (s == value);    
179   }
180
181   bool operator==(const std::string& value) const
182   {
183     std::string s(*this);
184     return (s == value);    
185   }
186
187   SGPropertyNode* node() const
188   {
189     return PropertyObjectBase::node(false);
190   }
191 private:
192 };
193
194 } // of namespace simgear
195
196 typedef simgear::PropertyObject<double> SGPropObjDouble;
197 typedef simgear::PropertyObject<bool> SGPropObjBool;
198 typedef simgear::PropertyObject<std::string> SGPropObjString;
199 typedef simgear::PropertyObject<long> SGPropObjInt;
200
201 #endif