#ifndef OBJECTVISITOR_H
#define OBJECTVISITOR_H
#include <QObject>
#include <QVariant>
#include <algorithm>
#include <cstdint>
class Visitor
{
public:
Visitor() {}
virtual ~Visitor() {}
virtual void enterObject(const char* className, const char* objectName) = 0;
virtual void leaveObject(const char* className, const char* objectName) = 0;
// Reads or writes a property value
virtual void visit(const char* className,
const char* propertyName, QVariant::Type typ, QVariant& value) = 0;
// By default, it is a reader, but implementing this enables a visitor that sets values
virtual bool isWriting() { return false; }
};
void Visit(Visitor& visitor, QObject* object)
{
std::string objectName = object->objectName().toLocal8Bit().data();
if (objectName.size() <= 1) {
objectName = std::to_string((uint64_t)(void*)object);
}
visitor.enterObject(object->metaObject()->className(), objectName.c_str());
for (int i = 0; i < object->metaObject()->propertyCount(); i++)
{
const QMetaProperty& property = object->metaObject()->property(i);
if (visitor.isWriting()) {
QVariant value;
visitor.visit(property.enclosingMetaObject()->className(),
property.name(), property.type(), value);
property.write(object, value);
} else {
QVariant value = property.read(object);
visitor.visit(property.enclosingMetaObject()->className(),
property.name(), property.type(), value);
}
}
for (int i = 0; i < object->children().count(); i++)
{
Visit(visitor, object->children()[i]);
}
visitor.leaveObject(object->metaObject()->className(), objectName.c_str());
}
#endif // OBJECTVISITOR_H