[Code Style] Use prototypes in telemetry bundle

WTD-1482
This commit is contained in:
Victor Woeltjen 2015-08-14 16:47:20 -07:00
parent 1ea6f7620e
commit 2ccca016a5
9 changed files with 443 additions and 461 deletions

View File

@ -42,154 +42,147 @@ define(
* at the specific data which is appropriate to the domain object.)
*
* @memberof platform/telemetry
* @implements {Capability}
* @constructor
*/
function TelemetryCapability($injector, $q, $log, domainObject) {
var telemetryService,
subscriptions = [],
unsubscribeFunction;
// We could depend on telemetryService directly, but
// there isn't a platform implementation of this;
function getTelemetryService() {
if (telemetryService === undefined) {
try {
telemetryService =
$injector.get("telemetryService");
} catch (e) {
// $injector should throw if telemetryService
// is unavailable or unsatisfiable.
$log.warn("Telemetry service unavailable");
telemetryService = null;
}
// there isn't a platform implementation of this.
this.initializeTelemetryService = function () {
try {
return (this.telemetryService =
$injector.get("telemetryService"));
} catch (e) {
// $injector should throw if telemetryService
// is unavailable or unsatisfiable.
$log.warn("Telemetry service unavailable");
return (this.telemetryService = null);
}
return telemetryService;
}
// Build a request object. This takes the request that was
// passed to the capability, and adds source, id, and key
// fields associated with the object (from its type definition
// and/or its model)
function buildRequest(request) {
// Start with any "telemetry" field in type; use that as a
// basis for the request.
var type = domainObject.getCapability("type"),
typeRequest = (type && type.getDefinition().telemetry) || {},
modelTelemetry = domainObject.getModel().telemetry,
fullRequest = Object.create(typeRequest);
// Add properties from the telemetry field of this
// specific domain object.
Object.keys(modelTelemetry).forEach(function (k) {
fullRequest[k] = modelTelemetry[k];
});
// Add properties from this specific requestData call.
Object.keys(request).forEach(function (k) {
fullRequest[k] = request[k];
});
// Ensure an ID and key are present
if (!fullRequest.id) {
fullRequest.id = domainObject.getId();
}
if (!fullRequest.key) {
fullRequest.key = domainObject.getId();
}
return fullRequest;
}
// Issue a request for telemetry data
function requestTelemetry(request) {
// Bring in any defaults from the object model
var fullRequest = buildRequest(request || {}),
source = fullRequest.source,
key = fullRequest.key;
// Pull out the relevant field from the larger,
// structured response.
function getRelevantResponse(response) {
return ((response || {})[source] || {})[key] ||
EMPTY_SERIES;
}
// Issue a request to the service
function requestTelemetryFromService() {
return telemetryService.requestTelemetry([fullRequest]);
}
// If a telemetryService is not available,
// getTelemetryService() should reject, and this should
// bubble through subsequent then calls.
return getTelemetryService() &&
requestTelemetryFromService()
.then(getRelevantResponse);
}
// Listen for real-time and/or streaming updates
function subscribe(callback, request) {
var fullRequest = buildRequest(request || {});
// Unpack the relevant telemetry series
function update(telemetries) {
var source = fullRequest.source,
key = fullRequest.key,
result = ((telemetries || {})[source] || {})[key];
if (result) {
callback(result);
}
}
return getTelemetryService() &&
telemetryService.subscribe(update, [fullRequest]);
}
return {
/**
* Request telemetry data for this specific domain object.
* @param {TelemetryRequest} [request] parameters for this
* specific request
* @returns {Promise} a promise for the resulting telemetry
* object
* @memberof platform/telemetry.TelemetryCapability#
*/
requestData: requestTelemetry,
/**
* Get metadata about this domain object's associated
* telemetry.
* @memberof platform/telemetry.TelemetryCapability#
*/
getMetadata: function () {
// metadata just looks like a request,
// so use buildRequest to bring in both
// type-level and object-level telemetry
// properties
return buildRequest({});
},
/**
* Subscribe to updates to telemetry data for this domain
* object.
* @param {Function} callback a function to call when new
* data becomes available; the telemetry series
* containing the data will be given as an argument.
* @param {TelemetryRequest} [request] parameters for the
* subscription request
* @memberof platform/telemetry.TelemetryCapability#
*/
subscribe: subscribe
};
this.$q = $q;
this.$log = $log;
this.domainObject = domainObject;
}
// Build a request object. This takes the request that was
// passed to the capability, and adds source, id, and key
// fields associated with the object (from its type definition
// and/or its model)
TelemetryCapability.prototype.buildRequest = function (request) {
// Start with any "telemetry" field in type; use that as a
// basis for the request.
var domainObject = this.domainObject,
type = domainObject.getCapability("type"),
typeRequest = (type && type.getDefinition().telemetry) || {},
modelTelemetry = domainObject.getModel().telemetry,
fullRequest = Object.create(typeRequest);
// Add properties from the telemetry field of this
// specific domain object.
Object.keys(modelTelemetry).forEach(function (k) {
fullRequest[k] = modelTelemetry[k];
});
// Add properties from this specific requestData call.
Object.keys(request).forEach(function (k) {
fullRequest[k] = request[k];
});
// Ensure an ID and key are present
if (!fullRequest.id) {
fullRequest.id = domainObject.getId();
}
if (!fullRequest.key) {
fullRequest.key = domainObject.getId();
}
return fullRequest;
};
/**
* Request telemetry data for this specific domain object.
* @param {TelemetryRequest} [request] parameters for this
* specific request
* @returns {Promise} a promise for the resulting telemetry
* object
*/
TelemetryCapability.prototype.requestData = function requestTelemetry(request) {
// Bring in any defaults from the object model
var fullRequest = this.buildRequest(request || {}),
source = fullRequest.source,
key = fullRequest.key,
telemetryService = this.telemetryService ||
this.initializeTelemetryService(); // Lazy initialization
// Pull out the relevant field from the larger,
// structured response.
function getRelevantResponse(response) {
return ((response || {})[source] || {})[key] ||
EMPTY_SERIES;
}
// Issue a request to the service
function requestTelemetryFromService() {
return telemetryService.requestTelemetry([fullRequest]);
}
// If a telemetryService is not available,
// getTelemetryService() should reject, and this should
// bubble through subsequent then calls.
return telemetryService &&
requestTelemetryFromService().then(getRelevantResponse);
};
/**
* Get metadata about this domain object's associated
* telemetry.
* @returns {TelemetryMetadata} metadata about this object's telemetry
*/
TelemetryCapability.prototype.getMetadata = function () {
// metadata just looks like a request,
// so use buildRequest to bring in both
// type-level and object-level telemetry
// properties
return (this.metadata = this.metadata || this.buildRequest({}));
};
/**
* Subscribe to updates to telemetry data for this domain
* object.
* @param {Function} callback a function to call when new
* data becomes available; the telemetry series
* containing the data will be given as an argument.
* @param {TelemetryRequest} [request] parameters for the
* subscription request
*/
TelemetryCapability.prototype.subscribe = function subscribe(callback, request) {
var fullRequest = this.buildRequest(request || {}),
telemetryService = this.telemetryService ||
this.initializeTelemetryService(); // Lazy initialization
// Unpack the relevant telemetry series
function update(telemetries) {
var source = fullRequest.source,
key = fullRequest.key,
result = ((telemetries || {})[source] || {})[key];
if (result) {
callback(result);
}
}
return telemetryService &&
telemetryService.subscribe(update, [fullRequest]);
};
/**
* The telemetry capability is applicable when a
* domain object model has a "telemetry" field.
*/
TelemetryCapability.appliesTo = function (model) {
return (model &&
model.telemetry) ? true : false;
return (model && model.telemetry) ? true : false;
};
return TelemetryCapability;

View File

@ -36,6 +36,7 @@ define(
*
* @memberof platform/telemetry
* @constructor
* @deprecated use platform/telemetry.TelemetryHandler instead
*/
function TelemetryController($scope, $q, $timeout, $log) {

View File

@ -33,37 +33,40 @@ define(
* @memberof platform/telemetry
*/
function TelemetryDelegator($q) {
return {
/**
* Promise telemetry-providing objects associated with
* this domain object (either the domain object itself,
* or the objects it delegates)
* @returns {Promise.<DomainObject[]>} domain objects with
* a telemetry capability
* @memberof platform/telemetry.TelemetryDelegator#
*/
promiseTelemetryObjects: function (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);
});
}
};
this.$q = $q;
}
/**
* Promise telemetry-providing objects associated with
* this domain object (either the domain object itself,
* or the objects it delegates)
* @param {DomainObject} the domain object which may have
* or delegate telemetry
* @returns {Promise.<DomainObject[]>} domain objects with
* a telemetry capability
*/
TelemetryDelegator.prototype.promiseTelemetryObjects = function (domainObject) {
var $q = this.$q;
// 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);
});
};
return TelemetryDelegator;
}
);

