Merge pull request #1372 from nasa/api-review-followup-1122

[API] Address review followup items
This commit is contained in:
Andrew Henry 2017-01-18 21:42:22 -08:00 committed by GitHub
commit 7e8e861468
4 changed files with 65 additions and 26 deletions

29
API.md
View File

@ -129,8 +129,10 @@ provider.
The "composition" of a domain object is the list of objects it contains,
as shown (for example) in the tree for browsing. Open MCT provides a
default solution for composition, but there may be cases where you want
to provide the composition of a certain object (or type of object) dynamically.
[default solution](#default-composition-provider) for composition, but there
may be cases where you want to provide the composition of a certain object
(or type of object) dynamically.
For instance, you may want to populate a hierarchy under a custom root-level
object based on the contents of a telemetry dictionary.
To do this, you can add a new CompositionProvider:
@ -146,6 +148,29 @@ openmct.composition.addProvider({
});
```
#### Default Composition Provider
The default composition provider applies to any domain object with
a `composition` property. The value of `composition` should be an
array of identifiers, e.g.:
```js
var domainObject = {
name: "My Object",
type: 'folder',
composition: [
{
key: '412229c3-922c-444b-8624-736d85516247',
namespace: 'foo'
},
{
key: 'd6e0ce02-5b85-4e55-8006-a8a505b64c75',
namespace: 'foo'
}
]
};
```
### Adding Telemetry Providers
When connecting to a new telemetry source, you will want to register a new

View File

@ -21,13 +21,12 @@
*****************************************************************************/
define([
'./object-utils',
'./objectEventEmitter'
'./object-utils'
], function (
utils,
objectEventEmitter
utils
) {
function ObjectServiceProvider(objectService, instantiate, topic) {
function ObjectServiceProvider(eventEmitter, objectService, instantiate, topic) {
this.eventEmitter = eventEmitter;
this.objectService = objectService;
this.instantiate = instantiate;
@ -61,12 +60,12 @@ define([
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
//Don't trigger self
objectEventEmitter.off('mutation', handleMutation);
objectEventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
objectEventEmitter.on('mutation', handleMutation);
this.eventEmitter.off('mutation', handleMutation);
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
this.eventEmitter.on('mutation', handleMutation);
}.bind(this);
objectEventEmitter.on('mutation', handleMutation);
this.eventEmitter.on('mutation', handleMutation);
removeGeneralTopicListener = this.generalTopic.listen(handleLegacyMutation);
};
@ -96,6 +95,8 @@ define([
// Injects new object API as a decorator so that it hijacks all requests.
// Object providers implemented on new API should just work, old API should just work, many things may break.
function LegacyObjectAPIInterceptor(openmct, ROOTS, instantiate, topic, objectService) {
var eventEmitter = openmct.objects.eventEmitter;
this.getObjects = function (keys) {
var results = {},
promises = keys.map(function (keyString) {
@ -114,7 +115,12 @@ define([
};
openmct.objects.supersecretSetFallbackProvider(
new ObjectServiceProvider(objectService, instantiate, topic)
new ObjectServiceProvider(
eventEmitter,
objectService,
instantiate,
topic
)
);
ROOTS.forEach(function (r) {

View File

@ -21,11 +21,9 @@
*****************************************************************************/
define([
'lodash',
'./objectEventEmitter'
'lodash'
], function (
_,
objectEventEmitter
_
) {
var ANY_OBJECT_EVENT = "mutation";
@ -36,7 +34,8 @@ define([
* @param object
* @interface MutableObject
*/
function MutableObject(object) {
function MutableObject(eventEmitter, object) {
this.eventEmitter = eventEmitter;
this.object = object;
this.unlisteners = [];
}
@ -61,8 +60,11 @@ define([
*/
MutableObject.prototype.on = function (path, callback) {
var fullPath = qualifiedEventName(this.object, path);
objectEventEmitter.on(fullPath, callback);
this.unlisteners.push(objectEventEmitter.off.bind(objectEventEmitter, fullPath, callback));
var eventOff =
this.eventEmitter.off.bind(this.eventEmitter, fullPath, callback);
this.eventEmitter.on(fullPath, callback);
this.unlisteners.push(eventOff);
};
/**
@ -78,12 +80,12 @@ define([
_.set(this.object, 'modified', Date.now());
//Emit event specific to property
objectEventEmitter.emit(qualifiedEventName(this.object, path), value);
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
//Emit wildcare event
objectEventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
//Emit a general "any object" event
objectEventEmitter.emit(ANY_OBJECT_EVENT, this.object);
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
};
return MutableObject;

View File

@ -25,13 +25,15 @@ define([
'./object-utils',
'./MutableObject',
'./RootRegistry',
'./RootObjectProvider'
'./RootObjectProvider',
'EventEmitter'
], function (
_,
utils,
MutableObject,
RootRegistry,
RootObjectProvider
RootObjectProvider,
EventEmitter
) {
@ -42,6 +44,7 @@ define([
*/
function ObjectAPI() {
this.eventEmitter = new EventEmitter();
this.providers = {};
this.rootRegistry = new RootRegistry();
this.rootProvider = new RootObjectProvider(this.rootRegistry);
@ -175,7 +178,9 @@ define([
* @memberof module:openmct.ObjectAPI#
*/
ObjectAPI.prototype.mutate = function (domainObject, path, value) {
return new MutableObject(domainObject).set(path, value);
var mutableObject =
new MutableObject(this.eventEmitter, domainObject);
return mutableObject.set(path, value);
};
/**
@ -188,7 +193,8 @@ define([
* @memberof module:openmct.ObjectAPI#
*/
ObjectAPI.prototype.observe = function (domainObject, path, callback) {
var mutableObject = new MutableObject(domainObject);
var mutableObject =
new MutableObject(this.eventEmitter, domainObject);
mutableObject.on(path, callback);
return mutableObject.stopListening.bind(mutableObject);
};