mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 18:50:11 +00:00
Compare commits
1 Commits
docs-relea
...
refactor-c
Author | SHA1 | Date | |
---|---|---|---|
d16c60aa7a |
@ -20,6 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import EventEmitter from 'EventEmitter';
|
||||
/**
|
||||
* @typedef {import('../objects/ObjectAPI').DomainObject} DomainObject
|
||||
*/
|
||||
@ -60,6 +61,10 @@ export default class CompositionCollection {
|
||||
#publicAPI;
|
||||
#listeners;
|
||||
#mutables;
|
||||
#onGlobalAdd;
|
||||
#onGlobalRemove;
|
||||
static #globalEvents = new EventEmitter();
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {DomainObject} domainObject the domain object
|
||||
@ -95,6 +100,21 @@ export default class CompositionCollection {
|
||||
unobserve();
|
||||
});
|
||||
}
|
||||
|
||||
const keyString = publicAPI.objects.makeKeyString(domainObject.identifier);
|
||||
this.#onGlobalAdd = this._onGlobalAdd.bind(this);
|
||||
this.#onGlobalRemove = this._onGlobalRemove.bind(this);
|
||||
|
||||
CompositionCollection.#globalEvents.on(`add:${keyString}`, this.#onGlobalAdd);
|
||||
CompositionCollection.#globalEvents.on(`remove:${keyString}`, this.#onGlobalRemove);
|
||||
}
|
||||
|
||||
_onGlobalAdd(object) {
|
||||
this.#emit('add', object);
|
||||
}
|
||||
|
||||
_onGlobalRemove(identifier) {
|
||||
this.#emit('remove', identifier);
|
||||
}
|
||||
/**
|
||||
* Listen for changes to this composition. Supports 'add', 'remove', and
|
||||
@ -209,23 +229,21 @@ export default class CompositionCollection {
|
||||
* **Intended for internal use ONLY.**
|
||||
* true if the underlying provider should not be updated.
|
||||
*/
|
||||
add(child, skipMutate) {
|
||||
if (!skipMutate) {
|
||||
if (!this.#publicAPI.composition.checkPolicy(this.domainObject, child)) {
|
||||
throw `Object of type ${child.type} cannot be added to object of type ${this.domainObject.type}`;
|
||||
}
|
||||
|
||||
this.#provider.add(this.domainObject, child.identifier);
|
||||
} else {
|
||||
if (this.returnMutables && this.#publicAPI.objects.supportsMutation(child.identifier)) {
|
||||
let keyString = this.#publicAPI.objects.makeKeyString(child.identifier);
|
||||
|
||||
child = this.#publicAPI.objects.toMutable(child);
|
||||
this.#mutables[keyString] = child;
|
||||
}
|
||||
|
||||
this.#emit('add', child);
|
||||
add(child) {
|
||||
if (!this.#publicAPI.composition.checkPolicy(this.domainObject, child)) {
|
||||
throw `Object of type ${child.type} cannot be added to object of type ${this.domainObject.type}`;
|
||||
}
|
||||
|
||||
this.#provider.add(this.domainObject, child.identifier);
|
||||
if (this.returnMutables && this.#publicAPI.objects.supportsMutation(child.identifier)) {
|
||||
let keyString = this.#publicAPI.objects.makeKeyString(child.identifier);
|
||||
|
||||
child = this.#publicAPI.objects.toMutable(child);
|
||||
this.#mutables[keyString] = child;
|
||||
}
|
||||
|
||||
// const keyString = this.#publicAPI.objects.makeKeyString(this.domainObject.identifier);
|
||||
// CompositionCollection.#globalEvents.emit(`add:${keyString}`, child);
|
||||
}
|
||||
/**
|
||||
* Load the domain objects in this composition.
|
||||
@ -240,7 +258,12 @@ export default class CompositionCollection {
|
||||
this.#cleanUpMutables();
|
||||
const children = await this.#provider.load(this.domainObject);
|
||||
const childObjects = await Promise.all(children.map((c) => this.#publicAPI.objects.get(c, abortSignal)));
|
||||
childObjects.forEach(c => this.add(c, true));
|
||||
childObjects.forEach(c => {
|
||||
this.add(c);
|
||||
|
||||
const keyString = this.#publicAPI.objects.makeKeyString(this.domainObject.identifier);
|
||||
CompositionCollection.#globalEvents.emit(`add:${keyString}`, c);
|
||||
});
|
||||
this.#emit('load');
|
||||
|
||||
return childObjects;
|
||||
@ -259,20 +282,18 @@ export default class CompositionCollection {
|
||||
* true if the underlying provider should not be updated.
|
||||
* @name remove
|
||||
*/
|
||||
remove(child, skipMutate) {
|
||||
if (!skipMutate) {
|
||||
this.#provider.remove(this.domainObject, child.identifier);
|
||||
} else {
|
||||
if (this.returnMutables) {
|
||||
let keyString = this.#publicAPI.objects.makeKeyString(child);
|
||||
if (this.#mutables[keyString] !== undefined && this.#mutables[keyString].isMutable) {
|
||||
this.#publicAPI.objects.destroyMutable(this.#mutables[keyString]);
|
||||
delete this.#mutables[keyString];
|
||||
}
|
||||
remove(child) {
|
||||
this.#provider.remove(this.domainObject, child.identifier);
|
||||
if (this.returnMutables) {
|
||||
let keyString = this.#publicAPI.objects.makeKeyString(child);
|
||||
if (this.#mutables[keyString] !== undefined && this.#mutables[keyString].isMutable) {
|
||||
this.#publicAPI.objects.destroyMutable(this.#mutables[keyString]);
|
||||
delete this.#mutables[keyString];
|
||||
}
|
||||
|
||||
this.#emit('remove', child);
|
||||
}
|
||||
|
||||
// const keyString = this.#publicAPI.objects.makeKeyString(this.domainObject.identifier);
|
||||
// CompositionCollection.#globalEvents.emit(`remove:${keyString}`, child.identifier);
|
||||
}
|
||||
/**
|
||||
* Reorder the domain objects in this composition.
|
||||
@ -295,6 +316,10 @@ export default class CompositionCollection {
|
||||
this.mutationListener();
|
||||
delete this.mutationListener;
|
||||
}
|
||||
|
||||
const keyString = this.#publicAPI.objects.makeKeyString(this.domainObject.identifier);
|
||||
CompositionCollection.#globalEvents.off(`add:${keyString}`, this.#onGlobalAdd);
|
||||
CompositionCollection.#globalEvents.off(`remove:${keyString}`, this.#onGlobalRemove);
|
||||
}
|
||||
/**
|
||||
* Handle reorder from provider.
|
||||
|
@ -71,10 +71,6 @@ export default class CompositionProvider {
|
||||
return this.#listeningTo;
|
||||
}
|
||||
|
||||
get establishTopicListener() {
|
||||
return this.#establishTopicListener.bind(this);
|
||||
}
|
||||
|
||||
get publicAPI() {
|
||||
return this.#publicAPI;
|
||||
}
|
||||
@ -181,22 +177,6 @@ export default class CompositionProvider {
|
||||
throw new Error("This method must be implemented by a subclass.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens on general mutation topic, using injector to fetch to avoid
|
||||
* circular dependencies.
|
||||
* @private
|
||||
*/
|
||||
#establishTopicListener() {
|
||||
if (this.topicListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.#publicAPI.objects.eventEmitter.on('mutation', this.#onMutation.bind(this));
|
||||
this.topicListener = () => {
|
||||
this.#publicAPI.objects.eventEmitter.off('mutation', this.#onMutation.bind(this));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {DomainObject} parent
|
||||
@ -216,47 +196,5 @@ export default class CompositionProvider {
|
||||
#supportsComposition(parent, _child) {
|
||||
return this.#publicAPI.composition.supportsComposition(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles mutation events. If there are active listeners for the mutated
|
||||
* object, detects changes to composition and triggers necessary events.
|
||||
*
|
||||
* @private
|
||||
* @param {DomainObject} oldDomainObject
|
||||
*/
|
||||
#onMutation(oldDomainObject) {
|
||||
const id = objectUtils.makeKeyString(oldDomainObject.identifier);
|
||||
const listeners = this.#listeningTo[id];
|
||||
|
||||
if (!listeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldComposition = listeners.composition.map(objectUtils.makeKeyString);
|
||||
const newComposition = oldDomainObject.composition.map(objectUtils.makeKeyString);
|
||||
|
||||
const added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
|
||||
const removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);
|
||||
|
||||
function notify(value) {
|
||||
return function (listener) {
|
||||
if (listener.context) {
|
||||
listener.callback.call(listener.context, value);
|
||||
} else {
|
||||
listener.callback(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
listeners.composition = newComposition.map(objectUtils.parseKeyString);
|
||||
|
||||
added.forEach(function (addedChild) {
|
||||
listeners.add.forEach(notify(addedChild));
|
||||
});
|
||||
|
||||
removed.forEach(function (removedChild) {
|
||||
listeners.remove.forEach(notify(removedChild));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ export default class DefaultCompositionProvider extends CompositionProvider {
|
||||
event,
|
||||
callback,
|
||||
context) {
|
||||
this.establishTopicListener();
|
||||
//this.establishTopicListener();
|
||||
|
||||
/** @type {string} */
|
||||
const keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
@ -157,6 +157,8 @@ export default class DefaultCompositionProvider extends CompositionProvider {
|
||||
});
|
||||
|
||||
this.publicAPI.objects.mutate(domainObject, 'composition', composition);
|
||||
|
||||
this.objectListeners.remove?.forEach(listener => listener.callback.apply(listener.context, childId));
|
||||
}
|
||||
/**
|
||||
* Add a domain object to another domain object's composition.
|
||||
@ -174,6 +176,8 @@ export default class DefaultCompositionProvider extends CompositionProvider {
|
||||
if (!this.includes(parent, childId)) {
|
||||
parent.composition.push(childId);
|
||||
this.publicAPI.objects.mutate(parent, 'composition', parent.composition);
|
||||
|
||||
this.objectListeners.add?.forEach(listener => listener.callback.apply(listener.context, childId));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user