View File

@ -39,41 +39,35 @@ define(
* @constructor
*/
function TelemetryFormatter() {
function formatDomainValue(v, key) {
return isNaN(v) ? "" : moment.utc(v).format(DATE_FORMAT);
}
function formatRangeValue(v, key) {
return isNaN(v) ? v : v.toFixed(3);
}
return {
/**
* Format a domain value.
* @param {number} v the domain value; a timestamp
* in milliseconds since start of 1970
* @param {string} [key] the key which identifies the
* domain; if unspecified or unknown, this will
* be treated as a standard timestamp.
* @returns {string} a textual representation of the
* data and time, suitable for display.
* @memberof platform/telemetry.TelemetryFormatter#
*/
formatDomainValue: formatDomainValue,
/**
* Format a range value.
* @param {number} v the range value; a numeric value
* @param {string} [key] the key which identifies the
* range; if unspecified or unknown, this will
* be treated as a numeric value.
* @returns {string} a textual representation of the
* value, suitable for display.
* @memberof platform/telemetry.TelemetryFormatter#
*/
formatRangeValue: formatRangeValue
};
}
/**
* Format a domain value.
* @param {number} v the domain value; a timestamp
* in milliseconds since start of 1970
* @param {string} [key] the key which identifies the
* domain; if unspecified or unknown, this will
* be treated as a standard timestamp.
* @returns {string} a textual representation of the
* data and time, suitable for display.
*/
TelemetryFormatter.prototype.formatDomainValue = function (v, key) {
return isNaN(v) ? "" : moment.utc(v).format(DATE_FORMAT);
};
/**
* Format a range value.
* @param {number} v the range value; a numeric value
* @param {string} [key] the key which identifies the
* range; if unspecified or unknown, this will
* be treated as a numeric value.
* @returns {string} a textual representation of the
* value, suitable for display.
*/
TelemetryFormatter.prototype.formatRangeValue = function (v, key) {
return isNaN(v) ? String(v) : v.toFixed(VALUE_FORMAT_DIGITS);
};
return TelemetryFormatter;
}
);

