mirror of
https://github.com/nasa/openmct.git
synced 2025-05-12 21:43:23 +00:00
144 lines
5.2 KiB
JavaScript
144 lines
5.2 KiB
JavaScript
/*****************************************************************************
|
|
* Open MCT, Copyright (c) 2014-2024, United States Government
|
|
* as represented by the Administrator of the National Aeronautics and Space
|
|
* Administration. All rights reserved.
|
|
*
|
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
* Open MCT includes source code licensed under additional open source
|
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
* this source code distribution or the Licensing information page available
|
|
* at runtime from the About dialog for additional information.
|
|
*****************************************************************************/
|
|
import CompsManager from './CompsManager.js';
|
|
|
|
export default class CompsTelemetryProvider {
|
|
#openmct = null;
|
|
#sharedWorker = null;
|
|
#compsManagerPool = null;
|
|
#lastUniqueID = 1;
|
|
#requestPromises = {};
|
|
#subscriptionCallbacks = {};
|
|
|
|
constructor(openmct, compsManagerPool) {
|
|
this.#openmct = openmct;
|
|
this.#compsManagerPool = compsManagerPool;
|
|
this.#startSharedWorker();
|
|
}
|
|
|
|
isTelemetryObject(domainObject) {
|
|
return domainObject.type === 'comps';
|
|
}
|
|
|
|
supportsRequest(domainObject) {
|
|
return domainObject.type === 'comps';
|
|
}
|
|
|
|
supportsSubscribe(domainObject) {
|
|
return domainObject.type === 'comps';
|
|
}
|
|
|
|
#getCallbackID() {
|
|
return this.#lastUniqueID++;
|
|
}
|
|
|
|
// eslint-disable-next-line require-await
|
|
async request(domainObject, options) {
|
|
const specificCompsManager = CompsManager.getCompsManager(
|
|
domainObject,
|
|
this.#openmct,
|
|
this.#compsManagerPool
|
|
);
|
|
await specificCompsManager.load();
|
|
return new Promise((resolve, reject) => {
|
|
const callbackID = this.#getCallbackID();
|
|
const telemetryForComps = specificCompsManager.requestUnderlyingTelemetry();
|
|
const expression = specificCompsManager.getExpression();
|
|
// need to create callbackID with a promise for future execution
|
|
console.debug('🏟️ 1 Telemetry for comps:', telemetryForComps);
|
|
console.debug('🏟️ 2 Telemetry for comps:', specificCompsManager.requestUnderlyingTelemetry());
|
|
this.#requestPromises[callbackID] = { resolve, reject };
|
|
this.#sharedWorker.port.postMessage({
|
|
type: 'calculateRequest',
|
|
telemetryForComps,
|
|
expression,
|
|
callbackID
|
|
});
|
|
});
|
|
}
|
|
|
|
#computeOnNewTelemetry(specificCompsManager, newTelemetry, callbackID) {
|
|
const expression = specificCompsManager.getExpression();
|
|
const telemetryForComps = specificCompsManager.getFullDataFrame(newTelemetry);
|
|
console.debug('🏟️ created new Data frame:', telemetryForComps);
|
|
this.#sharedWorker.port.postMessage({
|
|
type: 'calculateSubscription',
|
|
telemetryForComps,
|
|
expression,
|
|
callbackID
|
|
});
|
|
}
|
|
|
|
subscribe(domainObject, callback) {
|
|
const specificCompsManager = CompsManager.getCompsManager(
|
|
domainObject,
|
|
this.#openmct,
|
|
this.#compsManagerPool
|
|
);
|
|
const callbackID = this.#getCallbackID();
|
|
this.#subscriptionCallbacks[callbackID] = callback;
|
|
specificCompsManager.on('underlyingTelemetryUpdated', (newTelemetry) => {
|
|
this.#computeOnNewTelemetry(specificCompsManager, newTelemetry, callbackID);
|
|
});
|
|
return () => {
|
|
specificCompsManager.off('calculationUpdated', callback);
|
|
delete this.#subscriptionCallbacks[callbackID];
|
|
};
|
|
}
|
|
|
|
#startSharedWorker() {
|
|
if (this.#sharedWorker) {
|
|
throw new Error('Shared worker already started');
|
|
}
|
|
const sharedWorkerURL = `${this.#openmct.getAssetPath()}${__OPENMCT_ROOT_RELATIVE__}compsMathWorker.js`;
|
|
|
|
this.#sharedWorker = new SharedWorker(sharedWorkerURL, `Comps Math Worker`);
|
|
this.#sharedWorker.port.onmessage = this.onSharedWorkerMessage.bind(this);
|
|
this.#sharedWorker.port.onmessageerror = this.onSharedWorkerMessageError.bind(this);
|
|
this.#sharedWorker.port.start();
|
|
|
|
// send an initial message to the worker
|
|
this.#sharedWorker.port.postMessage({ type: 'init' });
|
|
|
|
this.#openmct.on('destroy', () => {
|
|
this.#sharedWorker.port.close();
|
|
});
|
|
}
|
|
|
|
onSharedWorkerMessage(event) {
|
|
console.log('📝 Shared worker message:', event.data);
|
|
const { type, result, callbackID } = event.data;
|
|
if (type === 'calculationSubscriptionResult' && this.#subscriptionCallbacks[callbackID]) {
|
|
this.#subscriptionCallbacks[callbackID](result);
|
|
} else if (type === 'calculationRequestResult') {
|
|
this.#requestPromises[callbackID].resolve(result);
|
|
delete this.#requestPromises[callbackID];
|
|
} else if (type === 'error') {
|
|
console.error('❌ Shared worker error:', event.data);
|
|
}
|
|
}
|
|
|
|
onSharedWorkerMessageError(event) {
|
|
console.error('❌ Shared worker message error:', event);
|
|
}
|
|
}
|