31#ifndef FGPROPERTYMANAGER_H
32#define FGPROPERTYMANAGER_H
40#if defined( HAVE_CONFIG_H )
50# include "simgear/math/SGMath.hxx"
54#include "input_output/FGLog.h"
60template <
class C,
class T>
64 typedef T(C::* getter_t)()
const;
65 typedef void (C::* setter_t)(T);
67 getter_t getter =
nullptr, setter_t setter =
nullptr)
68 : _obj(obj), _getter(getter), _setter(setter) {}
70 if (_getter) {
return static_cast<int>((_obj.*_getter)()); }
74 if (_setter) { (_obj.*_setter)(
static_cast<T
>(value));
return true; }
77 SGRaw* clone()
const override {
86template <
class C,
class T,
class U>
90 typedef T(C::* getter_t)(U)
const;
91 typedef void (C::* setter_t)(U, T);
93 getter_t getter =
nullptr, setter_t setter =
nullptr)
94 : _obj(obj), _index(index), _getter(getter), _setter(setter) {}
96 if (_getter) {
return (_obj.*_getter)(_index); }
100 if (_setter) { (_obj.*_setter)(_index, value);
return true; }
103 SGRaw* clone()
const override {
115JSBSIM_API std::string GetPrintableName(
const SGPropertyNode* node);
116JSBSIM_API std::string GetFullyQualifiedName(
const SGPropertyNode* node);
117JSBSIM_API std::string GetRelativeName(
const SGPropertyNode* node,
const std::string &path);
131class JSBSIM_API FGPropertyManager
138 explicit FGPropertyManager(
SGPropertyNode* _root) : root(_root) {};
141 virtual ~FGPropertyManager(
void) { Unbind(); }
144 SGPropertyNode* GetNode(
const std::string &path,
bool create =
false)
145 {
return root->
getNode(path, create); }
146 SGPropertyNode* GetNode(
const std::string &relpath,
int index,
bool create =
false)
147 {
return root->
getNode(relpath, index, create); }
148 bool HasNode(
const std::string& path)
const
150 std::string newPath = path;
151 if (newPath[0] ==
'-') newPath.erase(0,1);
153 return prop !=
nullptr;
163 std::string mkPropertyName(std::string name,
bool lowercase);
178 void Untie (
const std::string &name);
200 void Unbind(
const void* instance);
210 template <
typename T>
void Unbind(
const std::shared_ptr<T>& instance) {
211 Unbind(instance.get());
223 template <
typename T>
void
224 Tie (
const std::string &name, T *pointer)
228 FGLogging log(LogLevel::ERROR);
229 log <<
"Could not get or create property " << name <<
"\n";
234 FGLogging log(LogLevel::ERROR);
235 log <<
"Failed to tie property " << name <<
" to a pointer\n";
238 tied_properties.push_back(PropertyState(property,
nullptr));
239 if (FGJSBBase::debug_lvl & 0x20) {
240 FGLogging log(LogLevel::DEBUG);
262 template <
class T,
class V>
263 typename std::enable_if_t<std::is_enum_v<V>,
void>
264 Tie (
const std::string &name, T * obj, V (T::*getter)() const,
265 void (T::*setter)(V) = nullptr)
269 FGLogging log(LogLevel::ERROR);
270 log <<
"Could not get or create property " << name <<
"\n";
275 FGLogging log(LogLevel::ERROR);
276 log <<
"Failed to tie property " << name <<
" to object methods\n";
279 tied_properties.push_back(PropertyState(property, obj));
280 if (!setter)
property->setAttribute(SGPropertyNode::WRITE,
false);
281 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
282 if (FGJSBBase::debug_lvl & 0x20) {
283 FGLogging log(LogLevel::DEBUG);
289 template <
class T,
class V>
290 typename std::enable_if_t<!std::is_enum_v<V>,
void>
291 Tie (
const std::string &name, T * obj, V (T::*getter)() const,
292 void (T::*setter)(V) = nullptr)
296 FGLogging log(LogLevel::ERROR);
297 log <<
"Could not get or create property " << name <<
"\n";
302 FGLogging log(LogLevel::ERROR);
303 log <<
"Failed to tie property " << name <<
" to object methods\n";
306 tied_properties.push_back(PropertyState(property, obj));
307 if (!setter)
property->setAttribute(SGPropertyNode::WRITE,
false);
308 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
309 if (FGJSBBase::debug_lvl & 0x20) {
310 FGLogging log(LogLevel::DEBUG);
332 template <
class T,
class V>
void
333 Tie (
const std::string &name, T * obj,
int index, V (T::*getter)(int) const,
334 void (T::*setter)(int, V) = nullptr)
338 FGLogging log(LogLevel::ERROR);
339 log <<
"Could not get or create property " << name <<
"\n";
345 FGLogging log(LogLevel::ERROR);
346 log <<
"Failed to tie property " << name
347 <<
" to indexed object methods\n";
350 tied_properties.push_back(PropertyState(property, obj));
351 if (!setter)
property->setAttribute(SGPropertyNode::WRITE,
false);
352 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
353 if (FGJSBBase::debug_lvl & 0x20) {
354 FGLogging log(LogLevel::DEBUG);
376 template <
class T,
class V,
class U>
377 typename std::enable_if_t<std::is_enum_v<U>,
void>
378 Tie(
const std::string& name, T* obj, U index, V(T::* getter)(U) const,
379 void (T::* setter)(U, V) = nullptr)
383 FGLogging log(LogLevel::ERROR);
384 log <<
"Could not get or create property " << name <<
"\n";
389 FGLogging log(LogLevel::ERROR);
390 log <<
"Failed to tie property " << name <<
" to indexed object methods\n";
393 tied_properties.push_back(PropertyState(property, obj));
394 if (!setter)
property->setAttribute(SGPropertyNode::WRITE,
false);
395 if (!getter)
property->setAttribute(SGPropertyNode::READ,
false);
396 if (FGJSBBase::debug_lvl & 0x20) {
397 FGLogging log(LogLevel::DEBUG);
404 struct PropertyState {
405 SGPropertyNode_ptr node;
406 const void* BindingInstance =
nullptr;
407 bool WriteAttribute =
true;
408 bool ReadAttribute =
true;
410 : node(property), BindingInstance(instance) {
411 WriteAttribute = node->getAttribute(SGPropertyNode::WRITE);
412 ReadAttribute = node->getAttribute(SGPropertyNode::READ);
415 node->setAttribute(SGPropertyNode::WRITE, WriteAttribute);
416 node->setAttribute(SGPropertyNode::READ, ReadAttribute);
420 std::list<PropertyState> tied_properties;
421 SGPropertyNode_ptr root;
A node in a property tree.
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.
Main namespace for the JSBSim Flight Dynamics Model.
Interface definition for a property list.