refactor: improve Object property management with duplicate prevention, memory cleanup, and updated VTK interface tests

This commit is contained in:
AndreaRigoni
2026-04-10 12:18:15 +00:00
parent dfd33e9a9c
commit 22262d3dc6
7 changed files with 41 additions and 20 deletions

View File

@@ -59,6 +59,10 @@ public:
GenericMFPtr sloptr;
std::string slostr;
};
~ObjectPrivate() {
for (auto& s : sigv) delete s.signal;
}
std::string m_InstanceName;
std::vector<Signal> sigv;
@@ -71,7 +75,13 @@ public:
// Implementations of Property methods
void Object::RegisterDisplayProperty(PropertyBase* prop) {
if (prop) d->m_DisplayProperties.push_back(prop);
if (prop) {
for (auto* existing : d->m_DisplayProperties) {
if (existing == prop) return;
if (existing->GetName() == prop->GetName()) return;
}
d->m_DisplayProperties.push_back(prop);
}
}
const std::vector<PropertyBase*>& Object::GetDisplayProperties() const {
@@ -80,6 +90,10 @@ const std::vector<PropertyBase*>& Object::GetDisplayProperties() const {
void Object::RegisterProperty(PropertyBase* prop) {
if (prop) {
for (auto* existing : d->m_Properties) {
if (existing == prop) return;
if (existing->GetName() == prop->GetName()) return;
}
d->m_Properties.push_back(prop);
}
}
@@ -105,13 +119,16 @@ PropertyBase* Object::GetProperty(const std::string& name) const {
for (auto* p : d->m_DynamicProperties) {
if (p->GetName() == name || p->GetQualifiedName() == name) return p;
}
for (auto* p : d->m_DisplayProperties) {
if (p->GetName() == name || p->GetQualifiedName() == name) return p;
}
return nullptr;
}
void Object::NotifyPropertiesUpdated() {
// Only notify properties in the primary list to avoid duplicates,
// as all registered properties should be there.
for (auto* p : d->m_Properties) p->Updated();
for (auto* p : d->m_DynamicProperties) p->Updated();
this->Updated();
}
void Object::Updated() { ULIB_SIGNAL_EMIT(Object::Updated); }
@@ -147,6 +164,9 @@ Object::~Object() {
for (auto* p : d->m_DynamicProperties) {
delete p;
}
for (auto* p : d->m_DisplayProperties) {
delete p;
}
delete d;
}

View File

@@ -103,6 +103,7 @@ public:
// Accessors
const T& Get() const { return *m_value; }
void Set(const T& value) {
if (!m_value) return;
T val = value;
if constexpr (std::is_arithmetic<T>::value) {
if (m_HasRange) { if (val < m_Min) val = m_Min; if (val > m_Max) val = m_Max; }

View File

@@ -24,3 +24,5 @@ int main() {
std::cout << "Tests passed (compilation and manual instantiation)!" << std::endl;
return 0;
}

View File

@@ -36,11 +36,11 @@ int main() {
BEGIN_TESTING(vtk ContainerBox Test);
{
ContainerBox box;
box.Scale(Vector3f(1_m, 2_m, 1_m));
box.SetPosition(Vector3f(0, 0, 0));
ContainerBox* box = new ContainerBox();
box->Scale(Vector3f(1_m, 2_m, 1_m));
box->SetPosition(Vector3f(0, 0, 0));
Vtk::ContainerBox v_box(&box);
Vtk::ContainerBox v_box(box);
v_box.Update();
v_box.SetRepresentation(Vtk::Prop3D::Surface);

View File

@@ -15,11 +15,11 @@ using namespace uLib;
int main() {
std::cout << "Creating ContainerBox..." << std::endl;
ContainerBox box(Vector3f(1.0, 1.0, 1.0)); // 1x1x1 unit box
box.SetInstanceName("MyTestBox");
ContainerBox* box = new ContainerBox(Vector3f(1.0, 1.0, 1.0)); // 1x1x1 unit box
box->SetInstanceName("MyTestBox");
std::cout << "Creating VTK representation..." << std::endl;
Vtk::ContainerBox v_box(&box);
Vtk::ContainerBox v_box(box);
v_box.SetRepresentation(Vtk::Prop3D::Wireframe);
v_box.SetColor(1.0, 0.0, 0.0); // Red

View File

@@ -11,6 +11,7 @@
#include "Vtk/uLibVtkInterface.h"
#include "Core/Property.h"
#include "Math/Dense.h"
#include <iostream>
#include <cassert>
#include "testing-prototype.h"
@@ -33,7 +34,7 @@ int main() {
// Verify specific properties exist
Property<double>* opacityProp = nullptr;
Property<double>* colorRProp = nullptr;
Property<Vector3d>* colorProp = nullptr;
for (auto* prop : props) {
std::cout << " - [" << prop->GetTypeName() << "] " << prop->GetName()
@@ -42,13 +43,13 @@ int main() {
if (prop->GetName() == "Opacity") {
opacityProp = dynamic_cast<Property<double>*>(prop);
}
if (prop->GetName() == "ColorR") {
colorRProp = dynamic_cast<Property<double>*>(prop);
if (prop->GetName() == "Color") {
colorProp = dynamic_cast<Property<Vector3d>*>(prop);
}
}
assert(opacityProp != nullptr && "Opacity property not registered!");
assert(colorRProp != nullptr && "ColorR property not registered!");
assert(colorProp != nullptr && "Color property not registered!");
// Test modification via uLib Property interface
std::cout << "Modifying Opacity via property proxy (0.25)..." << std::endl;
@@ -58,9 +59,9 @@ int main() {
assert(opacityProp->Get() == 0.25);
assert(opacityProp->GetValueAsString().find("0.25") != std::string::npos);
std::cout << "Modifying ColorR via property proxy (0.9)..." << std::endl;
*colorRProp = 0.9;
assert(colorRProp->Get() == 0.9);
std::cout << "Modifying Color via property proxy (0.9, 0.1, 0.1)..." << std::endl;
*colorProp = Vector3d(0.9, 0.1, 0.1);
assert(colorProp->Get().x() == 0.9);
std::cout << "All Prop3D Property Registration Tests PASSED!" << std::endl;

View File

@@ -290,9 +290,6 @@ public:
Prop3D::Prop3D() : Object(), pd(new Prop3DData(this)) {
ULIB_ACTIVATE_DISPLAY_PROPERTIES;
for (auto* p : this->GetDisplayProperties()) {
uLib::Object::connect(p, &uLib::Object::Updated, this, &Prop3D::Update);
}
}
Prop3D::~Prop3D()