View File

@ -36,19 +36,31 @@ define(
* @param $q Angular's $q
*/
function TelemetryHandler($q, telemetrySubscriber) {
return {
handle: function (domainObject, callback, lossless) {
var subscription = telemetrySubscriber.subscribe(
domainObject,
callback,
lossless
);
return new TelemetryHandle($q, subscription);
}
};
this.$q = $q;
this.telemetrySubscriber = telemetrySubscriber;
}
/**
* Start receiving telemetry associated with this domain object
* (either directly, or via delegation.)
* @param {DomainObject} domainObject the domain object
* @param {Function} callback callback to invoke when new data is
* available
* @param {boolean} lossless true if the callback should be invoked
* one separate time for each new latest value
* @returns {TelemetryHandle} a handle to telemetry data
* associated with this object
*/
TelemetryHandler.prototype.handle = function (domainObject, callback, lossless) {
var subscription = this.telemetrySubscriber.subscribe(
domainObject,
callback,
lossless
);
return new TelemetryHandle(this.$q, subscription);
};
return TelemetryHandler;
}

View File

@ -34,6 +34,7 @@ define(
* objects.)
* @memberof platform/telemetry
* @constructor
* @implements {platform/telemetry.TelemetryPool}
*/
function TelemetryQueue() {
// General approach here:
@ -60,9 +61,37 @@ define(
// 0 1 2 3 4
// a * * * * *
// b * * *
// c * * *
var queue = [],
counts = {};
// c * * *
this.queue = [];
this.counts = {};
}
TelemetryQueue.prototype.isEmpty = function () {
return this.queue.length < 1;
};
TelemetryQueue.prototype.poll = function () {
var counts = this.counts;
// Decrement counts for a specific key
function decrementCount(key) {
if (counts[key] < 2) {
delete counts[key];
} else {
counts[key] -= 1;
}
}
// Decrement counts for the object that will be popped
Object.keys(counts).forEach(decrementCount);
return this.queue.shift();
};
TelemetryQueue.prototype.put = function (key, value) {
var queue = this.queue,
counts = this.counts;
// Look up an object in the queue that does not have a value
// assigned to this key (or, add a new one)
@ -71,7 +100,7 @@ define(
// Track the largest free position for this key
counts[key] = index + 1;
// If it's before the end of the queue, add it there
if (index < queue.length) {
return queue[index];
@ -84,54 +113,9 @@ define(
queue.push(object);
return object;
}
// Decrement counts for a specific key
function decrementCount(key) {
if (counts[key] < 2) {
delete counts[key];
} else {
counts[key] -= 1;
}
}
// Decrement all counts
function decrementCounts() {
Object.keys(counts).forEach(decrementCount);
}
return {
/**
* Check if any value groups remain in this pool.
* @return {boolean} true if value groups remain
* @memberof platform/telemetry.TelemetryQueue#
*/
isEmpty: function () {
return queue.length < 1;
},
/**
* Retrieve the next value group from this pool.
* This gives an object containing key-value pairs,
* where keys and values correspond to the arguments
* given to previous put functions.
* @return {object} key-value pairs
* @memberof platform/telemetry.TelemetryQueue#
*/
poll: function () {
// Decrement counts for the object that will be popped
decrementCounts();
return queue.shift();
},
/**
* Put a key-value pair into the pool.
* @param {string} key the key to store the value under
* @param {*} value the value to store
* @memberof platform/telemetry.TelemetryQueue#
*/
put: function (key, value) {
getFreeObject(key)[key] = value;
}
};
}
getFreeObject(key)[key] = value;
};
return TelemetryQueue;
}

View File

@ -44,39 +44,36 @@ define(
* @param $timeout Angular's $timeout
*/
function TelemetrySubscriber($q, $timeout) {
return {
/**
* Subscribe to streaming telemetry updates
* associated with this domain object (either
* directly or via capability delegation.)
*
* @param {DomainObject} domainObject the object whose
* associated telemetry data is of interest
* @param {Function} callback a function to invoke
* when new data has become available.
* @param {boolean} lossless flag to indicate whether the
* callback should be notified for all values
* (otherwise, multiple values in quick succession
* will call back with only the latest value.)
* @returns {TelemetrySubscription} the subscription,
* which will provide access to latest values.
*
* @method
* @memberof TelemetrySubscriber
* @memberof platform/telemetry.TelemetrySubscriber#
*/
subscribe: function (domainObject, callback, lossless) {
return new TelemetrySubscription(
$q,
$timeout,
domainObject,
callback,
lossless
);
}
};
this.$q = $q;
this.$timeout = $timeout;
}
/**
* Subscribe to streaming telemetry updates
* associated with this domain object (either
* directly or via capability delegation.)
*
* @param {DomainObject} domainObject the object whose
* associated telemetry data is of interest
* @param {Function} callback a function to invoke
* when new data has become available.
* @param {boolean} lossless flag to indicate whether the
* callback should be notified for all values
* (otherwise, multiple values in quick succession
* will call back with only the latest value.)
* @returns {platform/telemetry.TelemetrySubscription} the
* subscription, which will provide access to latest values.
*/
TelemetrySubscriber.prototype.subscribe = function (domainObject, callback, lossless) {
return new TelemetrySubscription(
this.$q,
this.$timeout,
domainObject,
callback,
lossless
);
};
return TelemetrySubscriber;
}
);

