Git Product home page Git Product logo

Comments (2)

Skycoder42 avatar Skycoder42 commented on July 2, 2024

First, make sure to read the documentation about this library treats polymorphism: https://skycoder42.github.io/QtJsonSerializer/class_qt_json_serializer_1_1_serializer_base.html#a18d5fc879178e3d3ab9094de4f3277e2

As stated there, the serializer should add a special "@Class" property that holds the actual type. This property is written and read/interpreted by the object serializer itself - this means if you have a custom serializer, you have to duplicate that behaviour.

Getting the can convert for the base class is correct, as from C++, you request the deserialization of a Base object. Your serializer should be able to detect that it is actually a Derived and do the serialization, as generally there is no guarantee that the object being deserialized is actually of the Derived type. If you know that beforehand, you could just deserialize it as Derived directly and don't need polymorphism.

I hope this helps you with your problem. If not, maybe post the code of your custom converter here, and I can take a look at it and give you some ideas on how to proceed.

from qtjsonserializer.

useful-friend avatar useful-friend commented on July 2, 2024

I'm using version: 3.3.1-3

The serializer works fine with most of my polymorphic classes except the one I mentioned above.

I've used the Q_CLASSINFO("polymorphic", "true") in the Base class declaration.
Let's say we have the following code snippet.
Note: "..." means that the code in the QJsonObjectConverter is used without any changes.

class Base : public QObject
{
    Q_OBJECT
    Q_CLASSINFO("polymorphic", "true")
public:
    Base(QObject *parent = nullptr) {}
}


class Derived : public Base
{
    Q_OBJECT
public:
    Q_INVOKABLE  Derived(int a, QObject *parent = nullptr) : Base(parent) {}
}

class Derived2 : public Base
{
    Q_OBJECT
public:
    Q_INVOKABLE  Derived2(int a, int b, QObject *parent = nullptr) : Base(parent) {}
}

First I need to do something to override the default object instantiation by adding a type converter. right?
so I created two new type converter with the following codes:

class Q_JSONSERIALIZER_EXPORT QJsonCustomConverter : public QJsonTypeConverter
{
   int m_number;
public:
    QJsonCustomConverter(int n) : m_number(n) {}
    bool canConvert(int metaTypeId) const override;
    ...
    ...
    ...
}

definition:

bool QJsonCustomConverter::canConvert(int metaTypeId) const
{
    if (metaTypeId != QMetaType::type("Derived*"))
        return false;
    auto flags = QMetaType::typeFlags(metaTypeId);
    return (flags.testFlag(QMetaType::PointerToQObject) ||
            flags.testFlag(QMetaType::SharedPointerToQObject) ||//weak ptr cannot be constructed
            flags.testFlag(QMetaType::TrackingPointerToQObject));
}
...
...
QVariant QJsonCustomConverter::deserialize(int propertyType, const QJsonValue &value, QObject *parent, const QJsonTypeConverter::SerializationHelper *helper) const
{
...
...
auto object = metaObject->newInstance(Q_ARG(int, m_number), Q_ARG(QObject*, parent));
    if(!object) {
        throw QJsonDeserializationException(QByteArray("Failed to construct object")
    }
...
...
}

and for the second class:

class Q_JSONSERIALIZER_EXPORT QJsonCustomConverter2 : public QJsonTypeConverter
{
   int m_number;
   int m_number2;
public:
    QJsonCustomConverter2(int n, int n2) : m_number(n), m_number2(n2) {}
    bool canConvert(int metaTypeId) const override;
    ...
    ...
    ...
}

definition:

bool QJsonCustomConverter::canConvert(int metaTypeId) const
{
    if (metaTypeId != QMetaType::type("Derived2*"))
        return false;
    auto flags = QMetaType::typeFlags(metaTypeId);
    return (flags.testFlag(QMetaType::PointerToQObject) ||
            flags.testFlag(QMetaType::SharedPointerToQObject) ||//weak ptr cannot be constructed
            flags.testFlag(QMetaType::TrackingPointerToQObject));
}
...
...
QVariant QJsonCustomConverter::deserialize(int propertyType, const QJsonValue &value, QObject *parent, const QJsonTypeConverter::SerializationHelper *helper) const
{
...
...
auto object = metaObject->newInstance(Q_ARG(int, m_number), Q_ARG(int, m_number2), Q_ARG(QObject*, parent));
    if(!object) {
        throw QJsonDeserializationException(QByteArray("Failed to construct object")
    }
...
...
}

I added those converters and faced the problem mentioned in the previous post in deserialization and none of the converters is used because the canConvert function returns false.

from qtjsonserializer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.