summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2013-11-20 14:13:39 +0100
committerMilian Wolff <milian.wolff@kdab.com>2013-12-05 15:52:07 +0100
commit4a0d66958ab8c3785d82086d63c8eb441c95b7f1 (patch)
treed04144352c22a6a3f7741fb4540ce22bd89790de /src
parentdf4e4df31e5f3b464c6d5777a2fb66237fb2525f (diff)
downloadqtwebchannel-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.qml44
-rw-r--r--src/qobject.js22
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
};
}