diff --git a/API.md b/API.md index f3717d95c3..3c4ef726c5 100644 --- a/API.md +++ b/API.md @@ -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 diff --git a/src/api/objects/LegacyObjectAPIInterceptor.js b/src/api/objects/LegacyObjectAPIInterceptor.js index 9eb996ea00..666dcfd5c0 100644 --- a/src/api/objects/LegacyObjectAPIInterceptor.js +++ b/src/api/objects/LegacyObjectAPIInterceptor.js @@ -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) { diff --git a/src/api/objects/MutableObject.js b/src/api/objects/MutableObject.js index 003bc2c5b9..1eb5fe4e0e 100644 --- a/src/api/objects/MutableObject.js +++ b/src/api/objects/MutableObject.js @@ -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; diff --git a/src/api/objects/ObjectAPI.js b/src/api/objects/ObjectAPI.js index 6fc9383a55..4d39b2bd5e 100644 --- a/src/api/objects/ObjectAPI.js +++ b/src/api/objects/ObjectAPI.js @@ -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); };