JSBSim Flight Dynamics Model 1.2.3 (07 Jun 2025)
An Open Source Flight Dynamics and Control Software Library in C++
Loading...
Searching...
No Matches
FGPropertyManager.h
1/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3 Header: FGPropertyManager.h
4 Author: Tony Peden
5 Based on work originally by David Megginson
6 Date: 2/2002
7
8 ------------- Copyright (C) 2002 -------------
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU Lesser General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
18 details.
19
20 You should have received a copy of the GNU Lesser General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22 Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 Further information about the GNU Lesser General Public License can also be found on
25 the world wide web at http://www.gnu.org.
26
27%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28SENTRY
29%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
30
31#ifndef FGPROPERTYMANAGER_H
32#define FGPROPERTYMANAGER_H
33
34/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35INCLUDES
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37
38// This is needed by MSVC9 when included in FlightGear because of
39// the new Vec4d class in props.hxx
40#if defined( HAVE_CONFIG_H )
41# include <config.h>
42#endif
43
44#include <string>
45#include <list>
46#include <memory>
48#if !PROPS_STANDALONE
49# include "simgear/math/SGMath.hxx"
50#endif
51
52#include "FGJSBBase.h"
53
54/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55FORWARD DECLARATIONS
56%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
57
58namespace JSBSim {
59
60JSBSIM_API std::string GetPrintableName(const SGPropertyNode* node);
61JSBSIM_API std::string GetFullyQualifiedName(const SGPropertyNode* node);
62JSBSIM_API std::string GetRelativeName(const SGPropertyNode* node, const std::string &path);
63
64/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65CLASS DOCUMENTATION
66%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
67
72/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73CLASS DECLARATION
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
75
76class JSBSIM_API FGPropertyManager
77{
78 public:
80 FGPropertyManager(void) { root = new SGPropertyNode; }
81
83 explicit FGPropertyManager(SGPropertyNode* _root) : root(_root) {};
84
86 virtual ~FGPropertyManager(void) { Unbind(); }
87
88 SGPropertyNode* GetNode(void) const { return root; }
89 SGPropertyNode* GetNode(const std::string &path, bool create = false)
90 { return root->getNode(path, create); }
91 SGPropertyNode* GetNode(const std::string &relpath, int index, bool create = false)
92 { return root->getNode(relpath, index, create); }
93 bool HasNode(const std::string& path) const
94 {
95 std::string newPath = path;
96 if (newPath[0] == '-') newPath.erase(0,1);
97 SGPropertyNode* prop = root->getNode(newPath);
98 return prop != nullptr;
99 }
100
108 std::string mkPropertyName(std::string name, bool lowercase);
109
111 // Convenience functions for tying properties, with logging.
113
114
123 void Untie (const std::string &name);
124
133 void Untie (SGPropertyNode* property);
134
136 void Unbind (void);
137
145 void Unbind(const void* instance);
146
155 template <typename T> void Unbind(const std::shared_ptr<T>& instance) {
156 Unbind(instance.get());
157 }
158
168 template <typename T> void
169 Tie (const std::string &name, T *pointer)
170 {
171 SGPropertyNode* property = root->getNode(name.c_str(), true);
172 if (!property) {
173 std::cerr << "Could not get or create property " << name << std::endl;
174 return;
175 }
176
177 if (!property->tie(SGRawValuePointer<T>(pointer), false))
178 std::cerr << "Failed to tie property " << name << " to a pointer" << std::endl;
179 else {
180 tied_properties.push_back(PropertyState(property, nullptr));
181 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
182 }
183 }
184
199 template <typename T> void
200 Tie (const std::string &name, T (*getter)(), void (*setter)(T) = nullptr)
201 {
202 SGPropertyNode* property = root->getNode(name.c_str(), true);
203 if (!property) {
204 std::cerr << "Could not get or create property " << name << std::endl;
205 return;
206 }
207
208 if (!property->tie(SGRawValueFunctions<T>(getter, setter), false))
209 std::cerr << "Failed to tie property " << name << " to functions"
210 << std::endl;
211 else {
212 tied_properties.push_back(PropertyState(property, nullptr));
213 if (!setter) property->setAttribute(SGPropertyNode::WRITE, false);
214 if (!getter) property->setAttribute(SGPropertyNode::READ, false);
215 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
216 }
217 }
218
234 template <typename T> void
235 Tie (const std::string &name, int index, T (*getter)(int),
236 void (*setter)(int, T) = nullptr)
237 {
238 SGPropertyNode* property = root->getNode(name.c_str(), true);
239 if (!property) {
240 std::cerr << "Could not get or create property " << name << std::endl;
241 return;
242 }
243
244 if (!property->tie(SGRawValueFunctionsIndexed<T>(index, getter, setter),
245 false))
246 std::cerr << "Failed to tie property " << name << " to indexed functions"
247 << std::endl;
248 else {
249 tied_properties.push_back(PropertyState(property, nullptr));
250 if (!setter) property->setAttribute(SGPropertyNode::WRITE, false);
251 if (!getter) property->setAttribute(SGPropertyNode::READ, false);
252 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
253 }
254 }
255
272 template <class T, class V> void
273 Tie (const std::string &name, T * obj, V (T::*getter)() const,
274 void (T::*setter)(V) = nullptr)
275 {
276 SGPropertyNode* property = root->getNode(name.c_str(), true);
277 if (!property) {
278 std::cerr << "Could not get or create property " << name << std::endl;
279 return;
280 }
281
282 if (!property->tie(SGRawValueMethods<T,V>(*obj, getter, setter), false))
283 std::cerr << "Failed to tie property " << name << " to object methods"
284 << std::endl;
285 else {
286 tied_properties.push_back(PropertyState(property, obj));
287 if (!setter) property->setAttribute(SGPropertyNode::WRITE, false);
288 if (!getter) property->setAttribute(SGPropertyNode::READ, false);
289 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
290 }
291 }
292
309 template <class T, class V> void
310 Tie (const std::string &name, T * obj, int index, V (T::*getter)(int) const,
311 void (T::*setter)(int, V) = nullptr)
312 {
313 SGPropertyNode* property = root->getNode(name.c_str(), true);
314 if (!property) {
315 std::cerr << "Could not get or create property " << name << std::endl;
316 return;
317 }
318
319 if (!property->tie(SGRawValueMethodsIndexed<T,V>(*obj, index, getter, setter),
320 false))
321 std::cerr << "Failed to tie property " << name
322 << " to indexed object methods" << std::endl;
323 else {
324 tied_properties.push_back(PropertyState(property, obj));
325 if (!setter) property->setAttribute(SGPropertyNode::WRITE, false);
326 if (!getter) property->setAttribute(SGPropertyNode::READ, false);
327 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
328 }
329 }
330
331 private:
332 struct PropertyState {
333 SGPropertyNode_ptr node;
334 const void* BindingInstance = nullptr;
335 bool WriteAttribute = true;
336 bool ReadAttribute = true;
337 PropertyState(SGPropertyNode* property, const void* instance)
338 : node(property), BindingInstance(instance) {
339 WriteAttribute = node->getAttribute(SGPropertyNode::WRITE);
340 ReadAttribute = node->getAttribute(SGPropertyNode::READ);
341 }
342 void untie(void) {
343 node->setAttribute(SGPropertyNode::WRITE, WriteAttribute);
344 node->setAttribute(SGPropertyNode::READ, ReadAttribute);
345 node->untie();
346 }
347 };
348 std::list<PropertyState> tied_properties;
349 SGPropertyNode_ptr root;
350};
351}
352#endif // FGPROPERTYMANAGER_H
Class wrapper for property handling.
void Tie(const std::string &name, int index, T(*getter)(int), void(*setter)(int, T)=nullptr)
Tie a property to a pair of indexed functions.
virtual ~FGPropertyManager(void)
Destructor.
void Tie(const std::string &name, T(*getter)(), void(*setter)(T)=nullptr)
Tie a property to a pair of simple functions.
void Tie(const std::string &name, T *obj, V(T::*getter)() const, void(T::*setter)(V)=nullptr)
Tie a property to a pair of object methods.
void Tie(const std::string &name, T *pointer)
Tie a property to an external variable.
void Unbind(const std::shared_ptr< T > &instance)
Unbind all properties bound by this manager to an instance.
FGPropertyManager(SGPropertyNode *_root)
Constructor.
void Tie(const std::string &name, T *obj, int index, V(T::*getter)(int) const, void(T::*setter)(int, V)=nullptr)
Tie a property to a pair of indexed object methods.
FGPropertyManager(void)
Default constructor.
A node in a property tree.
Definition props.hxx:754
void setAttribute(Attribute attr, bool state)
Set a single mode attribute for the property node.
Definition props.hxx:1138
SGPropertyNode * getNode(const char *relative_path, bool create=false)
Get a pointer to another node by relative path.
An indexed value bound to static functions.
Definition props.hxx:550
A value managed through static functions.
Definition props.hxx:470
An indexed value managed through an object and access methods.
Definition props.hxx:616
A value managed through an object and access methods.
Definition props.hxx:583
A raw value bound to a pointer.
Definition props.hxx:413
Interface definition for a property list.