diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/webchannel/doc/src/index.qdoc | 13 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher.cpp | 24 | ||||
-rw-r--r-- | src/webchannel/qmetaobjectpublisher_p.h | 9 | ||||
-rw-r--r-- | src/webchannel/qwebchannel.cpp | 5 |
4 files changed, 42 insertions, 9 deletions
diff --git a/src/webchannel/doc/src/index.qdoc b/src/webchannel/doc/src/index.qdoc index 43f4e6f..5529093 100644 --- a/src/webchannel/doc/src/index.qdoc +++ b/src/webchannel/doc/src/index.qdoc @@ -31,13 +31,12 @@ \title Qt WebChannel \brief Bridges the gap between Qt applications and HTML/JavaScript. - Qt WebChannel enables peer-to-peer communication between the server - (QML/C++ application) and the client (HTML/JavaScript or QML application). The - transport mechanism is supported out of the box by \l{Qt WebEngine}. It works on all - browsers that support \l{Qt WebSockets}, enabling Qt WebChannel applications - to run in any JavaScript runtime. Additionally, a custom transport - mechanism can also be implemented using Qt WebSockets to support Qt - WebChannel-based communication. + Qt WebChannel enables peer-to-peer communication between a server (QML/C++ + application) and a client (HTML/JavaScript or QML application). It is + supported out of the box by \l{Qt WebEngine}. In addition it can work on all + browsers that support \l{Qt WebSockets}{WebSockets}, enabling Qt WebChannel + clients to run in any JavaScript environment (including QML). This requires + the implementation of a custom transport based on Qt WebSockets. The module provides a JavaScript library for seamless integration of C++ and QML applications with HTML/JavaScript and QML clients. The clients must use the diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index e9d93ea..66676f0 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -495,6 +495,29 @@ QVariant QMetaObjectPublisher::toVariant(const QJsonValue &value, int targetType return variant; } +void QMetaObjectPublisher::transportRemoved(QWebChannelAbstractTransport *transport) +{ + auto it = transportedWrappedObjects.find(transport); + // It is not allowed to modify a container while iterating over it. So save + // objects which should be removed and call objectDestroyed() on them later. + QVector<QObject*> objectsForDeletion; + while (it != transportedWrappedObjects.end() && it.key() == transport) { + if (wrappedObjects.contains(it.value())) { + QVector<QWebChannelAbstractTransport*> &transports = wrappedObjects[it.value()].transports; + transports.removeOne(transport); + if (transports.isEmpty()) + objectsForDeletion.append(wrappedObjects[it.value()].object); + } + + it++; + } + + transportedWrappedObjects.remove(transport); + + foreach (QObject *obj, objectsForDeletion) + objectDestroyed(obj); +} + // NOTE: transport can be a nullptr // in such a case, we need to ensure that the property is registered to // the target transports of the parentObjectId @@ -526,6 +549,7 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA oi.transports = webChannel->d_func()->transports; } wrappedObjects.insert(id, oi); + transportedWrappedObjects.insert(transport, id); initializePropertyUpdates(object, classInfo); } else if (wrappedObjects.contains(id)) { diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h index 29956e0..830e510 100644 --- a/src/webchannel/qmetaobjectpublisher_p.h +++ b/src/webchannel/qmetaobjectpublisher_p.h @@ -94,7 +94,7 @@ public: virtual ~QMetaObjectPublisher(); /** - * Register @p object nuder the given @p id. + * Register @p object under the given @p id. * * The properties, signals and public methods of the QObject are * published to the remote client, where an object with the given identifier @@ -177,6 +177,11 @@ public: QVariant toVariant(const QJsonValue &value, int targetType) const; /** + * Remove wrapped objects which last transport relation is with the passed transport object. + */ + void transportRemoved(QWebChannelAbstractTransport *transport); + + /** * Given a QVariant containing a QObject*, wrap the object and register for property updates * return the objects class information. * @@ -257,6 +262,8 @@ private: // Map of objects wrapped from invocation returns QHash<QString, ObjectInfo> wrappedObjects; + // Map of transports to wrapped object ids + QMultiHash<QWebChannelAbstractTransport*, QString> transportedWrappedObjects; // Map of objects to maps of signal indices to a set of all their property indices. // The last value is a set as a signal can be the notify signal of multiple properties. diff --git a/src/webchannel/qwebchannel.cpp b/src/webchannel/qwebchannel.cpp index c2e0d19..0e9a4c5 100644 --- a/src/webchannel/qwebchannel.cpp +++ b/src/webchannel/qwebchannel.cpp @@ -81,9 +81,11 @@ QT_BEGIN_NAMESPACE */ void QWebChannelPrivate::_q_transportDestroyed(QObject *object) { - const int idx = transports.indexOf(static_cast<QWebChannelAbstractTransport*>(object)); + QWebChannelAbstractTransport *transport = static_cast<QWebChannelAbstractTransport*>(object); + const int idx = transports.indexOf(transport); if (idx != -1) { transports.remove(idx); + publisher->transportRemoved(transport); } } @@ -252,6 +254,7 @@ void QWebChannel::disconnectFrom(QWebChannelAbstractTransport *transport) disconnect(transport, 0, this, 0); disconnect(transport, 0, d->publisher, 0); d->transports.remove(idx); + d->publisher->transportRemoved(transport); } } |