Skycoder42 / QtJsonSerializer

A library to perform generic seralization and deserialization of QObjects from and to JSON and CBOR
https://skycoder42.github.io/QtJsonSerializer/
BSD 3-Clause "New" or "Revised" License
143 stars 70 forks source link

Best practices for registering custom types for QtJsonSerializer #23

Closed arietto closed 4 years ago

arietto commented 4 years ago

Hello! What should I do if I have multiple custom embedded types? For example, matryoshka;

Gadget_A {
    QList<B> b_list;
};
//...
Gadget_B {
    QList<C> c_list;
};
//...
Gadget_C: {
    QString name;
};

What are the tricks for tracking such types? I mean QJsonSerializer::registerListConverters() usage. For example, if we use Q_DECLARE_METATYPE, then we put it after class declaration, Placing QJsonSerializer::registerListConverters() in main.cpp is more error-prone.

Skycoder42 commented 4 years ago

I would recommend to put it in the same place as you put qRegisterMetaType<T>() calls. What exactly you do depends on your general code style, I would say.

In my opinion, there are 2 clean ways to do this, that I would recommend (besides just putting everything in the main): Either hidden or explicit.

The explicit variant would add a static register function to each object, that can be automatically called for dynamic libraries and applications. For example:

struct Gadget_C {
    QString name;
    static void registerMetaType() {
        qRegisterMetaType<Gadget_C>();
        QJsonSerializer::registerListConverters<Gadget_C>();
    }
};
// and optionally in the cpp:
namespace {
    void startup_hook() {
        Gadget_C::registerMetaType();
    }
}
Q_COREAPP_STARTUP_FUNCTION(startup_hook)

The hidden option instead uses the constructor of the gadget to register itself the first time one is created:

struct Gadget_C {
    QString name;
    Gadget_C() {
        static auto once = true;
        if (once) {
            once = false;
            qRegisterMetaType<Gadget_C>();
            QJsonSerializer::registerListConverters<Gadget_C>();
        }
    }
};
arietto commented 4 years ago

Thank you for ideas!