fix(cine): Resolve Cine Player Faults on DisplaySet Update (#4909)

This commit is contained in:
Pedro Köhler 2025-04-04 14:33:36 -03:00 committed by GitHub
parent 0eb9ff235c
commit 746f2524eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 49 additions and 23 deletions

View File

@ -41,7 +41,7 @@ const _generateReport = (measurementData, additionalFindingTypes, options = {})
}; };
const commandsModule = (props: withAppTypes) => { const commandsModule = (props: withAppTypes) => {
const { servicesManager, extensionManager } = props; const { servicesManager, extensionManager, commandsManager } = props;
const { customizationService, viewportGridService, displaySetService } = servicesManager.services; const { customizationService, viewportGridService, displaySetService } = servicesManager.services;
const actions = { const actions = {
@ -156,12 +156,14 @@ const commandsModule = (props: withAppTypes) => {
const displaySets = displaySetService.getDisplaySetsForSeries(SeriesInstanceUIDs[0]); const displaySets = displaySetService.getDisplaySetsForSeries(SeriesInstanceUIDs[0]);
if (displaySets.length) { if (displaySets.length) {
viewportGridService.setDisplaySetsForViewports([ commandsManager.run('setDisplaySetsForViewports', {
{ viewportsToUpdate: [
viewportId: viewportGridService.getActiveViewportId(), {
displaySetInstanceUIDs: [displaySets[0].displaySetInstanceUID], viewportId: viewportGridService.getActiveViewportId(),
}, displaySetInstanceUIDs: [displaySets[0].displaySetInstanceUID],
]); },
],
});
} }
}, },
}; };

View File

@ -263,7 +263,7 @@ const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
} }
} }
viewportGridService.setDisplaySetsForViewports(viewportsToUpdate); commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate });
}, },
swapComputedWithDynamicDisplaySet: () => { swapComputedWithDynamicDisplaySet: () => {
// Todo: this assumes there is only one dynamic display set in the viewer // Todo: this assumes there is only one dynamic display set in the viewer
@ -313,7 +313,7 @@ const commandsModule = ({ commandsManager, servicesManager }: withAppTypes) => {
} }
} }
viewportGridService.setDisplaySetsForViewports(viewportsToUpdate); commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate });
}, },
createNewLabelMapForDynamicVolume: async ({ label }) => { createNewLabelMapForDynamicVolume: async ({ label }) => {
const { viewports, activeViewportId } = viewportGridService.getState(); const { viewports, activeViewportId } = viewportGridService.getState();

View File

@ -581,7 +581,6 @@ function commandsModule({
}); });
viewport.render(); viewport.render();
}, },
toggleViewportColorbar: ({ viewportId, displaySetInstanceUIDs, options = {} }) => { toggleViewportColorbar: ({ viewportId, displaySetInstanceUIDs, options = {} }) => {
const hasColorbar = colorbarService.hasColorbar(viewportId); const hasColorbar = colorbarService.hasColorbar(viewportId);
if (hasColorbar) { if (hasColorbar) {
@ -590,7 +589,6 @@ function commandsModule({
} }
colorbarService.addColorbar(viewportId, displaySetInstanceUIDs, options); colorbarService.addColorbar(viewportId, displaySetInstanceUIDs, options);
}, },
setWindowLevel(props) { setWindowLevel(props) {
const { toolGroupId } = props; const { toolGroupId } = props;
const { viewportId } = _getActiveViewportEnabledElement(); const { viewportId } = _getActiveViewportEnabledElement();
@ -1536,6 +1534,22 @@ function commandsModule({
measurementService.remove(activeAnnotationUID); measurementService.remove(activeAnnotationUID);
}); });
}, },
setDisplaySetsForViewports: ({ viewportsToUpdate }) => {
const { cineService, viewportGridService } = servicesManager.services;
// Stopping the cine of modified viewports before changing the viewports to
// avoid inconsistent state and lost references
viewportsToUpdate.forEach(viewport => {
const state = cineService.getState();
const currentCineState = state.cines?.[viewport.viewportId];
cineService.setCine({
id: viewport.viewportId,
frameRate: currentCineState?.frameRate ?? state.default?.frameRate ?? 24,
isPlaying: false,
});
});
viewportGridService.setDisplaySetsForViewports(viewportsToUpdate);
},
undo: () => { undo: () => {
DefaultHistoryMemo.undo(); DefaultHistoryMemo.undo();
}, },
@ -1987,6 +2001,7 @@ function commandsModule({
deleteActiveAnnotation: { deleteActiveAnnotation: {
commandFn: actions.deleteActiveAnnotation, commandFn: actions.deleteActiveAnnotation,
}, },
setDisplaySetsForViewports: actions.setDisplaySetsForViewports,
undo: actions.undo, undo: actions.undo,
redo: actions.redo, redo: actions.redo,
interpolateLabelmap: actions.interpolateLabelmap, interpolateLabelmap: actions.interpolateLabelmap,

View File

@ -622,7 +622,7 @@ const commandsModule = ({
}); });
} }
viewportGridService.setDisplaySetsForViewports(updatedViewports); commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate: updatedViewports });
setTimeout(() => actions.scrollActiveThumbnailIntoView(), 0); setTimeout(() => actions.scrollActiveThumbnailIntoView(), 0);
}, },

