Przeglądaj źródła

Add qtprotobuf qml plugin to apply extra class registration
- Add valuetypes provider
- Add extra registration for code protobuf types

Alexey Edelev 5 lat temu
rodzic
commit
82113492f7

+ 2 - 0
src/protobuf/CMakeLists.txt

@@ -67,3 +67,5 @@ install(FILES "${CMAKE_BINARY_DIR}/QtProtobufGen.cmake" DESTINATION "${TARGET_CM
 
 configure_file("${CMAKE_SOURCE_DIR}/cmake/ProtobufLookup.cmake" "${CMAKE_BINARY_DIR}/ProtobufLookup.cmake" COPYONLY)
 install(FILES "${CMAKE_BINARY_DIR}/ProtobufLookup.cmake" DESTINATION "${TARGET_CMAKE_DIR}")
+
+add_subdirectory("quick")

+ 4 - 0
src/protobuf/qtprotobuf.cpp

@@ -66,14 +66,17 @@ void registerTypes() {
     QMetaType::registerConverter<int64, int64_t>(int64::toType);
     QMetaType::registerConverter<qint64, int64>(int64::fromType);
     QMetaType::registerConverter<int64, qint64>(int64::toType);
+    QMetaType::registerConverter<int32_t, int64>(int64::fromType);
 
     QMetaType::registerConverter<uint32_t, fixed32>(fixed32::fromType);
     QMetaType::registerConverter<fixed32, uint32_t>(fixed32::toType);
+    QMetaType::registerConverter<int32_t, fixed32>(fixed32::fromType);
 
     QMetaType::registerConverter<uint64_t, fixed64>(fixed64::fromType);
     QMetaType::registerConverter<fixed64, uint64_t>(fixed64::toType);
     QMetaType::registerConverter<quint64, fixed64>(fixed64::fromType);
     QMetaType::registerConverter<fixed64, quint64>(fixed64::toType);
+    QMetaType::registerConverter<int32_t, fixed64>(fixed64::fromType);
 
     QMetaType::registerConverter<int32_t, sfixed32>(sfixed32::fromType);
     QMetaType::registerConverter<sfixed32, int32_t>(sfixed32::toType);
@@ -82,6 +85,7 @@ void registerTypes() {
     QMetaType::registerConverter<sfixed64, int64_t>(sfixed64::toType);
     QMetaType::registerConverter<qint64, sfixed64>(sfixed64::fromType);
     QMetaType::registerConverter<sfixed64, qint64>(sfixed64::toType);
+    QMetaType::registerConverter<int32_t, sfixed64>(sfixed64::fromType);
     ProtobufObjectPrivate::registerSerializers();
 }
 }

+ 39 - 0
src/protobuf/quick/CMakeLists.txt

@@ -0,0 +1,39 @@
+set(TARGET protobufquickplugin)
+
+set(TARGET_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${TARGET})
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+
+find_package(Qt5 COMPONENTS Core Qml REQUIRED)
+
+execute_process(
+    COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_QML
+    OUTPUT_VARIABLE TARGET_IMPORTS_DIR
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+file(GLOB SOURCES
+    qtprotobufquickplugin.cpp
+    qtprotobufvaluetypes.cpp)
+
+file(GLOB HEADERS
+    qtprotobufquickplugin.h
+    qtprotobufvaluetypes_p.h
+    qtprotobufquick_global.h)
+
+add_library(${TARGET} SHARED ${SOURCES})
+target_link_libraries(${TARGET} PRIVATE Qt5::Core Qt5::Qml ${QTPROTOBUF_COMMON_NAMESPACE}::QtProtobuf)
+set_target_properties(${TARGET} PROPERTIES
+    LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/QtProtobuf")
+target_compile_definitions(${TARGET} PRIVATE QTPROTOBUFQUICK_LIB)
+target_include_directories(${TARGET} PRIVATE ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
+install(TARGETS ${TARGET}
+    PUBLIC_HEADER DESTINATION ${TARGET_INCLUDE_DIR}
+    LIBRARY DESTINATION ${TARGET_IMPORTS_DIR})
+
+add_custom_command(TARGET ${TARGET}
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir $<TARGET_FILE_DIR:${TARGET}>/qmldir
+    COMMENT "Copying qmldir to binary directory")
+
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/qmldir DESTINATION "${TARGET_IMPORTS_DIR}/QtProtobuf")

+ 4 - 0
src/protobuf/quick/qmldir

@@ -0,0 +1,4 @@
+module QtProtobuf
+plugin protobufquickplugin
+classname QtProtobufQuickPlugin
+

+ 34 - 0
src/protobuf/quick/qtprotobufquick_global.h

@@ -0,0 +1,34 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <QtCore/QtGlobal>
+
+#ifdef QTPROTOBUFQUICK_LIB
+    #define QTPROTOBUFQUICKSHARED_EXPORT Q_DECL_EXPORT
+#else
+    #define QTPROTOBUFQUICKSHARED_EXPORT Q_DECL_IMPORT
+#endif

+ 64 - 0
src/protobuf/quick/qtprotobufquickplugin.cpp

@@ -0,0 +1,64 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "qtprotobufquickplugin.h"
+#include "qtprotobufvaluetypes_p.h"
+#include <private/qqmlmetatype_p.h>
+#include <QDebug>
+
+void QtProtobufQuickPlugin::registerTypes(const char *uri)
+{
+    Q_ASSERT(uri == QLatin1String("QtProtobuf"));
+    QQmlMetaType::registerCustomStringConverter(qMetaTypeId<qtprotobuf::int32>(), [](const QString &s)
+    {
+        return QVariant::fromValue(qtprotobuf::int32(s.toInt()));
+    });
+    QQmlMetaType::registerCustomStringConverter(qMetaTypeId<qtprotobuf::int64>(), [](const QString &s)
+    {
+        return QVariant::fromValue(qtprotobuf::int64(s.toLongLong()));
+    });
+    QQmlMetaType::registerCustomStringConverter(qMetaTypeId<qtprotobuf::fixed32>(), [](const QString &s)
+    {
+        return QVariant::fromValue(qtprotobuf::fixed32(s.toUInt()));
+    });
+    QQmlMetaType::registerCustomStringConverter(qMetaTypeId<qtprotobuf::fixed64>(), [](const QString &s)
+    {
+        return QVariant::fromValue(qtprotobuf::fixed64(s.toULongLong()));
+    });
+    QQmlMetaType::registerCustomStringConverter(qMetaTypeId<qtprotobuf::sfixed32>(), [](const QString &s)
+    {
+        return QVariant::fromValue(qtprotobuf::sfixed32(s.toInt()));
+    });
+    QQmlMetaType::registerCustomStringConverter(qMetaTypeId<qtprotobuf::sfixed64>(), [](const QString &s)
+    {
+        return QVariant::fromValue(qtprotobuf::sfixed64(s.toLongLong()));
+    });
+    qtprotobuf::registerValueTypes();
+}
+
+QtProtobufQuickPlugin::~QtProtobufQuickPlugin()
+{
+    qtprotobuf::releaseValueTypes();
+}

+ 39 - 0
src/protobuf/quick/qtprotobufquickplugin.h

@@ -0,0 +1,39 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <QQmlExtensionPlugin>
+#include "qtprotobufquick_global.h"
+
+class QTPROTOBUFQUICKSHARED_EXPORT QtProtobufQuickPlugin : public QQmlExtensionPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+
+public:
+    ~QtProtobufQuickPlugin();
+    void registerTypes(const char *) override;
+};

+ 198 - 0
src/protobuf/quick/qtprotobufvaluetypes.cpp

@@ -0,0 +1,198 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <QtQml/private/qqmlglobal_p.h>
+#include <QtQml/private/qv4engine_p.h>
+#include <QtQml/private/qv4object_p.h>
+#include <QtQml/private/qv8engine_p.h>
+
+#include "qtprotobufvaluetypes_p.h"
+#include "qtprotobuftypes.h"
+
+namespace qtprotobuf {
+
+class QtProtobufValueTypeProvider : public QQmlValueTypeProvider
+{
+    QtProtobufValueTypeProvider() = default;
+    Q_DISABLE_COPY(QtProtobufValueTypeProvider)
+    QtProtobufValueTypeProvider(QtProtobufValueTypeProvider &&) = delete;
+    QtProtobufValueTypeProvider &operator =(QtProtobufValueTypeProvider &&) = delete;
+public:
+    static QtProtobufValueTypeProvider *instance() {
+        static QtProtobufValueTypeProvider provider;
+        return &provider;
+    }
+
+    const QMetaObject *getMetaObjectForMetaType(int type) override {
+        qDebug() << "getMetaObjectForMetaType: " <<  type << qMetaTypeId<fixed32>();
+        if (type == qMetaTypeId<fixed32>()) {
+            return &QtProtobufFixed32ValueType::staticMetaObject;
+        }
+
+        return nullptr;
+    }
+
+    bool init(int type, QVariant &dst) {
+        if (type == qMetaTypeId<fixed32>()) {
+            qDebug() << "init: " << type;
+            dst.setValue<fixed32>(0);
+            return true;
+        }
+
+        return false;
+    }
+
+    bool create(int type, int argc, const void *argv[], QVariant *v) override {
+        if (type == qMetaTypeId<fixed32>()) {
+            if (argc == 1) {
+                const int *value = reinterpret_cast<const int*>(argv[0]);
+                qDebug() << "create: " << type << "value" << *value;
+                *v = QVariant::fromValue(fixed32(*value));
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    bool createFromString(int type, const QString &s, void *data, size_t dataSize) override {
+        bool ok = false;
+        if (type == qMetaTypeId<fixed32>()) {
+            Q_ASSERT(dataSize >= sizeof(fixed32));
+            fixed32 *t = reinterpret_cast<fixed32 *>(data);
+            qDebug() << "createFromString: " << type << "value" << *t;
+            new (t) fixed32(s.toUInt(&ok));
+            return ok;
+        }
+
+        return false;
+    }
+
+    bool createStringFrom(int type, const void *data, QString *s) override {
+        if (type == qMetaTypeId<fixed32>()) {
+            qDebug() << "createStringFrom: " << type;
+            const fixed32 *t = reinterpret_cast<const fixed32 *>(data);
+            new (s) QString(QString::number(t->_t));
+            return true;
+        }
+
+        return false;
+    }
+
+    bool variantFromString(const QString &s, QVariant *v) override {
+        bool ok = false;
+        fixed32 t = fixed32(s.toUInt(&ok));
+        if (ok) {
+            qDebug() << "variantFromString1: ";
+            *v = QVariant::fromValue(t);
+            return ok;
+        }
+
+        return false;
+    }
+
+    bool variantFromString(int type, const QString &s, QVariant *v) override {
+        bool ok = false;
+
+        if (type == qMetaTypeId<fixed32>()) {
+            qDebug() << "variantFromString: " << type;
+            fixed32 t = fixed32(s.toUInt(&ok));
+            if (ok) {
+                *v = QVariant::fromValue(t);
+            }
+            return ok;
+        }
+
+        return false;
+    }
+
+//    bool variantFromJsObject(int type, QQmlV4Handle object, QV4::ExecutionEngine *v4, QVariant *v) override {
+//        QV4::Scope scope(v4);
+//        QV4::ScopedObject obj(scope, object);
+//        if (type == qMetaTypeId<fixed32>) {
+//            obj.ge
+//        }
+//    }
+
+    bool equal(int type, const void *lhs, const QVariant &rhs) override {
+        if (type == qMetaTypeId<fixed32>()) {
+            return *(reinterpret_cast<const fixed32 *>(lhs)) == rhs.value<fixed32>();
+        }
+
+        return false;
+    }
+
+    bool store(int type, const void *src, void *dst, size_t dstSize) override {
+        if (type == qMetaTypeId<fixed32>()) {
+            qDebug() << "store: " << type;
+            Q_ASSERT(dstSize >= sizeof(fixed32));
+            const fixed32 *srcT = reinterpret_cast<const fixed32 *>(src);
+            fixed32 *dstT = reinterpret_cast<fixed32 *>(dst);
+            new (dstT) fixed32(*srcT);
+            return true;
+        }
+        return false;
+    }
+
+    bool read(const QVariant &src, void *dst, int dstType) override {
+        bool ok;
+        if (dstType == qMetaTypeId<fixed32>()) {
+            qDebug() << "read: " << dstType;
+            fixed32 *dstT = reinterpret_cast<fixed32 *>(dst);
+            *dstT = src.toUInt(&ok);
+            if (!ok) {
+                *dstT = src.value<fixed32>();
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    bool write(int type, const void *src, QVariant &dst) override {
+        if (type == qMetaTypeId<fixed32>()) {
+            qDebug() << "write: " << type;
+            return true;
+        }
+        return false;
+    }
+};
+
+QString QtProtobufFixed32ValueType::toString() const
+{
+    return QString::number(v._t);
+}
+
+
+void registerValueTypes() {
+    QQml_addValueTypeProvider(QtProtobufValueTypeProvider::instance());
+    QQmlValueTypeFactory::registerValueTypes("QtProtobuf", 1, 0);
+}
+
+void releaseValueTypes() {
+    QQml_removeValueTypeProvider(QtProtobufValueTypeProvider::instance());
+}
+
+}

+ 46 - 0
src/protobuf/quick/qtprotobufvaluetypes_p.h

@@ -0,0 +1,46 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>
+ *
+ * This file is part of qtprotobuf project https://git.semlanik.org/semlanik/qtprotobuf
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ * software and associated documentation files (the "Software"), to deal in the Software
+ * without restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+ * to permit persons to whom the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include "qtprotobufquick_global.h"
+#include "qtprotobuftypes.h"
+
+#include <QtQml/private/qqmlvaluetype_p.h>
+
+namespace qtprotobuf {
+
+void registerValueTypes();
+void releaseValueTypes();
+
+class QTPROTOBUFQUICKSHARED_EXPORT QtProtobufFixed32ValueType
+{
+    fixed32 v;
+    Q_GADGET
+public:
+    Q_INVOKABLE QString toString() const;
+};
+
+}