fix some on properties and signal connection
This commit is contained in:
@@ -88,6 +88,16 @@ const std::vector<PropertyBase*>& Object::GetProperties() const {
|
||||
return d->m_Properties;
|
||||
}
|
||||
|
||||
PropertyBase* Object::GetProperty(const std::string& name) const {
|
||||
for (auto* p : d->m_Properties) {
|
||||
if (p->GetName() == name) return p;
|
||||
}
|
||||
for (auto* p : d->m_DynamicProperties) {
|
||||
if (p->GetName() == name) return p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// In Object.h, the template serialize needs to be updated to call property serialization.
|
||||
// However, since Object::serialize is a template in the header, we might need a helper here.
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ public:
|
||||
void RegisterProperty(PropertyBase* prop);
|
||||
void RegisterDynamicProperty(PropertyBase* prop);
|
||||
const std::vector<PropertyBase*>& GetProperties() const;
|
||||
PropertyBase* GetProperty(const std::string& name) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// PARAMETERS //
|
||||
|
||||
@@ -23,6 +23,12 @@ public:
|
||||
virtual const char* GetTypeName() const = 0;
|
||||
virtual std::string GetValueAsString() const = 0;
|
||||
virtual std::type_index GetTypeIndex() const = 0; // Added
|
||||
virtual const std::string& GetUnits() const = 0;
|
||||
virtual void SetUnits(const std::string& units) = 0;
|
||||
virtual const std::vector<std::string>& GetEnumLabels() const {
|
||||
static std::vector<std::string> empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
// Signal support
|
||||
signals:
|
||||
@@ -45,16 +51,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)
|
||||
: m_owner(owner), m_name(name), m_value(valuePtr), m_own(false) {
|
||||
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) {
|
||||
if (m_owner) {
|
||||
m_owner->RegisterProperty(this);
|
||||
}
|
||||
}
|
||||
|
||||
// MANAGED: Create and own internal storage
|
||||
Property(Object* owner, const std::string& name, const T& defaultValue = T())
|
||||
: m_owner(owner), m_name(name), m_value(new T(defaultValue)), m_own(true) {
|
||||
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) {
|
||||
if (m_owner) {
|
||||
m_owner->RegisterProperty(this);
|
||||
}
|
||||
@@ -68,6 +74,8 @@ public:
|
||||
virtual const std::string& GetName() const override { return m_name; }
|
||||
virtual const char* GetTypeName() const override { return typeid(T).name(); }
|
||||
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; }
|
||||
|
||||
|
||||
std::string GetValueAsString() const override {
|
||||
@@ -118,6 +126,7 @@ public:
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::string m_units;
|
||||
T* m_value;
|
||||
bool m_own;
|
||||
Object* m_owner;
|
||||
@@ -135,6 +144,22 @@ typedef Property<float> FloatProperty;
|
||||
typedef Property<double> DoubleProperty;
|
||||
typedef Property<Bool_t> BoolProperty;
|
||||
|
||||
/**
|
||||
* @brief Property specialized for enumerations, providing labels for GUI representations.
|
||||
*/
|
||||
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) {}
|
||||
|
||||
const std::vector<std::string>& GetEnumLabels() const override { return m_Labels; }
|
||||
const char* GetTypeName() const override { return "Enum"; }
|
||||
virtual std::type_index GetTypeIndex() const override { return std::type_index(typeid(EnumProperty)); }
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_Labels;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Macro to simplify property declaration within a class.
|
||||
* Usage: ULIB_PROPERTY(float, Width, 1.0f)
|
||||
@@ -188,10 +213,16 @@ public:
|
||||
template<class T>
|
||||
void save_override(const boost::serialization::hrp<T> &t) {
|
||||
if (m_Object) {
|
||||
// We use const_cast because we are just creating a proxy to the member
|
||||
m_Object->RegisterDynamicProperty(
|
||||
new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp<T>&>(t).value())
|
||||
);
|
||||
Property<T>* p = new Property<T>(m_Object, t.name(), &const_cast<boost::serialization::hrp<T>&>(t).value(), t.units() ? t.units() : "");
|
||||
m_Object->RegisterDynamicProperty(p);
|
||||
}
|
||||
}
|
||||
|
||||
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() : "");
|
||||
m_Object->RegisterDynamicProperty(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,12 +75,14 @@ template <class T> struct access2 {};
|
||||
template <class T>
|
||||
class hrp : public boost::serialization::wrapper_traits<hrp<T>> {
|
||||
const char *m_name;
|
||||
const char *m_units;
|
||||
T &m_value;
|
||||
|
||||
public:
|
||||
explicit hrp(const char *name_, T &t) : m_name(name_), m_value(t) {}
|
||||
explicit hrp(const char *name_, T &t, const char* units_ = nullptr) : m_name(name_), m_units(units_), m_value(t) {}
|
||||
|
||||
const char *name() const { return this->m_name; }
|
||||
const char *units() const { return this->m_units; }
|
||||
T &value() { return this->m_value; }
|
||||
const T &const_value() const { return this->m_value; }
|
||||
|
||||
@@ -98,11 +100,46 @@ public:
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline hrp<T> make_hrp(const char *name, T &t) {
|
||||
return hrp<T>(name, t);
|
||||
inline hrp<T> make_hrp(const char *name, T &t, const char* units = nullptr) {
|
||||
return hrp<T>(name, t, units);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class hrp_enum : public boost::serialization::wrapper_traits<hrp_enum<T>> {
|
||||
const char *m_name;
|
||||
const char *m_units;
|
||||
T &m_value;
|
||||
std::vector<std::string> m_labels;
|
||||
|
||||
public:
|
||||
explicit hrp_enum(const char *name_, T &t, const std::vector<std::string>& labels, const char* units_ = nullptr)
|
||||
: m_name(name_), m_units(units_), m_value(t), m_labels(labels) {}
|
||||
|
||||
const char *name() const { return this->m_name; }
|
||||
const char *units() const { return this->m_units; }
|
||||
T &value() { return this->m_value; }
|
||||
const std::vector<std::string>& labels() const { return m_labels; }
|
||||
|
||||
BOOST_SERIALIZATION_SPLIT_MEMBER()
|
||||
|
||||
template <class Archivex>
|
||||
void save(Archivex &ar, const unsigned int /* version */) const {
|
||||
ar << boost::serialization::make_nvp(m_name, m_value);
|
||||
}
|
||||
|
||||
template <class Archivex>
|
||||
void load(Archivex &ar, const unsigned int /* version */) {
|
||||
ar >> boost::serialization::make_nvp(m_name, m_value);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline hrp_enum<T> make_hrp_enum(const char *name, T &t, const std::vector<std::string>& labels, const char* units = nullptr) {
|
||||
return hrp_enum<T>(name, t, labels, units);
|
||||
}
|
||||
|
||||
#define HRP(name) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name)
|
||||
#define HRPU(name, units) boost::serialization::make_hrp(BOOST_PP_STRINGIZE(name), name, units)
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
Reference in New Issue
Block a user