add properties groups
This commit is contained in:
@@ -2,11 +2,16 @@
|
||||
#define U_CORE_PROPERTY_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <typeinfo>
|
||||
#include <typeindex> // Added
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <vector>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/serialization/serialization.hpp>
|
||||
#include "Core/Archives.h"
|
||||
#include "Core/Signal.h"
|
||||
#include "Core/Object.h"
|
||||
@@ -29,6 +34,12 @@ public:
|
||||
static std::vector<std::string> empty;
|
||||
return empty;
|
||||
}
|
||||
virtual const std::string& GetGroup() const = 0;
|
||||
virtual void SetGroup(const std::string& group) = 0;
|
||||
std::string GetQualifiedName() const {
|
||||
if (GetGroup().empty()) return GetName();
|
||||
return GetGroup() + "." + GetName();
|
||||
}
|
||||
|
||||
// Signal support
|
||||
signals:
|
||||
@@ -51,16 +62,16 @@ template <typename T>
|
||||
class Property : public PropertyBase {
|
||||
public:
|
||||
// PROXY: Use an existing variable as back-end storage
|
||||
Property(Object* owner, const std::string& name, T* valuePtr, const std::string& units = "")
|
||||
: m_owner(owner), m_name(name), m_units(units), m_value(valuePtr), m_own(false) {
|
||||
Property(Object* owner, const std::string& name, T* valuePtr, const std::string& units = "", const std::string& group = "")
|
||||
: m_owner(owner), m_name(name), m_units(units), m_group(group), m_value(valuePtr), m_own(false) {
|
||||
if (m_owner) {
|
||||
m_owner->RegisterProperty(this);
|
||||
}
|
||||
}
|
||||
|
||||
// MANAGED: Create and own internal storage
|
||||
Property(Object* owner, const std::string& name, const T& defaultValue = T(), const std::string& units = "")
|
||||
: m_owner(owner), m_name(name), m_units(units), m_value(new T(defaultValue)), m_own(true) {
|
||||
Property(Object* owner, const std::string& name, const T& defaultValue = T(), const std::string& units = "", const std::string& group = "")
|
||||
: m_owner(owner), m_name(name), m_units(units), m_group(group), m_value(new T(defaultValue)), m_own(true) {
|
||||
if (m_owner) {
|
||||
m_owner->RegisterProperty(this);
|
||||
}
|
||||
@@ -76,6 +87,8 @@ public:
|
||||
virtual std::type_index GetTypeIndex() const override { return std::type_index(typeid(T)); }
|
||||
virtual const std::string& GetUnits() const override { return m_units; }
|
||||
virtual void SetUnits(const std::string& units) override { m_units = units; }
|
||||
virtual const std::string& GetGroup() const override { return m_group; }
|
||||
virtual void SetGroup(const std::string& group) override { m_group = group; }
|
||||
|
||||
|
||||
std::string GetValueAsString() const override {
|
||||
@@ -127,6 +140,7 @@ public:
|
||||
private:
|
||||
std::string m_name;
|
||||
std::string m_units;
|
||||
std::string m_group;
|
||||
T* m_value;
|
||||
bool m_own;
|
||||
Object* m_owner;
|
||||
@@ -149,8 +163,8 @@ typedef Property<Bool_t> BoolProperty;
|
||||
*/
|
||||
class EnumProperty : public Property<int> {
|
||||
public:
|
||||
EnumProperty(Object* owner, const std::string& name, int* valuePtr, const std::vector<std::string>& labels, const std::string& units = "")
|
||||
: Property<int>(owner, name, valuePtr, units), m_Labels(labels) {}
|
||||
EnumProperty(Object* owner, const std::string& name, int* valuePtr, const std::vector<std::string>& labels, const std::string& units = "", const std::string& group = "")
|
||||
: Property<int>(owner, name, valuePtr, units, group), m_Labels(labels) {}
|
||||
|
||||
const std::vector<std::string>& GetEnumLabels() const override { return m_Labels; }
|
||||
const char* GetTypeName() const override { return "Enum"; }
|
||||
@@ -209,11 +223,20 @@ public:
|
||||
boost::archive::detail::common_oarchive<property_register_archive>(boost::archive::no_header),
|
||||
m_Object(obj) {}
|
||||
|
||||
std::string GetCurrentGroup() const {
|
||||
std::string group;
|
||||
for (const auto& g : m_GroupStack) {
|
||||
if (!group.empty()) group += ".";
|
||||
group += g;
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
// Core logic: encounter HRP -> Create Dynamic Property
|
||||
template<class T>
|
||||
void save_override(const boost::serialization::hrp<T> &t) {
|
||||
if (m_Object) {
|
||||
Property<T>* p = new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp<T>&>(t).value(), t.units() ? t.units() : "");
|
||||
Property<T>* p = new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp<T>&>(t).value(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||
m_Object->RegisterDynamicProperty(p);
|
||||
}
|
||||
}
|
||||
@@ -221,7 +244,7 @@ public:
|
||||
template<class T>
|
||||
void save_override(const boost::serialization::hrp_enum<T> &t) {
|
||||
if (m_Object) {
|
||||
EnumProperty* p = new EnumProperty(m_Object, t.name(), (int*)&const_cast<boost::serialization::hrp_enum<T>&>(t).value(), t.labels(), t.units() ? t.units() : "");
|
||||
EnumProperty* p = new EnumProperty(m_Object, t.name(), (int*)&const_cast<boost::serialization::hrp_enum<T>&>(t).value(), t.labels(), t.units() ? t.units() : "", GetCurrentGroup());
|
||||
m_Object->RegisterDynamicProperty(p);
|
||||
}
|
||||
}
|
||||
@@ -229,11 +252,24 @@ public:
|
||||
// Handle standard NVPs by recursing (important for base classes)
|
||||
template<class T>
|
||||
void save_override(const boost::serialization::nvp<T> &t) {
|
||||
boost::archive::detail::common_oarchive<property_register_archive>::save_override(t.const_value());
|
||||
if (t.name()) m_GroupStack.push_back(t.name());
|
||||
this->save_helper(t.const_value(), typename boost::is_class<T>::type());
|
||||
if (t.name()) m_GroupStack.pop_back();
|
||||
}
|
||||
|
||||
// Ignore everything else
|
||||
template<class T> void save_override(const T &t) {}
|
||||
// Recursion for nested classes, ignore primitives
|
||||
template<class T>
|
||||
void save_override(const T &t) {
|
||||
this->save_helper(t, typename boost::is_class<T>::type());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void save_helper(const T &t, boost::mpl::true_) {
|
||||
boost::serialization::serialize_adl(*this, const_cast<T&>(t), 0);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void save_helper(const T &t, boost::mpl::false_) {}
|
||||
|
||||
// Required attribute overrides for common_oarchive
|
||||
void save_override(const boost::archive::object_id_type & t) {}
|
||||
@@ -244,6 +280,9 @@ public:
|
||||
void save_override(const boost::archive::class_id_reference_type & t) {}
|
||||
void save_override(const boost::archive::class_name_type & t) {}
|
||||
void save_override(const boost::archive::tracking_type & t) {}
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_GroupStack;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user