View File

@ -46,10 +46,9 @@ export default {
'studyBrowser.studyMode': 'all', 'studyBrowser.studyMode': 'all',
'studyBrowser.thumbnailDoubleClickCallback': { 'studyBrowser.thumbnailDoubleClickCallback': {
callbacks: [ callbacks: [
({ activeViewportId, servicesManager, isHangingProtocolLayout }) => ({ activeViewportId, servicesManager, commandsManager, isHangingProtocolLayout }) =>
async displaySetInstanceUID => { async displaySetInstanceUID => {
const { hangingProtocolService, viewportGridService, uiNotificationService } = const { hangingProtocolService, uiNotificationService } = servicesManager.services;
servicesManager.services;
let updatedViewports = []; let updatedViewports = [];
const viewportId = activeViewportId; const viewportId = activeViewportId;
@ -69,7 +68,9 @@ export default {
}); });
} }
viewportGridService.setDisplaySetsForViewports(updatedViewports); commandsManager.run('setDisplaySetsForViewports', {
viewportsToUpdate: updatedViewports,
});
}, },
], ],
}, },

View File

@ -247,7 +247,8 @@ function ViewerViewportGrid(props: withAppTypes) {
}); });
event.consume(); event.consume();
viewportGridService.setDisplaySetsForViewports(updatedViewports);
commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate: updatedViewports });
} }
); );
@ -268,7 +269,8 @@ function ViewerViewportGrid(props: withAppTypes) {
dropHandlerPromise.then(({ handled }) => { dropHandlerPromise.then(({ handled }) => {
if (!handled) { if (!handled) {
const updatedViewports = _getUpdatedViewports(viewportId, displaySetInstanceUID); const updatedViewports = _getUpdatedViewports(viewportId, displaySetInstanceUID);
viewportGridService.setDisplaySetsForViewports(updatedViewports);
commandsManager.run('setDisplaySetsForViewports', { viewportsToUpdate: updatedViewports });
} }
}); });
viewportGridService.publishViewportOnDropHandled({ displaySetInstanceUID }); viewportGridService.publishViewportOnDropHandled({ displaySetInstanceUID });

View File

@ -189,14 +189,14 @@ class ViewportGridService extends PubSubService {
this.setDisplaySetsForViewports([props]); this.setDisplaySetsForViewports([props]);
} }
public async setDisplaySetsForViewports(props) { public async setDisplaySetsForViewports(viewportsToUpdate) {
await this.serviceImplementation._setDisplaySetsForViewports(props); await this.serviceImplementation._setDisplaySetsForViewports(viewportsToUpdate);
const state = this.getState(); const state = this.getState();
const updatedViewports = []; const updatedViewports = [];
const removedViewportIds = []; const removedViewportIds = [];
for (const viewport of props) { for (const viewport of viewportsToUpdate) {
const updatedViewport = state.viewports.get(viewport.viewportId); const updatedViewport = state.viewports.get(viewport.viewportId);
if (updatedViewport) { if (updatedViewport) {

View File

@ -1814,7 +1814,10 @@ window.config = {
}); });
} }
viewportGridService.setDisplaySetsForViewports(updatedViewports); commandsManager.run({
commandName: 'setDisplaySetsForViewports',
commandOptions: { viewportsToUpdate: updatedViewports },
});
}, },
}`, }`,
configuration: ` configuration: `
@ -1859,7 +1862,10 @@ window.config = {
duration: 3000, duration: 3000,
}); });
} }
viewportGridService.setDisplaySetsForViewports(updatedViewports); commandsManager.run({
commandName: 'setDisplaySetsForViewports',
commandOptions: { viewportsToUpdate: updatedViewports },
});
}; };
}, },
}], }],