property - first attempt

This commit is contained in:
AndreaRigoni
2026-03-23 12:55:09 +00:00
parent b52ae808b8
commit 94843de711
16 changed files with 482 additions and 63 deletions

128
src/Core/Property.h Normal file
View File

@@ -0,0 +1,128 @@
#ifndef U_CORE_PROPERTY_H
#define U_CORE_PROPERTY_H
#include <string>
#include <sstream>
#include <typeinfo>
#include <boost/serialization/nvp.hpp>
#include <boost/lexical_cast.hpp>
#include "Core/Archives.h"
#include "Core/Signal.h"
#include "Core/Object.h"
namespace uLib {
/**
* @brief Base class for properties to allow runtime listing and identification.
*/
class PropertyBase : public Object {
public:
virtual ~PropertyBase() {}
virtual const std::string& GetName() const = 0;
virtual const char* GetTypeName() const = 0;
virtual std::string GetValueAsString() const = 0;
// Signal support
signals:
virtual void Updated() override { ULIB_SIGNAL_EMIT(PropertyBase::Updated); }
// Serialization support for different uLib archives
virtual void serialize(Archive::xml_oarchive & ar, const unsigned int version) = 0;
virtual void serialize(Archive::xml_iarchive & ar, const unsigned int version) = 0;
virtual void serialize(Archive::text_oarchive & ar, const unsigned int version) = 0;
virtual void serialize(Archive::text_iarchive & ar, const unsigned int version) = 0;
virtual void serialize(Archive::hrt_oarchive & ar, const unsigned int version) = 0;
virtual void serialize(Archive::hrt_iarchive & ar, const unsigned int version) = 0;
virtual void serialize(Archive::log_archive & ar, const unsigned int version) = 0;
};
/**
* @brief Template class for typed properties.
*/
template <typename T>
class Property : public PropertyBase {
public:
Property(Object* owner, const std::string& name, const T& defaultValue = T())
: m_owner(owner), m_name(name), m_value(defaultValue) {
if (m_owner) {
m_owner->RegisterProperty(this);
}
}
virtual ~Property() {}
const std::string& GetName() const override { return m_name; }
const char* GetTypeName() const override { return typeid(T).name(); }
std::string GetValueAsString() const override {
try {
return boost::lexical_cast<std::string>(m_value);
} catch (const boost::bad_lexical_cast&) {
std::stringstream ss;
ss << m_value;
return ss.str();
}
}
// Accessors
const T& Get() const { return m_value; }
void Set(const T& value) {
if (m_value != value) {
m_value = value;
ULIB_SIGNAL_EMIT(Property<T>::PropertyChanged);
}
}
// Operators for seamless usage
operator const T&() const { return m_value; }
Property& operator=(const T& value) {
Set(value);
return *this;
}
// Signals
signals:
virtual void PropertyChanged() { ULIB_SIGNAL_EMIT(Property<T>::PropertyChanged); }
// Serialization
template <class ArchiveT>
void serialize_impl(ArchiveT & ar, const unsigned int version) {
ar & boost::serialization::make_nvp(m_name.c_str(), m_value);
}
void serialize(Archive::xml_oarchive & ar, const unsigned int v) override { serialize_impl(ar, v); }
void serialize(Archive::xml_iarchive & ar, const unsigned int v) override { serialize_impl(ar, v); }
void serialize(Archive::text_oarchive & ar, const unsigned int v) override { serialize_impl(ar, v); }
void serialize(Archive::text_iarchive & ar, const unsigned int v) override { serialize_impl(ar, v); }
void serialize(Archive::hrt_oarchive & ar, const unsigned int v) override { serialize_impl(ar, v); }
void serialize(Archive::hrt_iarchive & ar, const unsigned int v) override { serialize_impl(ar, v); }
void serialize(Archive::log_archive & ar, const unsigned int v) override { serialize_impl(ar, v); }
private:
std::string m_name;
T m_value;
Object* m_owner;
};
/**
* @brief Conveninent typedefs for common property types.
*/
typedef Property<std::string> StringProperty;
typedef Property<int> IntProperty;
typedef Property<unsigned int> UIntProperty;
typedef Property<long> LongProperty;
typedef Property<unsigned long> ULongProperty;
typedef Property<float> FloatProperty;
typedef Property<double> DoubleProperty;
typedef Property<Bool_t> BoolProperty;
/**
* @brief Macro to simplify property declaration within a class.
* Usage: ULIB_PROPERTY(float, Width, 1.0f)
*/
#define ULIB_PROPERTY(type, name, defaultValue) \
Property<type> name = Property<type>(this, #name, defaultValue);
} // namespace uLib
#endif // U_CORE_PROPERTY_H