/**
 * This file is generated by dconfig2cpp.
 * Command line arguments: ./dconfig2cpp -p ./dtkcore/toolGenerate/dconfig2cpp ./dtkcore/tests/data/dconf-example.meta.json
 * Generation time: 2025-01-14T10:54:59
 * JSON file version: 1.0
 * 
 * WARNING: DO NOT MODIFY THIS FILE MANUALLY.
 * If you need to change the content, please modify the dconfig2cpp tool.
 */

#ifndef DCONF-EXAMPLE_META_H
#define DCONF-EXAMPLE_META_H

#include <QThread>
#include <QVariant>
#include <QDebug>
#include <QAtomicPointer>
#include <QAtomicInteger>
#include <DConfig>

class dconf-example_meta : public QObject {
    Q_OBJECT

    Q_PROPERTY(QList<QVariant> array READ array WRITE setArray NOTIFY arrayChanged)
    Q_PROPERTY(QList<QVariant> array_map READ array_map WRITE setArray_map NOTIFY array_mapChanged)
    Q_PROPERTY(QList<QVariant> array_map_struct READ array_map_struct WRITE setArray_map_struct NOTIFY array_map_structChanged)
    Q_PROPERTY(bool canExit READ canExit WRITE setCanExit NOTIFY canExitChanged)
    Q_PROPERTY(QString key2 READ key2 WRITE setKey2 NOTIFY key2Changed)
    Q_PROPERTY(QString key3 READ key3 WRITE setKey3 NOTIFY key3Changed)
    Q_PROPERTY(QVariantMap map READ map WRITE setMap NOTIFY mapChanged)
    Q_PROPERTY(QVariantMap map_array READ map_array WRITE setMap_array NOTIFY map_arrayChanged)
    Q_PROPERTY(double number READ number WRITE setNumber NOTIFY numberChanged)
    Q_PROPERTY(double numberDouble READ numberDouble WRITE setNumberDouble NOTIFY numberDoubleChanged)
    Q_PROPERTY(bool publicConfig READ publicConfig WRITE setPublicConfig NOTIFY publicConfigChanged)
    Q_PROPERTY(QVariantMap struct READ struct WRITE setStruct NOTIFY structChanged)
public:
    explicit dconf-example_meta(QThread *thread, const QString &appId, const QString &name, const QString &subpath, QObject *parent = nullptr)
        : QObject(parent) {

        if (!thread->isRunning()) {
            qWarning() << QStringLiteral("Warning: The provided thread is not running.");
        }
        Q_ASSERT(QThread::currentThread() != thread);
        auto worker = new QObject();
        worker->moveToThread(thread);
        QMetaObject::invokeMethod(worker, [=]() {
            auto config = DTK_CORE_NAMESPACE::DConfig::create(appId, name, subpath, nullptr);
            if (!config) {
                qWarning() << QStringLiteral("Failed to create DConfig instance.");
                worker->deleteLater();
                return;
            }
            config->moveToThread(QThread::currentThread());
            initialize(config);
            worker->deleteLater();
        });
    }
    explicit dconf-example_meta(QThread *thread, DTK_CORE_NAMESPACE::DConfigBackend *backend, const QString &appId, const QString &name, const QString &subpath, QObject *parent = nullptr)
        : QObject(parent) {

        if (!thread->isRunning()) {
            qWarning() << QStringLiteral("Warning: The provided thread is not running.");
        }
        Q_ASSERT(QThread::currentThread() != thread);
        auto worker = new QObject();
        worker->moveToThread(thread);
        QMetaObject::invokeMethod(worker, [=]() {
            auto config = DTK_CORE_NAMESPACE::DConfig::create(backend, appId, name, subpath, nullptr);
            if (!config) {
                qWarning() << QStringLiteral("Failed to create DConfig instance.");
                worker->deleteLater();
                return;
            }
            config->moveToThread(QThread::currentThread());
            initialize(config);
            worker->deleteLater();
        });
    }
    explicit dconf-example_meta(QThread *thread, const QString &name, const QString &subpath, QObject *parent = nullptr)
        : QObject(parent) {

        if (!thread->isRunning()) {
            qWarning() << QStringLiteral("Warning: The provided thread is not running.");
        }
        Q_ASSERT(QThread::currentThread() != thread);
        auto worker = new QObject();
        worker->moveToThread(thread);
        QMetaObject::invokeMethod(worker, [=]() {
            auto config = DTK_CORE_NAMESPACE::DConfig::create(name, subpath, nullptr);
            if (!config) {
                qWarning() << QStringLiteral("Failed to create DConfig instance.");
                worker->deleteLater();
                return;
            }
            config->moveToThread(QThread::currentThread());
            initialize(config);
            worker->deleteLater();
        });
    }
    explicit dconf-example_meta(QThread *thread, DTK_CORE_NAMESPACE::DConfigBackend *backend, const QString &name, const QString &subpath, QObject *parent = nullptr)
        : QObject(parent) {

        if (!thread->isRunning()) {
            qWarning() << QStringLiteral("Warning: The provided thread is not running.");
        }
        Q_ASSERT(QThread::currentThread() != thread);
        auto worker = new QObject();
        worker->moveToThread(thread);
        QMetaObject::invokeMethod(worker, [=]() {
            auto config = DTK_CORE_NAMESPACE::DConfig::create(backend, name, subpath, nullptr);
            if (!config) {
                qWarning() << QStringLiteral("Failed to create DConfig instance.");
                worker->deleteLater();
                return;
            }
            config->moveToThread(QThread::currentThread());
            initialize(config);
            worker->deleteLater();
        });
    }
    ~dconf-example_meta() {
        if (m_config.loadRelaxed()) {
            m_config.loadRelaxed()->deleteLater();
        }
    }

