From 34bb2ff51a1a7fa62774a4d9ff2a3f40b90485c6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 29 Dec 2014 13:57:20 -0800 Subject: [PATCH] [Telemetry] Add TelemetrySubscriber Add TelemetrySubscriber, a helper class to be used for supporting real-time telemetry. WTD-614. --- platform/telemetry/src/TelemetryAggregator.js | 3 +- platform/telemetry/src/TelemetrySubscriber.js | 107 ++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 platform/telemetry/src/TelemetrySubscriber.js diff --git a/platform/telemetry/src/TelemetryAggregator.js b/platform/telemetry/src/TelemetryAggregator.js index 45c3a5e036..ccd40c690c 100644 --- a/platform/telemetry/src/TelemetryAggregator.js +++ b/platform/telemetry/src/TelemetryAggregator.js @@ -64,7 +64,8 @@ define( * which may (or may not, depending on * availability) satisfy the requests */ - requestTelemetry: requestTelemetry + requestTelemetry: requestTelemetry, + subscribe: subscribe }; } diff --git a/platform/telemetry/src/TelemetrySubscriber.js b/platform/telemetry/src/TelemetrySubscriber.js new file mode 100644 index 0000000000..f078905df6 --- /dev/null +++ b/platform/telemetry/src/TelemetrySubscriber.js @@ -0,0 +1,107 @@ +/*global define*/ + +define( + [], + function () { + "use strict"; + + function TelemetrySubscriber($q, $timeout, domainObject, callback) { + var unsubscribePromise, + latestValues = {}, + telemetryObjects = [], + updatePending; + + // Look up domain objects which have telemetry capabilities. + // This will either be the object in view, or object that + // this object delegates its telemetry capability to. + function promiseRelevantObjects(domainObject) { + // If object has been cleared, there are no relevant + // telemetry-providing domain objects. + if (!domainObject) { + return $q.when([]); + } + + // Otherwise, try delegation first, and attach the + // object itself if it has a telemetry capability. + return $q.when(domainObject.useCapability( + "delegation", + "telemetry" + )).then(function (result) { + var head = domainObject.hasCapability("telemetry") ? + [ domainObject ] : [], + tail = result || []; + return head.concat(tail); + }); + } + + function fireCallback(values) { + callback(values); + updatePending = false; + } + + function update(domainObject, telemetry) { + var count = telemetry && telemetry.getPointCount(); + + if (!updatePending && count) { + updatePending = true; + $timeout(fireCallback, 0); + } + + if (count > 0) { + latestValues[domainObject.getId()] = { + domain: telemetry.getDomainValue(count - 1), + range: telemetry.getRangeValue(count - 1) + }; + } + } + + function subscribe(domainObject) { + var telemetryCapability = + domainObject.getCapability("telemetry"); + return telemetryCapability.subscribe(function (telemetry) { + update(domainObject, telemetry); + }); + } + + function subscribeAll(domainObjects) { + return domainObjects.map(subscribe); + } + + function cacheObjectReferences(objects) { + telemetryObjects = objects; + return objects; + } + + // Get a reference to relevant objects (those with telemetry + // capabilities) + unsubscribePromise = + promiseRelevantObjects(domainObject) + .then(cacheObjectReferences) + .then(subscribeAll); + + return { + unsubscribe: function () { + return unsubscribePromise.then(function (unsubscribes) { + return $q.all(unsubscribes.map(function (unsubscribe) { + return unsubscribe(); + })); + }); + }, + getDomainValue: function (domainObject) { + var id = domainObject.getId(); + return (latestValues[id] || {}).domain; + }, + getRangeValue: function (domainObject) { + var id = domainObject.getId(); + return (latestValues[id] || {}).range; + }, + getTelemetryObjects: function () { + return telemetryObjects; + } + }; + } + + return TelemetrySubscriber; + + } +); \ No newline at end of file