View File

@ -26,6 +26,32 @@ define(
function (TelemetryQueue, TelemetryTable, TelemetryDelegator) {
"use strict";
/**
* A pool of telemetry values.
* @interface platform/telemetry.TelemetryPool
* @private
*/
/**
* Check if any value groups remain in this pool.
* @return {boolean} true if value groups remain
* @method platform/telemetry.TelemetryPool#isEmpty
*/
/**
* Retrieve the next value group from this pool.
* This gives an object containing key-value pairs,
* where keys and values correspond to the arguments
* given to previous put functions.
* @return {object} key-value pairs
* @method platform/telemetry.TelemetryPool#poll
*/
/**
* Put a key-value pair into the pool.
* @param {string} key the key to store the value under
* @param {*} value the value to store
* @method platform/telemetry.TelemetryPool#put
*/
/**
* A TelemetrySubscription tracks latest values for streaming
* telemetry data and handles notifying interested observers.
@ -52,14 +78,9 @@ define(
* the callback once, with access to the latest data
*/
function TelemetrySubscription($q, $timeout, domainObject, callback, lossless) {
var delegator = new TelemetryDelegator($q),
unsubscribePromise,
telemetryObjectPromise,
latestValues = {},
telemetryObjects = [],
var self = this,
delegator = new TelemetryDelegator($q),
pool = lossless ? new TelemetryQueue() : new TelemetryTable(),
metadatas,
unlistenToMutation,
updatePending;
// Look up domain objects which have telemetry capabilities.
@ -72,7 +93,7 @@ define(
function updateValuesFromPool() {
var values = pool.poll();
Object.keys(values).forEach(function (k) {
latestValues[k] = values[k];
self.latestValues[k] = values[k];
});
}
@ -165,8 +186,8 @@ define(
// initial subscription chain; this allows `getTelemetryObjects()`
// to return a non-Promise to simplify usage elsewhere.
function cacheObjectReferences(objects) {
telemetryObjects = objects;
metadatas = objects.map(lookupMetadata);
self.telemetryObjects = objects;
self.metadatas = objects.map(lookupMetadata);
// Fire callback, as this will be the first time that
// telemetry objects are available, or these objects
// will have changed.
@ -176,14 +197,6 @@ define(
return objects;
}
function unsubscribeAll() {
return unsubscribePromise.then(function (unsubscribes) {
return $q.all(unsubscribes.map(function (unsubscribe) {
return unsubscribe();
}));
});
}
function initialize() {
// Get a reference to relevant objects (those with telemetry
// capabilities) and subscribe to their telemetry updates.
@ -191,23 +204,23 @@ define(
// will be unsubscribe functions. (This must be a promise
// because delegation is supported, and retrieving delegate
// telemetry-capable objects may be an asynchronous operation.)
telemetryObjectPromise = promiseRelevantObjects(domainObject);
unsubscribePromise = telemetryObjectPromise
self.telemetryObjectPromise = promiseRelevantObjects(domainObject);
self.unsubscribePromise = self.telemetryObjectPromise
.then(cacheObjectReferences)
.then(subscribeAll);
}
function idsMatch(ids) {
return ids.length === telemetryObjects.length &&
return ids.length === self.telemetryObjects.length &&
ids.every(function (id, index) {
return telemetryObjects[index].getId() === id;
return self.telemetryObjects[index].getId() === id;
});
}
function modelChange(model) {
if (!idsMatch((model || {}).composition || [])) {
// Reinitialize if composition has changed
unsubscribeAll().then(initialize);
self.unsubscribeAll().then(initialize);
}
}
@ -219,122 +232,126 @@ define(
}
}
initialize();
unlistenToMutation = addMutationListener();
this.$q = $q;
this.latestValues = {};
this.telemetryObjects = [];
this.metadatas = [];
return {
/**
* Terminate all underlying subscriptions associated
* with this object.
* @method
* @memberof TelemetrySubscription
* @memberof platform/telemetry.TelemetrySubscription#
*/
unsubscribe: function () {
if (unlistenToMutation) {
unlistenToMutation();
}
return unsubscribeAll();
},
/**
* Get the most recent domain value that has been observed
* for the specified domain object. This will typically be
* a timestamp.
*
* The domain object passed here should be one that is
* subscribed-to here; that is, it should be one of the
* domain objects returned by `getTelemetryObjects()`.
*
* @param {DomainObject} domainObject the object of interest
* @returns the most recent domain value observed
* @method
* @memberof TelemetrySubscription
* @memberof platform/telemetry.TelemetrySubscription#
*/
getDomainValue: function (domainObject) {
var id = domainObject.getId();
return (latestValues[id] || {}).domain;
},
/**
* Get the most recent range value that has been observed
* for the specified domain object. This will typically
* be a numeric measurement.
*
* The domain object passed here should be one that is
* subscribed-to here; that is, it should be one of the
* domain objects returned by `getTelemetryObjects()`.
*
* @param {DomainObject} domainObject the object of interest
* @returns the most recent range value observed
* @method
* @memberof TelemetrySubscription
* @memberof platform/telemetry.TelemetrySubscription#
*/
getRangeValue: function (domainObject) {
var id = domainObject.getId();
return (latestValues[id] || {}).range;
},
/**
* Get the latest telemetry datum for this domain object.
*
* @param {DomainObject} domainObject the object of interest
* @returns {TelemetryDatum} the most recent datum
* @memberof platform/telemetry.TelemetrySubscription#
*/
getDatum: function (domainObject) {
var id = domainObject.getId();
return (latestValues[id] || {}).datum;
},
/**
* Get all telemetry-providing domain objects which are
* being observed as part of this subscription.
*
* Capability delegation will be taken into account (so, if
* a Telemetry Panel was passed in the constructor, this will
* return its contents.) Capability delegation is resolved
* asynchronously so the return value here may change over
* time; while this resolution is pending, this method will
* return an empty array.
*
* @returns {DomainObject[]} all subscribed-to domain objects
* @method
* @memberof TelemetrySubscription
* @memberof platform/telemetry.TelemetrySubscription#
*/
getTelemetryObjects: function () {
return telemetryObjects;
},
/**
* Get all telemetry metadata associated with
* telemetry-providing domain objects managed by
* this controller.
*
* This will ordered in the
* same manner as `getTelemetryObjects()` or
* `getResponse()`; that is, the metadata at a
* given index will correspond to the telemetry-providing
* domain object at the same index.
* @returns {Array} an array of metadata objects
* @memberof platform/telemetry.TelemetrySubscription#
*/
getMetadata: function () {
return metadatas;
},
/**
* Get a promise for all telemetry-providing objects
* associated with this subscription.
* @returns {Promise.<DomainObject[]>} a promise for
* telemetry-providing objects
* @memberof platform/telemetry.TelemetrySubscription#
*/
promiseTelemetryObjects: function () {
// Unsubscribe promise is available after objects
// are loaded.
return telemetryObjectPromise;
}
};
initialize();
this.unlistenToMutation = addMutationListener();
}
TelemetrySubscription.prototype.unsubscribeAll = function () {
var $q = this.$q;
return this.unsubscribePromise.then(function (unsubscribes) {
return $q.all(unsubscribes.map(function (unsubscribe) {
return unsubscribe();
}));
});
};
/**
* Terminate all underlying subscriptions associated
* with this object.
*/
TelemetrySubscription.prototype.unsubscribe = function () {
if (this.unlistenToMutation) {
this.unlistenToMutation();
}
return this.unsubscribeAll();
};
/**
* Get the most recent domain value that has been observed
* for the specified domain object. This will typically be
* a timestamp.
*
* The domain object passed here should be one that is
* subscribed-to here; that is, it should be one of the
* domain objects returned by `getTelemetryObjects()`.
*
* @param {DomainObject} domainObject the object of interest
* @returns the most recent domain value observed
*/
TelemetrySubscription.prototype.getDomainValue = function (domainObject) {
var id = domainObject.getId();
return (this.latestValues[id] || {}).domain;
};
/**
* Get the most recent range value that has been observed
* for the specified domain object. This will typically
* be a numeric measurement.
*
* The domain object passed here should be one that is
* subscribed-to here; that is, it should be one of the
* domain objects returned by `getTelemetryObjects()`.
*
* @param {DomainObject} domainObject the object of interest
* @returns the most recent range value observed
*/
TelemetrySubscription.prototype.getRangeValue = function (domainObject) {
var id = domainObject.getId();
return (this.latestValues[id] || {}).range;
};
/**
* Get the latest telemetry datum for this domain object.
*
* @param {DomainObject} domainObject the object of interest
* @returns {TelemetryDatum} the most recent datum
*/
TelemetrySubscription.prototype.getDatum = function (domainObject) {
var id = domainObject.getId();
return (this.latestValues[id] || {}).datum;
};
/**
* Get all telemetry-providing domain objects which are
* being observed as part of this subscription.
*
* Capability delegation will be taken into account (so, if
* a Telemetry Panel was passed in the constructor, this will
* return its contents.) Capability delegation is resolved
* asynchronously so the return value here may change over
* time; while this resolution is pending, this method will
* return an empty array.
*
* @returns {DomainObject[]} all subscribed-to domain objects
*/
TelemetrySubscription.prototype.getTelemetryObjects = function () {
return this.telemetryObjects;
};
/**
* Get all telemetry metadata associated with
* telemetry-providing domain objects managed by
* this controller.
*
* This will ordered in the
* same manner as `getTelemetryObjects()` or
* `getResponse()`; that is, the metadata at a
* given index will correspond to the telemetry-providing
* domain object at the same index.
* @returns {TelemetryMetadata[]} an array of metadata objects
*/
TelemetrySubscription.prototype.getMetadata = function () {
return this.metadatas;
};
/**
* Get a promise for all telemetry-providing objects
* associated with this subscription.
* @returns {Promise.<DomainObject[]>} a promise for
* telemetry-providing objects
* @memberof platform/telemetry.TelemetrySubscription#
*/
TelemetrySubscription.prototype.promiseTelemetryObjects = function () {
// Unsubscribe promise is available after objects
// are loaded.
return this.telemetryObjectPromise;
};
return TelemetrySubscription;
}

View File

@ -34,45 +34,26 @@ define(
* values.
* @memberof platform/telemetry
* @constructor
* @implements {platform/telemetry.TelemetryPool}
*/
function TelemetryTable() {
var table;
return {
/**
* Check if any value groups remain in this pool.
* @return {boolean} true if value groups remain
* @memberof platform/telemetry.TelemetryTable#
*/
isEmpty: function () {
return !table;
},
/**
* Retrieve the next value group from this pool.
* This gives an object containing key-value pairs,
* where keys and values correspond to the arguments
* given to previous put functions.
* @return {object} key-value pairs
* @memberof platform/telemetry.TelemetryTable#
*/
poll: function () {
var t = table;
table = undefined;
return t;
},
/**
* Put a key-value pair into the pool.
* @param {string} key the key to store the value under
* @param {*} value the value to store
* @memberof platform/telemetry.TelemetryTable#
*/
put: function (key, value) {
table = table || {};
table[key] = value;
}
};
}
TelemetryTable.prototype.isEmpty = function () {
return !this.table;
};
TelemetryTable.prototype.poll = function () {
var t = this.table;
this.table = undefined;
return t;
};
TelemetryTable.prototype.put = function (key, value) {
this.table = this.table || {};
this.table[key] = value;
};
return TelemetryTable;
}
);