    QList<QVariant> array() const {
        return p_array;
    }
    void setArray(const QList<QVariant> &value) {
        auto oldValue = p_array;
        p_array = value;
        markPropertySet(0);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("array"), value);
            });
        }
        if (p_array != oldValue) {
            Q_EMIT arrayChanged();
        }
    }
    QList<QVariant> array_map() const {
        return p_array_map;
    }
    void setArray_map(const QList<QVariant> &value) {
        auto oldValue = p_array_map;
        p_array_map = value;
        markPropertySet(1);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("array_map"), value);
            });
        }
        if (p_array_map != oldValue) {
            Q_EMIT array_mapChanged();
        }
    }
    QList<QVariant> array_map_struct() const {
        return p_array_map_struct;
    }
    void setArray_map_struct(const QList<QVariant> &value) {
        auto oldValue = p_array_map_struct;
        p_array_map_struct = value;
        markPropertySet(2);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("array_map_struct"), value);
            });
        }
        if (p_array_map_struct != oldValue) {
            Q_EMIT array_map_structChanged();
        }
    }
    bool canExit() const {
        return p_canExit;
    }
    void setCanExit(const bool &value) {
        auto oldValue = p_canExit;
        p_canExit = value;
        markPropertySet(3);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("canExit"), value);
            });
        }
        if (p_canExit != oldValue) {
            Q_EMIT canExitChanged();
        }
    }
    QString key2() const {
        return p_key2;
    }
    void setKey2(const QString &value) {
        auto oldValue = p_key2;
        p_key2 = value;
        markPropertySet(4);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("key2"), value);
            });
        }
        if (p_key2 != oldValue) {
            Q_EMIT key2Changed();
        }
    }
    QString key3() const {
        return p_key3;
    }
    void setKey3(const QString &value) {
        auto oldValue = p_key3;
        p_key3 = value;
        markPropertySet(5);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("key3"), value);
            });
        }
        if (p_key3 != oldValue) {
            Q_EMIT key3Changed();
        }
    }
    QVariantMap map() const {
        return p_map;
    }
    void setMap(const QVariantMap &value) {
        auto oldValue = p_map;
        p_map = value;
        markPropertySet(6);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("map"), value);
            });
        }
        if (p_map != oldValue) {
            Q_EMIT mapChanged();
        }
    }
    QVariantMap map_array() const {
        return p_map_array;
    }
    void setMap_array(const QVariantMap &value) {
        auto oldValue = p_map_array;
        p_map_array = value;
        markPropertySet(7);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("map_array"), value);
            });
        }
        if (p_map_array != oldValue) {
            Q_EMIT map_arrayChanged();
        }
    }
    double number() const {
        return p_number;
    }
    void setNumber(const double &value) {
        auto oldValue = p_number;
        p_number = value;
        markPropertySet(8);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("number"), value);
            });
        }
        if (p_number != oldValue) {
            Q_EMIT numberChanged();
        }
    }
    double numberDouble() const {
        return p_numberDouble;
    }
    void setNumberDouble(const double &value) {
        auto oldValue = p_numberDouble;
        p_numberDouble = value;
        markPropertySet(9);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("numberDouble"), value);
            });
        }
        if (p_numberDouble != oldValue) {
            Q_EMIT numberDoubleChanged();
        }
    }
    bool publicConfig() const {
        return p_publicConfig;
    }
    void setPublicConfig(const bool &value) {
        auto oldValue = p_publicConfig;
        p_publicConfig = value;
        markPropertySet(10);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("publicConfig"), value);
            });
        }
        if (p_publicConfig != oldValue) {
            Q_EMIT publicConfigChanged();
        }
    }
    QVariantMap struct() const {
        return p_struct;
    }
    void setStruct(const QVariantMap &value) {
        auto oldValue = p_struct;
        p_struct = value;
        markPropertySet(11);
        if (auto config = m_config.loadRelaxed()) {
            QMetaObject::invokeMethod(config, [this, value]() {
                m_config.loadRelaxed()->setValue(QStringLiteral("struct"), value);
            });
        }
        if (p_struct != oldValue) {
            Q_EMIT structChanged();
        }
    }
