refactor: improve Object property management with duplicate prevention, memory cleanup, and updated VTK interface tests
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -24,3 +24,5 @@ int main() {
|
||||
std::cout << "Tests passed (compilation and manual instantiation)!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user