Skip to content

Commit 7ed06f4

Browse files
committed
feat: onDataAvailable/Changed event hooks
1 parent f68e400 commit 7ed06f4

File tree

8 files changed

+177
-38
lines changed

8 files changed

+177
-38
lines changed

src/core/Geometry2DRepresentation.tsx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
12
import vtkActor2D, {
23
IActor2DInitialValues,
34
} from '@kitware/vtk.js/Rendering/Core/Actor2D';
@@ -11,6 +12,7 @@ import { Vector2 } from '@kitware/vtk.js/types';
1112
import {
1213
forwardRef,
1314
PropsWithChildren,
15+
useCallback,
1416
useEffect,
1517
useImperativeHandle,
1618
useMemo,
@@ -20,14 +22,14 @@ import { IDownstream, IRepresentation } from '../types';
2022
import { compareShallowObject } from '../utils/comparators';
2123
import useBooleanAccumulator from '../utils/useBooleanAccumulator';
2224
import useComparableEffect from '../utils/useComparableEffect';
23-
import useLatest from '../utils/useLatest';
2425
import {
2526
DownstreamContext,
2627
RepresentationContext,
2728
useRendererContext,
2829
} from './contexts';
2930
import useColorTransferFunction from './modules/useColorTransferFunction';
3031
import useCoordinate from './modules/useCoordinate';
32+
import useDataEvents from './modules/useDataEvents';
3133
import useMapper from './modules/useMapper';
3234
import useProp from './modules/useProp';
3335

@@ -120,6 +122,11 @@ export default forwardRef(function Geometry2DRepresentation(
120122
trackModified
121123
);
122124

125+
const getInputData = useCallback(
126+
() => getMapper().getInputData(),
127+
[getMapper]
128+
);
129+
123130
// --- actor --- //
124131

125132
const actorProps = {
@@ -154,15 +161,15 @@ export default forwardRef(function Geometry2DRepresentation(
154161

155162
// --- events --- //
156163

157-
const onDataAvailable = useLatest(props.onDataAvailable);
164+
const { dataChangedEvent, dataAvailableEvent } =
165+
useDataEvents<vtkPolyData>(props);
166+
167+
// trigger data available event
158168
useEffect(() => {
159169
if (dataAvailable) {
160-
// trigger onDataAvailable after making updates to the actor and mapper
161-
onDataAvailable.current?.();
170+
dataAvailableEvent.current.dispatchEvent(getInputData());
162171
}
163-
// onDataAvailable is a ref
164-
// eslint-disable-next-line react-hooks/exhaustive-deps
165-
}, [dataAvailable]);
172+
}, [dataAvailable, dataAvailableEvent, getInputData]);
166173

167174
// --- //
168175

@@ -178,6 +185,7 @@ export default forwardRef(function Geometry2DRepresentation(
178185
const representation = useMemo<IRepresentation>(
179186
() => ({
180187
dataChanged: () => {
188+
dataChangedEvent.current.dispatchEvent(getInputData());
181189
renderer.requestRender();
182190
},
183191
dataAvailable: (available = true) => {
@@ -186,8 +194,17 @@ export default forwardRef(function Geometry2DRepresentation(
186194
},
187195
getActor,
188196
getMapper,
197+
onDataAvailable: (cb) => dataAvailableEvent.current.addEventListener(cb),
198+
onDataChanged: (cb) => dataChangedEvent.current.addEventListener(cb),
189199
}),
190-
[renderer, getActor, getMapper]
200+
[
201+
renderer,
202+
getActor,
203+
getMapper,
204+
getInputData,
205+
dataAvailableEvent,
206+
dataChangedEvent,
207+
]
191208
);
192209

193210
const downstream = useMemo<IDownstream>(

src/core/GeometryRepresentation.tsx

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
12
import vtkActor, {
23
IActorInitialValues,
34
} from '@kitware/vtk.js/Rendering/Core/Actor';
@@ -9,6 +10,7 @@ import { Vector2 } from '@kitware/vtk.js/types';
910
import {
1011
forwardRef,
1112
PropsWithChildren,
13+
useCallback,
1214
useEffect,
1315
useImperativeHandle,
1416
useMemo,
@@ -18,13 +20,13 @@ import { IDownstream, IRepresentation } from '../types';
1820
import { compareShallowObject } from '../utils/comparators';
1921
import useBooleanAccumulator from '../utils/useBooleanAccumulator';
2022
import useComparableEffect from '../utils/useComparableEffect';
21-
import useLatest from '../utils/useLatest';
2223
import {
2324
DownstreamContext,
2425
RepresentationContext,
2526
useRendererContext,
2627
} from './contexts';
2728
import useColorTransferFunction from './modules/useColorTransferFunction';
29+
import useDataEvents from './modules/useDataEvents';
2830
import useMapper from './modules/useMapper';
2931
import useProp from './modules/useProp';
3032

@@ -137,6 +139,11 @@ export default forwardRef(function GeometryRepresentation(
137139
getMapper().setLookupTable(getLookupTable());
138140
}, [getMapper, getLookupTable]);
139141

142+
const getInputData = useCallback(
143+
() => getMapper().getInputData(),
144+
[getMapper]
145+
);
146+
140147
// --- actor --- //
141148

142149
const actorProps = {
@@ -167,15 +174,15 @@ export default forwardRef(function GeometryRepresentation(
167174

168175
// --- events --- //
169176

170-
const onDataAvailable = useLatest(props.onDataAvailable);
177+
const { dataChangedEvent, dataAvailableEvent } =
178+
useDataEvents<vtkPolyData>(props);
179+
180+
// trigger data available event
171181
useEffect(() => {
172182
if (dataAvailable) {
173-
// trigger onDataAvailable after making updates to the actor and mapper
174-
onDataAvailable.current?.();
183+
dataAvailableEvent.current.dispatchEvent(getInputData());
175184
}
176-
// onDataAvailable is a ref
177-
// eslint-disable-next-line react-hooks/exhaustive-deps
178-
}, [dataAvailable]);
185+
}, [dataAvailable, dataAvailableEvent, getInputData]);
179186

180187
// --- //
181188

@@ -191,6 +198,7 @@ export default forwardRef(function GeometryRepresentation(
191198
const representation = useMemo<IRepresentation>(
192199
() => ({
193200
dataChanged: () => {
201+
dataChangedEvent.current.dispatchEvent(getInputData());
194202
renderer.requestRender();
195203
},
196204
dataAvailable: () => {
@@ -199,8 +207,17 @@ export default forwardRef(function GeometryRepresentation(
199207
},
200208
getActor,
201209
getMapper,
210+
onDataAvailable: (cb) => dataAvailableEvent.current.addEventListener(cb),
211+
onDataChanged: (cb) => dataChangedEvent.current.addEventListener(cb),
202212
}),
203-
[renderer, getActor, getMapper]
213+
[
214+
renderer,
215+
getActor,
216+
getMapper,
217+
getInputData,
218+
dataAvailableEvent,
219+
dataChangedEvent,
220+
]
204221
);
205222

206223
const downstream = useMemo<IDownstream>(

src/core/ShareDataSet.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
useRepresentation,
3232
useShareDataSet,
3333
} from './contexts';
34+
import useDataEvents from './modules/useDataEvents';
3435

3536
const DATA_AVAILABLE_EVENT = 'dataAvailable';
3637
const DATA_CHANGED_EVENT = 'dataChanged';
@@ -63,7 +64,7 @@ export function ShareDataSetRoot(props: PropsWithChildren) {
6364
};
6465

6566
const handler = (ev: Event) => {
66-
if (!(ev instanceof CustomEvent<DataEventDetails>)) return;
67+
if (!(ev instanceof CustomEvent)) return;
6768
if (name === ev.detail?.name) {
6869
invoke();
6970
}
@@ -153,6 +154,10 @@ export function RegisterDataSet(props: RegisterDataSetProps) {
153154
share.unregister(id);
154155
});
155156

157+
// --- events --- //
158+
159+
const { dataChangedEvent, dataAvailableEvent } = useDataEvents({});
160+
156161
// --- //
157162

158163
const downstream = useMemo<IDownstream>(
@@ -171,14 +176,18 @@ export function RegisterDataSet(props: RegisterDataSetProps) {
171176
() => ({
172177
dataChanged() {
173178
share.dispatchDataChanged(id);
179+
dataChangedEvent.current.dispatchEvent();
174180
},
175181
dataAvailable() {
176182
share.dispatchDataAvailable(id);
183+
dataAvailableEvent.current.dispatchEvent();
177184
},
178185
getActor: () => null,
179186
getMapper: () => null,
187+
onDataAvailable: (cb) => share.onDataAvailable(id, cb),
188+
onDataChanged: (cb) => share.onDataChanged(id, cb),
180189
}),
181-
[id, share]
190+
[id, share, dataAvailableEvent, dataChangedEvent]
182191
);
183192

184193
return (

src/core/SliceRepresentation.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
12
import AbstractImageMapper, {
23
vtkAbstractImageMapper,
34
} from '@kitware/vtk.js/Rendering/Core/AbstractImageMapper';
@@ -23,13 +24,13 @@ import { IDownstream, IRepresentation } from '../types';
2324
import { compareShallowObject } from '../utils/comparators';
2425
import useBooleanAccumulator from '../utils/useBooleanAccumulator';
2526
import useComparableEffect from '../utils/useComparableEffect';
26-
import useLatest from '../utils/useLatest';
2727
import {
2828
DownstreamContext,
2929
RepresentationContext,
3030
useRendererContext,
3131
} from './contexts';
3232
import useColorTransferFunction from './modules/useColorTransferFunction';
33+
import useDataEvents from './modules/useDataEvents';
3334
import useMapper from './modules/useMapper';
3435
import useProp from './modules/useProp';
3536

@@ -162,6 +163,11 @@ export default forwardRef(function SliceRepresentation(
162163
return getInternalMapper();
163164
}, [mapperInstance, getInternalMapper]);
164165

166+
const getInputData = useCallback(
167+
() => getMapper().getInputData(),
168+
[getMapper]
169+
);
170+
165171
// --- actor --- //
166172

167173
const actorProps = {
@@ -254,15 +260,15 @@ export default forwardRef(function SliceRepresentation(
254260

255261
// --- events --- //
256262

257-
const onDataAvailable = useLatest(props.onDataAvailable);
263+
const { dataChangedEvent, dataAvailableEvent } =
264+
useDataEvents<vtkImageData>(props);
265+
266+
// trigger data available event
258267
useEffect(() => {
259268
if (dataAvailable) {
260-
// trigger onDataAvailable after making updates to the actor and mapper
261-
onDataAvailable.current?.();
269+
dataAvailableEvent.current.dispatchEvent(getInputData());
262270
}
263-
// onDataAvailable is a ref
264-
// eslint-disable-next-line react-hooks/exhaustive-deps
265-
}, [dataAvailable]);
271+
}, [dataAvailable, dataAvailableEvent, getInputData]);
266272

267273
// --- //
268274

@@ -278,6 +284,7 @@ export default forwardRef(function SliceRepresentation(
278284
const representation = useMemo<IRepresentation>(
279285
() => ({
280286
dataChanged: () => {
287+
dataChangedEvent.current.dispatchEvent(getInputData());
281288
renderer.requestRender();
282289
},
283290
dataAvailable: (available = true) => {
@@ -286,8 +293,17 @@ export default forwardRef(function SliceRepresentation(
286293
},
287294
getActor,
288295
getMapper,
296+
onDataAvailable: (cb) => dataAvailableEvent.current.addEventListener(cb),
297+
onDataChanged: (cb) => dataChangedEvent.current.addEventListener(cb),
289298
}),
290-
[renderer, getActor, getMapper]
299+
[
300+
renderer,
301+
getActor,
302+
getMapper,
303+
getInputData,
304+
dataAvailableEvent,
305+
dataChangedEvent,
306+
]
291307
);
292308

293309
const downstream = useMemo<IDownstream>(

0 commit comments

Comments
 (0)