Q_SIGNALS:
    void arrayChanged();
    void array_mapChanged();
    void array_map_structChanged();
    void canExitChanged();
    void key2Changed();
    void key3Changed();
    void mapChanged();
    void map_arrayChanged();
    void numberChanged();
    void numberDoubleChanged();
    void publicConfigChanged();
    void structChanged();
private:
    void initialize(DTK_CORE_NAMESPACE::DConfig *config) {
        Q_ASSERT(!m_config.loadRelaxed());
        m_config.storeRelaxed(config);
        if (testPropertySet(0)) {
            config->setValue(QStringLiteral("array"), QVariant::fromValue(p_array));
        } else {
            updateValue(QStringLiteral("array"), QVariant::fromValue(p_array));
        }
        if (testPropertySet(1)) {
            config->setValue(QStringLiteral("array_map"), QVariant::fromValue(p_array_map));
        } else {
            updateValue(QStringLiteral("array_map"), QVariant::fromValue(p_array_map));
        }
        if (testPropertySet(2)) {
            config->setValue(QStringLiteral("array_map_struct"), QVariant::fromValue(p_array_map_struct));
        } else {
            updateValue(QStringLiteral("array_map_struct"), QVariant::fromValue(p_array_map_struct));
        }
        if (testPropertySet(3)) {
            config->setValue(QStringLiteral("canExit"), QVariant::fromValue(p_canExit));
        } else {
            updateValue(QStringLiteral("canExit"), QVariant::fromValue(p_canExit));
        }
        if (testPropertySet(4)) {
            config->setValue(QStringLiteral("key2"), QVariant::fromValue(p_key2));
        } else {
            updateValue(QStringLiteral("key2"), QVariant::fromValue(p_key2));
        }
        if (testPropertySet(5)) {
            config->setValue(QStringLiteral("key3"), QVariant::fromValue(p_key3));
        } else {
            updateValue(QStringLiteral("key3"), QVariant::fromValue(p_key3));
        }
        if (testPropertySet(6)) {
            config->setValue(QStringLiteral("map"), QVariant::fromValue(p_map));
        } else {
            updateValue(QStringLiteral("map"), QVariant::fromValue(p_map));
        }
        if (testPropertySet(7)) {
            config->setValue(QStringLiteral("map_array"), QVariant::fromValue(p_map_array));
        } else {
            updateValue(QStringLiteral("map_array"), QVariant::fromValue(p_map_array));
        }
        if (testPropertySet(8)) {
            config->setValue(QStringLiteral("number"), QVariant::fromValue(p_number));
        } else {
            updateValue(QStringLiteral("number"), QVariant::fromValue(p_number));
        }
        if (testPropertySet(9)) {
            config->setValue(QStringLiteral("numberDouble"), QVariant::fromValue(p_numberDouble));
        } else {
            updateValue(QStringLiteral("numberDouble"), QVariant::fromValue(p_numberDouble));
        }
        if (testPropertySet(10)) {
            config->setValue(QStringLiteral("publicConfig"), QVariant::fromValue(p_publicConfig));
        } else {
            updateValue(QStringLiteral("publicConfig"), QVariant::fromValue(p_publicConfig));
        }
        if (testPropertySet(11)) {
            config->setValue(QStringLiteral("struct"), QVariant::fromValue(p_struct));
        } else {
            updateValue(QStringLiteral("struct"), QVariant::fromValue(p_struct));
        }

        connect(config, &DTK_CORE_NAMESPACE::DConfig::valueChanged, this, [this](const QString &key) {
            updateValue(key);
        }, Qt::DirectConnection);
    }
    void updateValue(const QString &key, const QVariant &fallback = QVariant()) {
        Q_ASSERT(QThread::currentThread() == m_config.loadRelaxed()->thread());
        const QVariant &value = m_config.loadRelaxed()->value(key, fallback);
        if (key == QStringLiteral("array")) {
            auto newValue = qvariant_cast<QList<QVariant>>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_array != newValue) {
                    p_array = newValue;
                    Q_EMIT arrayChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("array_map")) {
            auto newValue = qvariant_cast<QList<QVariant>>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_array_map != newValue) {
                    p_array_map = newValue;
                    Q_EMIT array_mapChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("array_map_struct")) {
            auto newValue = qvariant_cast<QList<QVariant>>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_array_map_struct != newValue) {
                    p_array_map_struct = newValue;
                    Q_EMIT array_map_structChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("canExit")) {
            auto newValue = qvariant_cast<bool>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_canExit != newValue) {
                    p_canExit = newValue;
                    Q_EMIT canExitChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("key2")) {
            auto newValue = qvariant_cast<QString>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_key2 != newValue) {
                    p_key2 = newValue;
                    Q_EMIT key2Changed();
                }
            });
            return;
        }
        if (key == QStringLiteral("key3")) {
            auto newValue = qvariant_cast<QString>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_key3 != newValue) {
                    p_key3 = newValue;
                    Q_EMIT key3Changed();
                }
            });
            return;
        }
        if (key == QStringLiteral("map")) {
            auto newValue = qvariant_cast<QVariantMap>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_map != newValue) {
                    p_map = newValue;
                    Q_EMIT mapChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("map_array")) {
            auto newValue = qvariant_cast<QVariantMap>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_map_array != newValue) {
                    p_map_array = newValue;
                    Q_EMIT map_arrayChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("number")) {
            auto newValue = qvariant_cast<double>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_number != newValue) {
                    p_number = newValue;
                    Q_EMIT numberChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("numberDouble")) {
            auto newValue = qvariant_cast<double>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_numberDouble != newValue) {
                    p_numberDouble = newValue;
                    Q_EMIT numberDoubleChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("publicConfig")) {
            auto newValue = qvariant_cast<bool>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_publicConfig != newValue) {
                    p_publicConfig = newValue;
                    Q_EMIT publicConfigChanged();
                }
            });
            return;
        }
        if (key == QStringLiteral("struct")) {
            auto newValue = qvariant_cast<QVariantMap>(value);
            QMetaObject::invokeMethod(this, [this, newValue]() {
                if (p_struct != newValue) {
                    p_struct = newValue;
                    Q_EMIT structChanged();
                }
            });
            return;
        }
    }
    inline void markPropertySet(const int index) {
        if (index < 32) {
            m_propertySetStatus0.fetchAndOrOrdered(1 << (index - 0));
            return;
        }
        Q_UNREACHABLE();
    }
    inline bool testPropertySet(const int index) const {
        if (index < 32) {
            return (m_propertySetStatus0.loadRelaxed() & (1 << (index - 0)));
        }
        Q_UNREACHABLE();
    }
    QAtomicPointer<DTK_CORE_NAMESPACE::DConfig> m_config = nullptr;
    QList<QVariant> p_array { QList<QVariant>{QVariant(QStringLiteral("value1")), QVariant(QStringLiteral("value2"))} };
    QList<QVariant> p_array_map { QList<QVariant>{QVariant(QVariantMap{{QStringLiteral("key1"), QVariant(QStringLiteral("value1"))}, {QStringLiteral("key2"), QVariant(QStringLiteral("value2"))}})} };
    QList<QVariant> p_array_map_struct { QList<QVariant>{QVariant(QVariantMap{{QStringLiteral("key1"), QVariant(QVariantMap{{QStringLiteral("field1"), QVariant(QStringLiteral("value1"))}})}, {QStringLiteral("key2"), QVariant(QStringLiteral("value2"))}})} };
    bool p_canExit { true };
    QString p_key2 { QStringLiteral("125") };
    QString p_key3 { QStringLiteral("application") };
    QVariantMap p_map { QVariantMap{{QStringLiteral("key1"), QVariant(QStringLiteral("value1"))}, {QStringLiteral("key2"), QVariant(QStringLiteral("value2"))}} };
    QVariantMap p_map_array { QVariantMap{{QStringLiteral("key1"), QVariant(QList<QVariant>{QVariant(QStringLiteral("value1"))})}, {QStringLiteral("key2"), QVariant(QList<QVariant>{QVariant(QStringLiteral("value2"))})}} };
    double p_number { 1 };
    double p_numberDouble { 1 };
    bool p_publicConfig { true };
    QVariantMap p_struct { QVariantMap{{QStringLiteral("key1"), QVariant(QStringLiteral("value1"))}, {QStringLiteral("key2"), QVariant(QStringLiteral("value2"))}} };
    QAtomicInteger<quint32> m_propertySetStatus0 = 0;
};

#endif // DCONF-EXAMPLE_META_H
