#include <QObject>
#include <QString>
#include <QFile>
#include <QDebug>
#include <QMap>
#include <QDataStream>
#include <QMetaObject>
#include <QByteArray>
#include <QVariant>
#include <QMetaProperty>
#include <QList>
#include <QMetaType>
#include <QBuffer>
#include <iostream>
{
Q_OBJECT
Q_PROPERTY(QString string READ string WRITE setString
)
public:
Object() {
}
const QString& string() const {
return str;
}
void setString
(const QString &ss
) { str = ss;
}
void dump() const {
std::cout << str.toStdString() << std::endl;
}
private:
};
{
Q_OBJECT
Q_PROPERTY(QObject *object READ object WRITE setObject
)
public:
Parent() {
}
return obj;
}
Q_ASSERT(!oo || qobject_cast<Object*>(oo));
obj = qobject_cast<Object*>(oo);
}
private:
Object *obj;
};
class BaseInterface
{
public:
virtual ~BaseInterface() {}
};
template <typename T>
class Creator : public BaseInterface
{
public:
T *ret = new T;
ret->setObjectName(objectName);
return ret;
}
};
class Factory
{
public:
BaseInterface *i = interfaces.value(className, 0);
assert (i);
return i->create(objectName);
}
static void registerClass
(const QString &className, BaseInterface
*interface
) { if (!interface) {
delete interfaces.value(className, 0);
interfaces.remove(className);
} else {
interfaces[className] = interface;
}
}
static QMap<QString, BaseInterface*> interfaces;
};
QMap<QString, BaseInterface*> Factory::interfaces;
{
QMap<QByteArray, QVariant> properties;
QMap<QByteArray, QByteArray> objectStarProperties;
QMap<QByteArray, QVariantList> listProp;;
const int props = mo->propertyCount();
for (int i=0; i<props; ++i) {
if (prop.
userType() == QMetaType::QObjectStar) { QObject *obj
= qVariantValue<QObject
*>
(prop.
read(o
));
if (obj) {
save(obj, &buf);
objectStarProperties[prop.name()] = buf.buffer();
}
} else if (prop.
userType() == QMetaType::QVariantList) { listProp[prop.name()] = prop.read(o).toList();
} else {
properties[prop.name()] = prop.read(o);
}
}
ds <<
QString::fromLatin1(mo
->className
());
ds << properties;
ds << objectStarProperties;
ds << listProp.size();
QMapIterator<QByteArray, QVariantList> it1( listProp );
while( it1.hasNext() ) {
it1.next();
QVariantList vlist = it1.value();
ds << vlist.size() << it1.key();
}
}
{
QMap<QByteArray, QVariant> properties;
QMap<QByteArray, QByteArray> objectStarProperties;
ds >> className;
ds >> properties;
ds >> objectStarProperties;
int nlists;
ds >> nlists;
QList<int> iList;
QList<QByteArray> propNameList;
for ( int idx=0; idx<nlists; idx++ ) {
int il;
ds >> il >> pnl;
iList.append( il );
propNameList.append( pnl );
}
QObject *o
= Factory
::create(className,
properties.value("objectName").toString());
if (!o) {
qWarning() << "Can't create object of type" << className;
return 0;
}
for (QMap<QByteArray, QVariant>::const_iterator it = properties.begin();
it != properties.end(); ++it) {
if (!o->setProperty(it.key().constData(), it.value())) {
qWarning() << "Can't set" << it.key();
}
}
for (QMap<QByteArray, QByteArray>::const_iterator it =
objectStarProperties.begin();
it != objectStarProperties.end(); ++it) {
buf.setData(it.value());
o->setProperty(it.key(), qVariantFromValue<QObject*>(obj));
}
for ( int idx=0; idx<nlists; idx++ ) {
QVariantList objList;
for (int ii=0; ii<iList[idx]; ++ii) {
objList << qVariantFromValue<QObject*>( oo );
}
o->setProperty( propNameList[idx], objList );
}
return o;
}
#include "main.moc"
int main()
{
Factory::registerClass("Parent", new Creator<Parent>());
Factory::registerClass("Object", new Creator<Object>());
Object *o = new Object;
o->setString("foobar");
Parent *p = new Parent;
p->setObject(o);
qobject_cast<Object*>( p->object() )->dump();
save(p, &file);
file.close();
Q_ASSERT(root);
Parent *pp = qobject_cast<Parent*>(root);
qobject_cast<Object*>( pp->object() )->dump();
return 0;
}