31#ifndef FGPROPERTYMANAGER_H
32#define FGPROPERTYMANAGER_H
40#if defined( HAVE_CONFIG_H )
50# include "simgear/math/SGMath.hxx"
59template <
class C,
class T>
63 typedef T(C::* getter_t)()
const;
64 typedef void (C::* setter_t)(T);
66 getter_t getter =
nullptr, setter_t setter =
nullptr)
67 : _obj(obj), _getter(getter), _setter(setter) {}
69 if (_getter) {
return static_cast<int>((_obj.*_getter)()); }
73 if (_setter) { (_obj.*_setter)(
static_cast<T
>(value));
return true; }
76 SGRaw* clone()
const override {
85template <
class C,
class T,
class U>
89 typedef T(C::* getter_t)(U)
const;
90 typedef void (C::* setter_t)(U, T);
92 getter_t getter =
nullptr, setter_t setter =
nullptr)
93 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
95 if (_getter) {
return (_obj.*_getter)(_index); }
99 if (_setter) { (_obj.*_setter)(_index, value);
return true; }
102 SGRaw* clone()
const override {
114JSBSIM_API std::string GetPrintableName(
const SGPropertyNode* node);
115JSBSIM_API std::string GetFullyQualifiedName(
const SGPropertyNode* node);
116JSBSIM_API std::string GetRelativeName(
const SGPropertyNode* node,
const std::string &path);
130class JSBSIM_API FGPropertyManager
137 explicit FGPropertyManager(
SGPropertyNode* _root) : root(_root) {};
140 virtual ~FGPropertyManager(
void) { Unbind(); }
143 SGPropertyNode* GetNode(
const std::string &path,
bool create =
false)
144 {
return root->
getNode(path, create); }
145 SGPropertyNode* GetNode(
const std::string &relpath,
int index,
bool create =
false)
146 {
return root->
getNode(relpath, index, create); }
147 bool HasNode(
const std::string& path)
const
149 std::string newPath = path;
150 if (newPath[0] ==
'-') newPath.erase(0,1);
152 return prop !=
nullptr;
162 std::string mkPropertyName(std::string name,
bool lowercase);
177 void Untie (
const std::string &name);
199 void Unbind(
const void* instance);
209 template <
typename T>
void Unbind(
const std::shared_ptr<T>& instance) {
210 Unbind(instance.get());
222 template <
typename T>
void
223 Tie (
const std::string &name, T *pointer)
227 std::cerr <<
"Could not get or create property " << name << std::endl;
232 std::cerr <<
"Failed to tie property " << name <<
" to a pointer" << std::endl;
234 tied_properties.push_back(PropertyState(property,
nullptr));
235 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
255 template <
class T,
class V>
256 typename std::enable_if_t<std::is_enum_v<V>,
void>
257 Tie (
const std::string &name, T * obj, V (T::*getter)() const,
258 void (T::*setter)(V) = nullptr)
262 std::cerr <<
"Could not get or create property " << name << std::endl;
267 std::cerr <<
"Failed to tie property " << name <<
" to object methods"
270 tied_properties.push_back(PropertyState(property, obj));
271 if (!setter)
property->
setAttribute(SGPropertyNode::WRITE,
false);
272 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
273 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
277 template <
class T,
class V>
278 typename std::enable_if_t<!std::is_enum_v<V>,
void>
279 Tie (
const std::string &name, T * obj, V (T::*getter)() const,
280 void (T::*setter)(V) = nullptr)
284 std::cerr <<
"Could not get or create property " << name << std::endl;
289 std::cerr <<
"Failed to tie property " << name <<
" to object methods"
292 tied_properties.push_back(PropertyState(property, obj));
293 if (!setter)
property->
setAttribute(SGPropertyNode::WRITE,
false);
294 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
295 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
315 template <
class T,
class V>
void
316 Tie (
const std::string &name, T * obj,
int index, V (T::*getter)(int) const,
317 void (T::*setter)(int, V) = nullptr)
321 std::cerr <<
"Could not get or create property " << name << std::endl;
327 std::cerr <<
"Failed to tie property " << name
328 <<
" to indexed object methods" << std::endl;
330 tied_properties.push_back(PropertyState(property, obj));
331 if (!setter)
property->
setAttribute(SGPropertyNode::WRITE,
false);
332 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
333 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
353 template <
class T,
class V,
class U>
354 typename std::enable_if_t<std::is_enum_v<U>,
void>
355 Tie(
const std::string& name, T* obj, U index, V(T::* getter)(U) const,
356 void (T::* setter)(U, V) = nullptr)
360 std::cerr <<
"Could not get or create property " << name << std::endl;
365 std::cerr <<
"Failed to tie property " << name
366 <<
" to indexed object methods" << std::endl;
368 tied_properties.push_back(PropertyState(property, obj));
369 if (!setter)
property->
setAttribute(SGPropertyNode::WRITE,
false);
370 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
371 if (FGJSBBase::debug_lvl & 0x20) std::cout << name << std::endl;
376 struct PropertyState {
377 SGPropertyNode_ptr node;
378 const void* BindingInstance =
nullptr;
379 bool WriteAttribute =
true;
380 bool ReadAttribute =
true;
382 : node(property), BindingInstance(instance) {
383 WriteAttribute = node->getAttribute(SGPropertyNode::WRITE);
384 ReadAttribute = node->getAttribute(SGPropertyNode::READ);
387 node->setAttribute(SGPropertyNode::WRITE, WriteAttribute);
388 node->setAttribute(SGPropertyNode::READ, ReadAttribute);
392 std::list<PropertyState> tied_properties;
393 SGPropertyNode_ptr root;
A node in a property tree.
void setAttribute(Attribute attr, bool state)
Set a single mode attribute for the property node.
SGPropertyNode * getNode(const char *relative_path, bool create=false)
Get a pointer to another node by relative path.
bool setValue(int value) override
Assign a new underlying value.
int getValue() const override
Return the underlying value.
bool setValue(T value) override
Assign a new underlying value.
T getValue() const override
Return the underlying value.
An indexed value managed through an object and access methods.
A value managed through an object and access methods.
A raw value bound to a pointer.
Abstract base class for a raw value.
static T DefaultValue()
The default underlying value for this type.
Base class for SGRawValue classes that holds no type information.
Interface definition for a property list.