Skip to content

Commit 931f6a0

Browse files
committed
refactor(cine): tighten comments and types from simplify review
- Trim verbose comments in VtkSliceView, useAnnotationTool, useVtkView to non-obvious WHY only; note why public cancelAnimation is unusable. - Rename cineActiveOnly -> restrictToActiveView so the flag describes the behavior, not the trigger. - Drop speculative `as any` casts and removeListener fallback in the interactor-lifecycle e2e; align BrowserLogEntry with WDIO's LogEntry.
1 parent 1baca1e commit 931f6a0

4 files changed

Lines changed: 19 additions & 29 deletions

File tree

src/components/vtk/VtkSliceView.vue

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,10 @@ watchImmediate(
101101
}
102102
);
103103
104-
// Restore persisted camera state before the clipping-range reset below.
105-
// resetCameraClippingRange uses the camera's current position to compute
106-
// near/far planes, so on remount (e.g. maximize toggle) it must run after
107-
// syncRef has written the saved position back into the camera — otherwise
108-
// the planes are computed against the default camera and the slice falls
109-
// outside the clip volume, leaving a black canvas.
104+
// Must run before the clipping-range watcher below: resetCameraClippingRange
105+
// computes near/far from the camera's current position, so on remount the
106+
// saved position must be syncRef'd back first or the slice falls outside
107+
// the clip volume and the canvas goes black.
110108
usePersistCameraConfig(viewID, imageID, view.renderer.getActiveCamera());
111109
112110
watchImmediate([imageMetadata, disableCameraAutoReset], () => {

src/core/vtk/useVtkView.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@ import {
1919
watchPostEffect,
2020
} from 'vue';
2121

22-
type VtkInteractorAnimationModel = {
23-
animationRequest?: number | null;
24-
};
25-
22+
// vtk.js' public interactor.cancelAnimation() is a no-op while the
23+
// post-wheel extension window is still open (model._animationExtendedEnd),
24+
// so on dispose during that window a pending rAF survives and fires against
25+
// the deleted interactor. Reach into the private animationRequest field to
26+
// cancel it directly.
2627
function cancelPendingInteractorAnimationFrame(
2728
interactor: vtkRenderWindowInteractor
2829
) {
2930
const model = (
30-
interactor as unknown as { get(): VtkInteractorAnimationModel }
31+
interactor as unknown as { get(): { animationRequest?: number | null } }
3132
).get();
3233
if (model.animationRequest == null) return;
3334

src/store/tools/useAnnotationTool.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,15 @@ export const useAnnotationTool = <
147147
if (!toolImageFrame) return;
148148

149149
const viewStore = useViewStore();
150-
// Cine forces every 2D view's effective axis to Axial, so without this
151-
// every cine view would jump to the same frame; scope it to the active
152-
// view instead.
153-
const cineActiveOnly = isCineImage(imageID);
150+
// Cine collapses every 2D view to Axial, so without the active-view gate
151+
// every cine view would jump to the same frame.
152+
const restrictToActiveView = isCineImage(imageID);
154153
const relevantViews = viewStore.getAllViews().filter((view) => {
155154
if (view.type !== '2D') return false;
156155
if (getEffectiveViewAxis(view, imageID) !== toolImageFrame.axis)
157156
return false;
158-
if (cineActiveOnly && view.id !== viewStore.activeView) return false;
157+
if (restrictToActiveView && view.id !== viewStore.activeView)
158+
return false;
159159
return true;
160160
});
161161

tests/specs/vtk-interactor-lifecycle.e2e.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@ import { openUrls } from './utils';
44
const VIEW_SELECTOR = 'div[data-testid="vtk-view vtk-two-view"]';
55
const DELETED_INSTANCE_ERROR = 'instance deleted - cannot call any method';
66

7-
type BrowserLogEntry = {
8-
level?: string;
9-
text?: string;
10-
message?: string;
11-
};
12-
13-
function formatBrowserLogEntry(entry: BrowserLogEntry) {
14-
return entry.text ?? entry.message ?? JSON.stringify(entry);
15-
}
7+
type BrowserLogEntry = { text: string | null };
168

179
async function captureBrowserConsoleLogsDuring(action: () => Promise<void>) {
1810
const logs: BrowserLogEntry[] = [];
@@ -21,14 +13,13 @@ async function captureBrowserConsoleLogsDuring(action: () => Promise<void>) {
2113
};
2214

2315
await (browser as any).sessionSubscribe({ events: ['log.entryAdded'] });
24-
(browser as any).on('log.entryAdded', handler);
16+
browser.on('log.entryAdded', handler);
2517

2618
try {
2719
await action();
2820
await browser.pause(250);
2921
} finally {
30-
(browser as any).off?.('log.entryAdded', handler);
31-
(browser as any).removeListener?.('log.entryAdded', handler);
22+
browser.off('log.entryAdded', handler);
3223
}
3324

3425
return logs;
@@ -84,7 +75,7 @@ describe('VTK interactor lifecycle', () => {
8475
});
8576

8677
const deletedInteractorErrors = logs
87-
.map(formatBrowserLogEntry)
78+
.map((entry) => entry.text ?? '')
8879
.filter((message) => message.includes(DELETED_INSTANCE_ERROR));
8980

9081
expect(deletedInteractorErrors).toEqual([]);

0 commit comments

Comments
 (0)