78 lines
2.2 KiB
C++
78 lines
2.2 KiB
C++
#include <mitsuba/mitsuba.h>
|
|
|
|
MTS_NAMESPACE_BEGIN
|
|
|
|
// #define DEBUG_SERIALIZATION 1
|
|
|
|
InstanceManager::InstanceManager() : m_counter(0) {
|
|
#ifdef DEBUG_SERIALIZATION
|
|
Log(EDebug, "Creating an instance manger");
|
|
#endif
|
|
}
|
|
|
|
InstanceManager::~InstanceManager() {
|
|
#ifdef DEBUG_SERIALIZATION
|
|
Log(EDebug, "Destroying an instance manager");
|
|
#endif
|
|
for (std::vector<SerializableObject *>::iterator it = m_fullyAllocated.begin();
|
|
it!= m_fullyAllocated.end(); ++it) {
|
|
(*it)->decRef();
|
|
}
|
|
}
|
|
|
|
SerializableObject *InstanceManager::getInstance(Stream *stream) {
|
|
m_lastID = stream->readUInt();
|
|
if (m_lastID == 0) {
|
|
return NULL;
|
|
} else if (m_idToObj.find(m_lastID) != m_idToObj.end()) {
|
|
return m_idToObj[m_lastID];
|
|
} else {
|
|
SerializableObject *object = NULL;
|
|
std::string className = stream->readString();
|
|
#ifdef DEBUG_SERIALIZATION
|
|
Log(EDebug, "Unserializing a class of type '%s'", className.c_str());
|
|
#endif
|
|
const Class *theClass = Class::forName(className);
|
|
if (theClass == NULL)
|
|
Log(EError, "Class with name '%s' not found!", className.c_str());
|
|
try {
|
|
object = static_cast<SerializableObject *>
|
|
(theClass->unserialize(stream, this));
|
|
} catch (std::exception &e) {
|
|
Log(EError, "Encountered an exception while unserializing an "
|
|
"instance of \"%s\": \"%s\"!", className.c_str(), e.what());
|
|
}
|
|
m_fullyAllocated.push_back(object);
|
|
object->incRef();
|
|
return object;
|
|
}
|
|
}
|
|
|
|
void InstanceManager::registerInstance(SerializableObject *object) {
|
|
m_idToObj[m_lastID] = object;
|
|
}
|
|
|
|
void InstanceManager::serialize(Stream *stream, const SerializableObject *inst) {
|
|
if (inst == NULL) {
|
|
stream->writeUInt(0);
|
|
} else if (m_objToId.find(inst) != m_objToId.end()) {
|
|
stream->writeUInt(m_objToId[inst]);
|
|
} else {
|
|
#ifdef DEBUG_SERIALIZATION
|
|
Log(EDebug, "Serializing a class of type '%s'", inst->getClass()->getName().c_str());
|
|
#endif
|
|
stream->writeUInt(++m_counter);
|
|
stream->writeString(inst->getClass()->getName());
|
|
m_objToId[inst]=m_counter;
|
|
inst->serialize(stream, this);
|
|
}
|
|
}
|
|
|
|
SerializableObject::SerializableObject(Stream *stream, InstanceManager *manager) {
|
|
manager->registerInstance(this);
|
|
}
|
|
|
|
MTS_IMPLEMENT_CLASS(SerializableObject, true, Object)
|
|
MTS_IMPLEMENT_CLASS(InstanceManager, false, Object)
|
|
MTS_NAMESPACE_END
|