mirror of
https://github.com/nasa/openmct.git
synced 2025-06-27 19:38:53 +00:00
Compare commits
1 Commits
feature-pl
...
refactor-c
Author | SHA1 | Date | |
---|---|---|---|
d16c60aa7a |
@ -20,6 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import EventEmitter from 'EventEmitter';
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../objects/ObjectAPI').DomainObject} DomainObject
|
* @typedef {import('../objects/ObjectAPI').DomainObject} DomainObject
|
||||||
*/
|
*/
|
||||||
@ -60,6 +61,10 @@ export default class CompositionCollection {
|
|||||||
#publicAPI;
|
#publicAPI;
|
||||||
#listeners;
|
#listeners;
|
||||||
#mutables;
|
#mutables;
|
||||||
|
#onGlobalAdd;
|
||||||
|
#onGlobalRemove;
|
||||||
|
static #globalEvents = new EventEmitter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {DomainObject} domainObject the domain object
|
* @param {DomainObject} domainObject the domain object
|
||||||
@ -95,6 +100,21 @@ export default class CompositionCollection {
|
|||||||
unobserve();
|
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
|
* Listen for changes to this composition. Supports 'add', 'remove', and
|
||||||
@ -209,23 +229,21 @@ export default class CompositionCollection {
|
|||||||
* **Intended for internal use ONLY.**
|
* **Intended for internal use ONLY.**
|
||||||
* true if the underlying provider should not be updated.
|
* true if the underlying provider should not be updated.
|
||||||
*/
|
*/
|
||||||
add(child, skipMutate) {
|
add(child) {
|
||||||
if (!skipMutate) {
|
if (!this.#publicAPI.composition.checkPolicy(this.domainObject, 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}`;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
* Load the domain objects in this composition.
|
||||||
@ -240,7 +258,12 @@ export default class CompositionCollection {
|
|||||||
this.#cleanUpMutables();
|
this.#cleanUpMutables();
|
||||||
const children = await this.#provider.load(this.domainObject);
|
const children = await this.#provider.load(this.domainObject);
|
||||||
const childObjects = await Promise.all(children.map((c) => this.#publicAPI.objects.get(c, abortSignal)));
|
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');
|
this.#emit('load');
|
||||||
|
|
||||||
return childObjects;
|
return childObjects;
|
||||||
@ -259,20 +282,18 @@ export default class CompositionCollection {
|
|||||||
* true if the underlying provider should not be updated.
|
* true if the underlying provider should not be updated.
|
||||||
* @name remove
|
* @name remove
|
||||||
*/
|
*/
|
||||||
remove(child, skipMutate) {
|
remove(child) {
|
||||||
if (!skipMutate) {
|
this.#provider.remove(this.domainObject, child.identifier);
|
||||||
this.#provider.remove(this.domainObject, child.identifier);
|
if (this.returnMutables) {
|
||||||
} else {
|
let keyString = this.#publicAPI.objects.makeKeyString(child);
|
||||||
if (this.returnMutables) {
|
if (this.#mutables[keyString] !== undefined && this.#mutables[keyString].isMutable) {
|
||||||
let keyString = this.#publicAPI.objects.makeKeyString(child);
|
this.#publicAPI.objects.destroyMutable(this.#mutables[keyString]);
|
||||||
if (this.#mutables[keyString] !== undefined && this.#mutables[keyString].isMutable) {
|
delete this.#mutables[keyString];
|
||||||
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.
|
* Reorder the domain objects in this composition.
|
||||||
@ -295,6 +316,10 @@ export default class CompositionCollection {
|
|||||||
this.mutationListener();
|
this.mutationListener();
|
||||||
delete 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.
|
* Handle reorder from provider.
|
||||||
|
@ -71,10 +71,6 @@ export default class CompositionProvider {
|
|||||||
return this.#listeningTo;
|
return this.#listeningTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
get establishTopicListener() {
|
|
||||||
return this.#establishTopicListener.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
get publicAPI() {
|
get publicAPI() {
|
||||||
return this.#publicAPI;
|
return this.#publicAPI;
|
||||||
}
|
}
|
||||||
@ -181,22 +177,6 @@ export default class CompositionProvider {
|
|||||||
throw new Error("This method must be implemented by a subclass.");
|
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
|
* @private
|
||||||
* @param {DomainObject} parent
|
* @param {DomainObject} parent
|
||||||
@ -216,47 +196,5 @@ export default class CompositionProvider {
|
|||||||
#supportsComposition(parent, _child) {
|
#supportsComposition(parent, _child) {
|
||||||
return this.#publicAPI.composition.supportsComposition(parent);
|
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,
|
event,
|
||||||
callback,
|
callback,
|
||||||
context) {
|
context) {
|
||||||
this.establishTopicListener();
|
//this.establishTopicListener();
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
const keyString = objectUtils.makeKeyString(domainObject.identifier);
|
const keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||||
@ -157,6 +157,8 @@ export default class DefaultCompositionProvider extends CompositionProvider {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.publicAPI.objects.mutate(domainObject, 'composition', composition);
|
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.
|
* 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)) {
|
if (!this.includes(parent, childId)) {
|
||||||
parent.composition.push(childId);
|
parent.composition.push(childId);
|
||||||
this.publicAPI.objects.mutate(parent, 'composition', parent.composition);
|
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