2023-11-13 16:42:55 +01:00
|
|
|
import OHIF, { Types, errorHandler } from '@ohif/core';
|
2022-11-16 20:19:52 +01:00
|
|
|
import React from 'react';
|
2022-07-27 18:39:04 +02:00
|
|
|
|
|
|
|
|
import * as cornerstone from '@cornerstonejs/core';
|
|
|
|
|
import * as cornerstoneTools from '@cornerstonejs/tools';
|
|
|
|
|
import {
|
|
|
|
|
init as cs3DInit,
|
|
|
|
|
eventTarget,
|
|
|
|
|
EVENTS,
|
|
|
|
|
metaData,
|
|
|
|
|
volumeLoader,
|
|
|
|
|
imageLoadPoolManager,
|
2024-01-22 15:44:35 +01:00
|
|
|
getEnabledElement,
|
2022-07-27 18:39:04 +02:00
|
|
|
Settings,
|
2023-02-23 03:01:36 +01:00
|
|
|
utilities as csUtilities,
|
2023-09-22 15:31:45 +02:00
|
|
|
Enums as csEnums,
|
2022-07-27 18:39:04 +02:00
|
|
|
} from '@cornerstonejs/core';
|
2023-10-03 16:59:09 +02:00
|
|
|
import { Enums } from '@cornerstonejs/tools';
|
2023-01-11 13:19:27 +01:00
|
|
|
import { cornerstoneStreamingImageVolumeLoader } from '@cornerstonejs/streaming-image-volume-loader';
|
2022-07-27 18:39:04 +02:00
|
|
|
|
|
|
|
|
import initWADOImageLoader from './initWADOImageLoader';
|
|
|
|
|
import initCornerstoneTools from './initCornerstoneTools';
|
|
|
|
|
|
|
|
|
|
import { connectToolsToMeasurementService } from './initMeasurementService';
|
|
|
|
|
import initCineService from './initCineService';
|
|
|
|
|
import interleaveCenterLoader from './utils/interleaveCenterLoader';
|
2022-12-29 17:00:13 +01:00
|
|
|
import nthLoader from './utils/nthLoader';
|
2022-07-27 18:39:04 +02:00
|
|
|
import interleaveTopToBottom from './utils/interleaveTopToBottom';
|
2023-03-22 22:45:28 +01:00
|
|
|
import initContextMenu from './initContextMenu';
|
2023-03-29 21:39:51 +02:00
|
|
|
import initDoubleClick from './initDoubleClick';
|
2023-07-06 18:09:34 +02:00
|
|
|
import { CornerstoneServices } from './types';
|
2023-10-03 23:01:00 +02:00
|
|
|
import initViewTiming from './utils/initViewTiming';
|
2020-09-15 03:18:46 +02:00
|
|
|
|
2022-07-27 18:39:04 +02:00
|
|
|
// TODO: Cypress tests are currently grabbing this from the window?
|
|
|
|
|
window.cornerstone = cornerstone;
|
|
|
|
|
window.cornerstoneTools = cornerstoneTools;
|
2019-10-09 16:23:14 +02:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
*/
|
2022-07-27 18:39:04 +02:00
|
|
|
export default async function init({
|
2020-08-05 14:56:02 +02:00
|
|
|
servicesManager,
|
|
|
|
|
commandsManager,
|
2023-05-03 18:30:02 +02:00
|
|
|
extensionManager,
|
2020-08-05 14:56:02 +02:00
|
|
|
configuration,
|
2022-07-27 18:39:04 +02:00
|
|
|
appConfig,
|
2023-03-22 22:45:28 +01:00
|
|
|
}: Types.Extensions.ExtensionParams): Promise<void> {
|
2023-09-29 23:54:16 +02:00
|
|
|
// Note: this should run first before initializing the cornerstone
|
2023-10-03 16:11:32 +02:00
|
|
|
// DO NOT CHANGE THE ORDER
|
|
|
|
|
const value = appConfig.useSharedArrayBuffer;
|
|
|
|
|
let sharedArrayBufferDisabled = false;
|
|
|
|
|
|
|
|
|
|
if (value === 'AUTO') {
|
|
|
|
|
cornerstone.setUseSharedArrayBuffer(csEnums.SharedArrayBufferModes.AUTO);
|
|
|
|
|
} else if (value === 'FALSE' || value === false) {
|
|
|
|
|
cornerstone.setUseSharedArrayBuffer(csEnums.SharedArrayBufferModes.FALSE);
|
|
|
|
|
sharedArrayBufferDisabled = true;
|
|
|
|
|
} else {
|
|
|
|
|
cornerstone.setUseSharedArrayBuffer(csEnums.SharedArrayBufferModes.TRUE);
|
2023-09-22 15:31:45 +02:00
|
|
|
}
|
|
|
|
|
|
2023-09-29 23:54:16 +02:00
|
|
|
await cs3DInit({
|
|
|
|
|
rendering: {
|
2023-11-03 17:19:24 +01:00
|
|
|
preferSizeOverAccuracy: Boolean(appConfig.preferSizeOverAccuracy),
|
|
|
|
|
useNorm16Texture: Boolean(appConfig.useNorm16Texture),
|
2023-09-29 23:54:16 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// For debugging e2e tests that are failing on CI
|
|
|
|
|
cornerstone.setUseCPURendering(Boolean(appConfig.useCPURendering));
|
|
|
|
|
|
2023-04-01 04:21:16 +02:00
|
|
|
cornerstone.setConfiguration({
|
|
|
|
|
...cornerstone.getConfiguration(),
|
|
|
|
|
rendering: {
|
|
|
|
|
...cornerstone.getConfiguration().rendering,
|
2023-09-01 22:19:39 +02:00
|
|
|
strictZSpacingForVolumeViewport: appConfig.strictZSpacingForVolumeViewport,
|
2023-04-01 04:21:16 +02:00
|
|
|
},
|
|
|
|
|
});
|
2022-07-27 18:39:04 +02:00
|
|
|
|
2023-08-15 13:20:45 +02:00
|
|
|
// For debugging large datasets, otherwise prefer the defaults
|
|
|
|
|
const { maxCacheSize } = appConfig;
|
|
|
|
|
if (maxCacheSize) {
|
|
|
|
|
cornerstone.cache.setMaxCacheSize(maxCacheSize);
|
|
|
|
|
}
|
2022-07-27 18:39:04 +02:00
|
|
|
|
|
|
|
|
initCornerstoneTools();
|
|
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
Settings.getRuntimeSettings().set('useCursors', Boolean(appConfig.useCursors));
|
2022-07-27 18:39:04 +02:00
|
|
|
|
2020-07-22 19:40:40 +02:00
|
|
|
const {
|
2023-02-13 14:55:55 +01:00
|
|
|
userAuthenticationService,
|
2023-03-22 22:45:28 +01:00
|
|
|
customizationService,
|
2023-02-13 14:55:55 +01:00
|
|
|
uiModalService,
|
2023-02-10 22:46:09 +01:00
|
|
|
uiNotificationService,
|
2023-02-07 20:31:55 +01:00
|
|
|
cineService,
|
2023-02-10 22:46:09 +01:00
|
|
|
cornerstoneViewportService,
|
|
|
|
|
hangingProtocolService,
|
|
|
|
|
toolGroupService,
|
2023-10-03 16:59:09 +02:00
|
|
|
toolbarService,
|
2023-02-10 22:46:09 +01:00
|
|
|
viewportGridService,
|
2023-03-15 17:41:41 +01:00
|
|
|
stateSyncService,
|
2024-01-22 15:44:35 +01:00
|
|
|
syncGroupService,
|
2023-07-06 18:09:34 +02:00
|
|
|
} = servicesManager.services as CornerstoneServices;
|
2020-09-15 03:18:46 +02:00
|
|
|
|
2022-11-16 20:19:52 +01:00
|
|
|
window.services = servicesManager.services;
|
2023-05-03 18:30:02 +02:00
|
|
|
window.extensionManager = extensionManager;
|
|
|
|
|
window.commandsManager = commandsManager;
|
2022-07-27 18:39:04 +02:00
|
|
|
|
2023-10-03 16:11:32 +02:00
|
|
|
if (
|
|
|
|
|
appConfig.showWarningMessageForCrossOrigin &&
|
|
|
|
|
!window.crossOriginIsolated &&
|
|
|
|
|
!sharedArrayBufferDisabled
|
|
|
|
|
) {
|
2023-02-10 22:46:09 +01:00
|
|
|
uiNotificationService.show({
|
2022-12-05 15:53:59 +01:00
|
|
|
title: 'Cross Origin Isolation',
|
2023-10-03 16:11:32 +02:00
|
|
|
message:
|
|
|
|
|
'Cross Origin Isolation is not enabled, read more about it here: https://docs.ohif.org/faq/',
|
2022-12-05 15:53:59 +01:00
|
|
|
type: 'warning',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
if (appConfig.showCPUFallbackMessage && cornerstone.getShouldUseCPURendering()) {
|
2023-02-13 14:55:55 +01:00
|
|
|
_showCPURenderingModal(uiModalService, hangingProtocolService);
|
2022-11-16 20:19:52 +01:00
|
|
|
}
|
|
|
|
|
|
2023-03-20 20:11:21 +01:00
|
|
|
// Stores a map from `lutPresentationId` to a Presentation object so that
|
|
|
|
|
// an OHIFCornerstoneViewport can be redisplayed with the same LUT
|
|
|
|
|
stateSyncService.register('lutPresentationStore', { clearOnModeExit: true });
|
|
|
|
|
|
2024-01-22 15:44:35 +01:00
|
|
|
// Stores synchronizers state to be restored
|
|
|
|
|
stateSyncService.register('synchronizersStore', { clearOnModeExit: true });
|
|
|
|
|
|
2023-03-20 20:11:21 +01:00
|
|
|
// Stores a map from `positionPresentationId` to a Presentation object so that
|
|
|
|
|
// an OHIFCornerstoneViewport can be redisplayed with the same position
|
|
|
|
|
stateSyncService.register('positionPresentationStore', {
|
|
|
|
|
clearOnModeExit: true,
|
|
|
|
|
});
|
2023-03-15 17:41:41 +01:00
|
|
|
|
2023-03-29 21:39:51 +02:00
|
|
|
// Stores the entire ViewportGridService getState when toggling to one up
|
|
|
|
|
// (e.g. via a double click) so that it can be restored when toggling back.
|
|
|
|
|
stateSyncService.register('toggleOneUpViewportGridStore', {
|
|
|
|
|
clearOnModeExit: true,
|
|
|
|
|
});
|
|
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
const labelmapRepresentation = cornerstoneTools.Enums.SegmentationRepresentations.Labelmap;
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
cornerstoneTools.segmentation.config.setGlobalRepresentationConfig(labelmapRepresentation, {
|
|
|
|
|
fillAlpha: 0.3,
|
|
|
|
|
fillAlphaInactive: 0.2,
|
|
|
|
|
outlineOpacity: 1,
|
|
|
|
|
outlineOpacityInactive: 0.65,
|
|
|
|
|
});
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
const metadataProvider = OHIF.classes.MetadataProvider;
|
|
|
|
|
|
2022-07-27 18:39:04 +02:00
|
|
|
volumeLoader.registerVolumeLoader(
|
|
|
|
|
'cornerstoneStreamingImageVolume',
|
|
|
|
|
cornerstoneStreamingImageVolumeLoader
|
|
|
|
|
);
|
|
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
hangingProtocolService.registerImageLoadStrategy('interleaveCenter', interleaveCenterLoader);
|
|
|
|
|
hangingProtocolService.registerImageLoadStrategy('interleaveTopToBottom', interleaveTopToBottom);
|
2023-02-10 22:46:09 +01:00
|
|
|
hangingProtocolService.registerImageLoadStrategy('nth', nthLoader);
|
2022-07-27 18:39:04 +02:00
|
|
|
|
2023-02-23 03:01:36 +01:00
|
|
|
// add metadata providers
|
|
|
|
|
metaData.addProvider(
|
|
|
|
|
csUtilities.calibratedPixelSpacingMetadataProvider.get.bind(
|
|
|
|
|
csUtilities.calibratedPixelSpacingMetadataProvider
|
|
|
|
|
)
|
|
|
|
|
); // this provider is required for Calibration tool
|
2022-07-27 18:39:04 +02:00
|
|
|
metaData.addProvider(metadataProvider.get.bind(metadataProvider), 9999);
|
|
|
|
|
|
|
|
|
|
imageLoadPoolManager.maxNumRequests = {
|
|
|
|
|
interaction: appConfig?.maxNumRequests?.interaction || 100,
|
|
|
|
|
thumbnail: appConfig?.maxNumRequests?.thumbnail || 75,
|
|
|
|
|
prefetch: appConfig?.maxNumRequests?.prefetch || 10,
|
|
|
|
|
};
|
|
|
|
|
|
2023-06-01 23:18:54 +02:00
|
|
|
initWADOImageLoader(userAuthenticationService, appConfig, extensionManager);
|
2019-12-09 18:47:23 +01:00
|
|
|
|
2020-08-05 14:56:02 +02:00
|
|
|
/* Measurement Service */
|
2023-09-01 22:19:39 +02:00
|
|
|
this.measurementServiceSource = connectToolsToMeasurementService(servicesManager);
|
2020-08-05 14:56:02 +02:00
|
|
|
|
2023-02-07 20:31:55 +01:00
|
|
|
initCineService(cineService);
|
2022-07-27 18:39:04 +02:00
|
|
|
|
|
|
|
|
// When a custom image load is performed, update the relevant viewports
|
2023-02-10 22:46:09 +01:00
|
|
|
hangingProtocolService.subscribe(
|
|
|
|
|
hangingProtocolService.EVENTS.CUSTOM_IMAGE_LOAD_PERFORMED,
|
2022-07-27 18:39:04 +02:00
|
|
|
volumeInputArrayMap => {
|
|
|
|
|
for (const entry of volumeInputArrayMap.entries()) {
|
|
|
|
|
const [viewportId, volumeInputArray] = entry;
|
2023-09-01 22:19:39 +02:00
|
|
|
const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
|
|
|
|
|
|
|
|
|
|
const ohifViewport = cornerstoneViewportService.getViewportInfo(viewportId);
|
|
|
|
|
|
|
|
|
|
const { lutPresentationStore, positionPresentationStore } = stateSyncService.getState();
|
2023-03-29 15:40:22 +02:00
|
|
|
const { presentationIds } = ohifViewport.getViewportOptions();
|
|
|
|
|
const presentations = {
|
2023-09-01 22:19:39 +02:00
|
|
|
positionPresentation: positionPresentationStore[presentationIds?.positionPresentationId],
|
|
|
|
|
lutPresentation: lutPresentationStore[presentationIds?.lutPresentationId],
|
2023-03-29 15:40:22 +02:00
|
|
|
};
|
|
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
cornerstoneViewportService.setVolumesForViewport(viewport, volumeInputArray, presentations);
|
2022-07-27 18:39:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2023-03-22 22:45:28 +01:00
|
|
|
initContextMenu({
|
|
|
|
|
cornerstoneViewportService,
|
|
|
|
|
customizationService,
|
|
|
|
|
commandsManager,
|
|
|
|
|
});
|
2020-08-05 14:56:02 +02:00
|
|
|
|
2023-03-29 21:39:51 +02:00
|
|
|
initDoubleClick({
|
|
|
|
|
customizationService,
|
|
|
|
|
commandsManager,
|
|
|
|
|
});
|
|
|
|
|
|
2023-10-03 16:59:09 +02:00
|
|
|
/**
|
|
|
|
|
* When a viewport gets a new display set, this call will go through all the
|
|
|
|
|
* active tools in the toolbar, and call any commands registered in the
|
|
|
|
|
* toolbar service with a callback to re-enable on displaying the viewport.
|
|
|
|
|
*/
|
|
|
|
|
const toolbarEventListener = evt => {
|
2022-09-16 05:23:17 +02:00
|
|
|
const { element } = evt.detail;
|
2023-10-03 16:59:09 +02:00
|
|
|
const activeTools = toolbarService.getActiveTools();
|
|
|
|
|
|
|
|
|
|
activeTools.forEach(tool => {
|
|
|
|
|
const toolData = toolbarService.getNestedButton(tool);
|
|
|
|
|
const commands = toolData?.listeners?.[evt.type];
|
|
|
|
|
commandsManager.run(commands, { element, evt });
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Listens for active viewport events and fires the toolbar listeners */
|
|
|
|
|
const activeViewportEventListener = evt => {
|
|
|
|
|
const { viewportId } = evt;
|
|
|
|
|
const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
|
|
|
|
|
|
|
|
|
|
const activeTools = toolbarService.getActiveTools();
|
|
|
|
|
|
|
|
|
|
activeTools.forEach(tool => {
|
|
|
|
|
if (!toolGroup?._toolInstances?.[tool]) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check if tool is active on the new viewport
|
|
|
|
|
const toolEnabled = toolGroup._toolInstances[tool].mode === Enums.ToolModes.Enabled;
|
|
|
|
|
|
|
|
|
|
if (!toolEnabled) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const button = toolbarService.getNestedButton(tool);
|
|
|
|
|
const commands = button?.listeners?.[evt.type];
|
|
|
|
|
commandsManager.run(commands, { viewportId, evt });
|
|
|
|
|
});
|
2022-09-16 05:23:17 +02:00
|
|
|
};
|
|
|
|
|
|
2023-11-13 16:42:55 +01:00
|
|
|
/**
|
|
|
|
|
* Runs error handler for failed requests.
|
2024-01-09 16:15:56 +01:00
|
|
|
* @param event
|
2023-11-13 16:42:55 +01:00
|
|
|
*/
|
|
|
|
|
const imageLoadFailedHandler = ({ detail }) => {
|
2024-01-09 16:15:56 +01:00
|
|
|
const handler = errorHandler.getHTTPErrorHandler();
|
2023-11-13 16:42:55 +01:00
|
|
|
handler(detail.error);
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-16 20:19:52 +01:00
|
|
|
const resetCrosshairs = evt => {
|
|
|
|
|
const { element } = evt.detail;
|
2023-09-01 22:19:39 +02:00
|
|
|
const { viewportId, renderingEngineId } = cornerstone.getEnabledElement(element);
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
const toolGroup = cornerstoneTools.ToolGroupManager.getToolGroupForViewport(
|
|
|
|
|
viewportId,
|
|
|
|
|
renderingEngineId
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!toolGroup || !toolGroup._toolInstances?.['Crosshairs']) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mode = toolGroup._toolInstances['Crosshairs'].mode;
|
|
|
|
|
|
|
|
|
|
if (mode === Enums.ToolModes.Active) {
|
|
|
|
|
toolGroup.setToolActive('Crosshairs');
|
|
|
|
|
} else if (mode === Enums.ToolModes.Passive) {
|
|
|
|
|
toolGroup.setToolPassive('Crosshairs');
|
|
|
|
|
} else if (mode === Enums.ToolModes.Enabled) {
|
|
|
|
|
toolGroup.setToolEnabled('Crosshairs');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-10-03 16:59:09 +02:00
|
|
|
eventTarget.addEventListener(EVENTS.STACK_VIEWPORT_NEW_STACK, evt => {
|
|
|
|
|
const { element } = evt.detail;
|
|
|
|
|
cornerstoneTools.utilities.stackContextPrefetch.enable(element);
|
|
|
|
|
});
|
2023-11-13 16:42:55 +01:00
|
|
|
eventTarget.addEventListener(EVENTS.IMAGE_LOAD_FAILED, imageLoadFailedHandler);
|
|
|
|
|
eventTarget.addEventListener(EVENTS.IMAGE_LOAD_ERROR, imageLoadFailedHandler);
|
2024-01-09 16:15:56 +01:00
|
|
|
|
2022-07-27 18:39:04 +02:00
|
|
|
function elementEnabledHandler(evt) {
|
|
|
|
|
const { element } = evt.detail;
|
2023-11-13 16:42:55 +01:00
|
|
|
|
2022-11-16 20:19:52 +01:00
|
|
|
element.addEventListener(EVENTS.CAMERA_RESET, resetCrosshairs);
|
|
|
|
|
|
2023-10-03 16:59:09 +02:00
|
|
|
eventTarget.addEventListener(EVENTS.STACK_VIEWPORT_NEW_STACK, toolbarEventListener);
|
2023-10-03 23:01:00 +02:00
|
|
|
|
|
|
|
|
initViewTiming({ element, eventTarget });
|
2020-08-05 14:56:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function elementDisabledHandler(evt) {
|
2022-11-16 20:19:52 +01:00
|
|
|
const { element } = evt.detail;
|
2022-07-27 18:39:04 +02:00
|
|
|
|
2022-11-16 20:19:52 +01:00
|
|
|
element.removeEventListener(EVENTS.CAMERA_RESET, resetCrosshairs);
|
|
|
|
|
|
2022-09-16 05:23:17 +02:00
|
|
|
// TODO - consider removing the callback when all elements are gone
|
|
|
|
|
// eventTarget.removeEventListener(
|
|
|
|
|
// EVENTS.STACK_VIEWPORT_NEW_STACK,
|
|
|
|
|
// newStackCallback
|
|
|
|
|
// );
|
2022-07-27 18:39:04 +02:00
|
|
|
}
|
2020-07-03 19:18:59 +02:00
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
eventTarget.addEventListener(EVENTS.ELEMENT_ENABLED, elementEnabledHandler.bind(null));
|
2020-07-03 18:39:41 +02:00
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
eventTarget.addEventListener(EVENTS.ELEMENT_DISABLED, elementDisabledHandler.bind(null));
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2023-02-10 22:46:09 +01:00
|
|
|
viewportGridService.subscribe(
|
2023-08-30 22:46:55 +02:00
|
|
|
viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED,
|
2023-10-03 16:59:09 +02:00
|
|
|
activeViewportEventListener
|
2023-11-03 17:19:24 +01:00
|
|
|
);
|
|
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
function CPUModal() {
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<p>
|
2023-09-01 22:19:39 +02:00
|
|
|
Your computer does not have enough GPU power to support the default GPU rendering mode. OHIF
|
|
|
|
|
has switched to CPU rendering mode. Please note that CPU rendering does not support all
|
|
|
|
|
features such as Volume Rendering, Multiplanar Reconstruction, and Segmentation Overlays.
|
2022-11-16 20:19:52 +01:00
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-13 14:55:55 +01:00
|
|
|
function _showCPURenderingModal(uiModalService, hangingProtocolService) {
|
2022-11-16 20:19:52 +01:00
|
|
|
const callback = progress => {
|
|
|
|
|
if (progress === 100) {
|
2023-02-13 14:55:55 +01:00
|
|
|
uiModalService.show({
|
2022-11-16 20:19:52 +01:00
|
|
|
content: CPUModal,
|
|
|
|
|
title: 'OHIF Fell Back to CPU Rendering',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-02-10 22:46:09 +01:00
|
|
|
const { unsubscribe } = hangingProtocolService.subscribe(
|
2023-03-15 17:41:41 +01:00
|
|
|
hangingProtocolService.EVENTS.PROTOCOL_CHANGED,
|
|
|
|
|
() => {
|
|
|
|
|
const done = callback(100);
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
if (done) {
|
|
|
|
|
unsubscribe();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
2020-09-15 03:18:46 +02:00
|
|
|
}
|