diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2013-11-20 14:13:39 +0100 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2013-12-05 15:52:07 +0100 |
commit | 4a0d66958ab8c3785d82086d63c8eb441c95b7f1 (patch) | |
tree | d04144352c22a6a3f7741fb4540ce22bd89790de /src | |
parent | df4e4df31e5f3b464c6d5777a2fb66237fb2525f (diff) | |
download | qtwebchannel-4a0d66958ab8c3785d82086d63c8eb441c95b7f1.tar.gz |
Make it possible to disconnect from signals on the client side.
To do so, we need to remember the connected functor and pass that to
disconnect, in both the client side as well as the QML server side.
Change-Id: Ic61fc5d2a203212278c23471c216683e309e2c9f
Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/MetaObjectPublisher.qml | 44 | ||||
-rw-r--r-- | src/qobject.js | 22 |
2 files changed, 56 insertions, 10 deletions
diff --git a/src/MetaObjectPublisher.qml b/src/MetaObjectPublisher.qml index 1d8222c..5c3cfca 100644 --- a/src/MetaObjectPublisher.qml +++ b/src/MetaObjectPublisher.qml @@ -56,6 +56,11 @@ MetaObjectPublisherImpl * This map contains the registered objects indexed by their name. */ property variant registeredObjects: ({}) + /** + * Tracks how many connections are active to object signals. + * + * Maps objectName -> signalName -> {handler: functor, subscribers: int}. + */ property var subscriberCountMap: ({}) // Map of object names to maps of signal names to an array of all their properties. @@ -159,15 +164,20 @@ MetaObjectPublisherImpl // if no one is connected, connect. if (!subscriberCountMap[payload.object].hasOwnProperty(payload.signal)) { - object[payload.signal].connect(function() { - var args = convertQMLArgsToJSArgs(arguments); - webChannel.sendMessage("Qt.signal", { - object: payload.object, - signal: payload.signal, - args: args - }); - }); - subscriberCountMap[payload.object][payload.signal] = true; + subscriberCountMap[payload.object][payload.signal] = { + subscribers: 1, + handler: function() { + var args = convertQMLArgsToJSArgs(arguments); + webChannel.sendMessage("Qt.signal", { + object: payload.object, + signal: payload.signal, + args: args + }); + } + }; + object[payload.signal].connect(subscriberCountMap[payload.object][payload.signal].handler); + } else { + ++subscriberCountMap[payload.object][payload.signal].subscribers; } return true; } @@ -178,6 +188,22 @@ MetaObjectPublisherImpl } return false; } + if (payload.type === "Qt.disconnectFromSignal") { + if (!object.hasOwnProperty(payload.signal)) { + return false; + } + subscriberCountMap = subscriberCountMap || {}; + subscriberCountMap[payload.object] = subscriberCountMap[payload.object] || {}; + + if (!subscriberCountMap[payload.object].hasOwnProperty(payload.signal)) { + return false + } + if (--subscriberCountMap[payload.object][payload.signal].subscribers === 0) { + object[payload.signal].disconnect(subscriberCountMap[payload.object][payload.signal].handler); + delete subscriberCountMap[payload.object][payload.signal]; + } + return true; + } if (payload.type === "Qt.setProperty") { object[payload.property] = payload.value; return true; diff --git a/src/qobject.js b/src/qobject.js index 048295c..e6513d5 100644 --- a/src/qobject.js +++ b/src/qobject.js @@ -102,8 +102,28 @@ function QObject(name, data, webChannel) signal: signal }); } + }, + disconnect: function(callback) { + if (typeof(callback) !== "function") { + console.error("Bad callback given to disconnect from signal " + signal); + return; + } + object.__objectSignals__[signal] = object.__objectSignals__[signal] || []; + var idx = object.__objectSignals__[signal].indexOf(callback); + if (idx === -1) { + console.error("Cannot find connection for given callback to signal" + signal, callback); + return; + } + object.__objectSignals__[signal].splice(idx, 1); + if (!isPropertyNotifySignal && object.__objectSignals__[signal].length === 0) { + // only required for "pure" signals, handled separately for properties in propertyUpdate + webChannel.exec({ + type: "Qt.disconnectFromSignal", + object: object.__id__, + signal: signal + }); + } } - // TODO: disconnect eventually }; } |