refactor using pimpl and fix test

This commit is contained in:
AndreaRigoni
2026-03-25 16:18:07 +00:00
parent a467b7385b
commit 7d4acaef6d
17 changed files with 479 additions and 412 deletions

View File

@@ -52,6 +52,7 @@ public:
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
}
std::cout << "DataAllocator Constructor: ptr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
}
DataAllocator(const DataAllocator<T> &other)
@@ -63,7 +64,12 @@ public:
m_RamData = new T[m_Size];
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
std::memcpy(m_RamData, other.m_RamData, m_Size * sizeof(T));
if (m_OwnsObjects) {
std::copy(other.m_RamData, other.m_RamData + m_Size, m_RamData);
} else {
std::memcpy(m_RamData, other.m_RamData, m_Size * sizeof(T));
}
}
#ifdef USE_CUDA
if (other.m_VramData) {
@@ -73,14 +79,17 @@ public:
}
#endif
}
std::cout << "DataAllocator CopyConstructor: from=" << other.m_RamData << " to=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
}
~DataAllocator() {
std::cout << "DataAllocator Destructor: ptr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
if (m_RamData) {
if (m_OwnsObjects)
delete[] m_RamData;
else
::operator delete(m_RamData);
m_RamData = nullptr;
}
#ifdef USE_CUDA
if (m_VramData) {
@@ -91,6 +100,13 @@ public:
DataAllocator &operator=(const DataAllocator &other) {
if (this != &other) {
if (m_Size == other.m_Size && m_OwnsObjects != other.m_OwnsObjects) {
// Ownership changed but size is same: we must force reallocation
// to avoid using the wrong delete operator later.
size_t oldSize = m_Size;
m_Size = 0;
resize(oldSize); // This will free the old buffer with the OLD ownership
}
m_OwnsObjects = other.m_OwnsObjects;
resize(other.m_Size);
m_Device = other.m_Device;
@@ -101,7 +117,11 @@ public:
else
m_RamData = static_cast<T *>(::operator new(m_Size * sizeof(T)));
}
std::memcpy(m_RamData, other.m_RamData, m_Size * sizeof(T));
if (m_OwnsObjects) {
std::copy(other.m_RamData, other.m_RamData + m_Size, m_RamData);
} else {
std::memcpy(m_RamData, other.m_RamData, m_Size * sizeof(T));
}
}
#ifdef USE_CUDA
if (other.m_VramData) {
@@ -112,6 +132,7 @@ public:
}
#endif
}
std::cout << "DataAllocator AssigmentOp: otherPtr=" << other.m_RamData << " thisPtr=" << m_RamData << " size=" << m_Size << " own=" << m_OwnsObjects << std::endl;
return *this;
}
@@ -152,6 +173,8 @@ public:
if (m_Size == size)
return;
std::cout << "DataAllocator Resize: from=" << m_Size << " to=" << size << " ptr=" << m_RamData << " own=" << m_OwnsObjects << std::endl;
T *newRam = nullptr;
T *newVram = nullptr;
@@ -162,7 +185,11 @@ public:
newRam = static_cast<T *>(::operator new(size * sizeof(T)));
if (m_RamData) {
std::memcpy(newRam, m_RamData, std::min(m_Size, size) * sizeof(T));
if (m_OwnsObjects) {
std::copy(m_RamData, m_RamData + std::min(m_Size, size), newRam);
} else {
std::memcpy(newRam, m_RamData, std::min(m_Size, size) * sizeof(T));
}
}
#ifdef USE_CUDA

View File

@@ -61,8 +61,8 @@ public:
};
std::string m_InstanceName;
Vector<Signal> sigv;
Vector<Slot> slov;
std::vector<Signal> sigv;
std::vector<Slot> slov;
std::vector<PropertyBase*> m_Properties;
std::vector<PropertyBase*> m_DynamicProperties;
bool m_SignalsBlocked;
@@ -117,15 +117,30 @@ template void Object::serialize(Archive::log_archive &, const unsigned int);
Object::Object() : d(new ObjectPrivate) {
d->m_SignalsBlocked = false;
std::cout << "Object Constructor: created d=" << d << std::endl;
}
Object::Object(const Object &copy) : d(new ObjectPrivate) {
if (copy.d) {
d->m_InstanceName = copy.d->m_InstanceName;
d->m_SignalsBlocked = copy.d->m_SignalsBlocked;
}
std::cout << "Object CopyConstructor: created d=" << d << " from copy.d=" << copy.d << std::endl;
}
Object& Object::operator=(const Object &other) {
// Intentionally does NOT share 'd'. Each Object owns its own ObjectPrivate.
// Without this, the compiler-generated operator= would copy the 'd' pointer,
// causing two objects to share the same ObjectPrivate. When both are
// destroyed, 'd' would be deleted twice, corrupting the heap.
if (this != &other && other.d) {
d->m_InstanceName = other.d->m_InstanceName;
d->m_SignalsBlocked = other.d->m_SignalsBlocked;
}
return *this;
}
Object::~Object() {
std::cout << "Object Destructor: deleting d=" << d << " name=" << d->m_InstanceName << std::endl;
for (auto* p : d->m_DynamicProperties) {
delete p;
}
@@ -135,6 +150,7 @@ Object::~Object() {
void Object::DeepCopy(const Object &copy) {
if (this == &copy) return;
if (copy.d) d->m_InstanceName = copy.d->m_InstanceName;
std::cout << "Object DeepCopy: from d=" << copy.d << " to d=" << d << std::endl;
// Note: signals, slots and properties are intentionally not copied
// to maintain instance uniquely and avoid duplicate registrations.
this->Updated();
@@ -161,9 +177,8 @@ void Object::LoadConfig(std::istream &is, int version) {
void Object::PrintSelf(std::ostream &o) const {
o << "OBJECT signals: ------------------\n";
Vector<ObjectPrivate::Signal>::Iterator itr;
for (itr = d->sigv.begin(); itr < d->sigv.end(); itr++) {
o << " signal:[ " << itr->sigstr << " ]\n";
for (const auto& sig : d->sigv) {
o << " signal:[ " << sig.sigstr << " ]\n";
}
o << "--------------------------------------\n\n";
}

View File

@@ -75,7 +75,7 @@ public:
Object();
Object(const Object &copy);
~Object();
virtual ~Object();
virtual const char * GetClassName() const { return "Object"; }
@@ -227,10 +227,7 @@ public:
void PrintSelf(std::ostream &o) const;
inline const Object &operator=(const Object &copy) {
this->DeepCopy(copy);
return *this;
}
Object &operator=(const Object &other);
private:
bool addSignalImpl(SignalBase *sig, GenericMFPtr fptr, const char *name);

View File

@@ -1,5 +1,6 @@
#include "Core/Monitor.h"
#include <iostream>
#include <chrono>
#include <thread>
#include <vector>
#include <cassert>