From 2d903d731ff27bd255d35635ded39117c9dd377e Mon Sep 17 00:00:00 2001 From: dannyrb Date: Sat, 6 Jun 2020 23:35:12 -0400 Subject: [PATCH] simplify stateMachine --- .../TrackedMeasurementsContext.jsx | 10 +- .../measurementTrackingMachine.js | 220 +++++++----------- 2 files changed, 95 insertions(+), 135 deletions(-) diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.jsx b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.jsx index b8d2c72e1..718763997 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.jsx +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.jsx @@ -19,13 +19,15 @@ function TrackedMeasurementsContextProvider( UIViewportDialogService, { children } ) { - function promptUser() { + function promptUser(ctx, evt) { + const { StudyInstanceUID, SeriesInstanceUID } = evt; // TODO: ... ActiveViewport? Or Study + Series --> Viewport? // Let's just use zero for meow? return new Promise(function(resolve, reject) { const handleSubmit = result => { UIViewportDialogService.hide(); - resolve(result); + // evt.data available for event transition + resolve({ userResponse: result, StudyInstanceUID, SeriesInstanceUID }); }; UIViewportDialogService.show({ @@ -45,7 +47,9 @@ function TrackedMeasurementsContextProvider( const machOptions = Object.assign({}, defaultOptions); // Merge services machOptions.services = Object.assign({}, machOptions.services, { - shouldTrackPrompt: promptUser, + promptBeginTracking: promptUser, + promptTrackNewStudy: promptUser, + promptTrackNewSeries: promptUser, }); console.log( diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js index 1ba59ca65..5a0862434 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js @@ -1,124 +1,101 @@ -import { Machine, assign } from 'xstate'; -// import { assign } from '@xstate/immer'; +import { assign } from 'xstate'; const machineConfiguration = { id: 'measurementTracking', - initial: 'notTracking', + initial: 'idle', context: { - prevTrackedStudy: '', - prevTrackedSeries: [], trackedStudy: '', trackedSeries: [], - promptResponse: 0, }, states: { - notTracking: { + off: { + type: 'final', + }, + idle: { entry: 'clearContext', on: { - TRACK_SERIES: { - target: 'awaitShouldTrackPrompt', - actions: 'trackSeries', - }, + TRACK_SERIES: 'promptBeginTracking', }, }, - awaitShouldTrackPrompt: { - initial: 'prompt', - states: { - prompt: { - invoke: { - id: 'shouldTrackPrompt', - src: 'shouldTrackPrompt', - onDone: { - target: 'validateResponse', - actions: assign({ promptResponse: (ctx, evt) => evt.data }), - }, - onError: { - target: 'validateResponse', - actions: assign({ promptResponse: (ctx, evt) => evt.data }), - }, + promptBeginTracking: { + invoke: { + src: 'promptBeginTracking', + onDone: [ + { + target: 'tracking', + actions: ['setTrackedStudyAndSeries'], + cond: 'promptAccepted', }, - }, - validateResponse: { - on: { - '': [ - { - target: '#measurementTracking.tracking', - cond: 'acceptResponse', - }, - { - target: '#measurementTracking.neverTrack', - cond: 'rejectResponse', - }, - { - target: '#measurementTracking.notTracking', - cond: 'cancelResponse', - }, - ], + { + target: 'off', + cond: 'promptDeclined', }, + { + target: 'idle', + }, + ], + onError: { + target: 'idle', }, }, }, - neverTrack: { - type: 'final', - }, tracking: { on: { TRACK_SERIES: [ { - target: 'tracking', - cond: 'hasNewSeriesForTrackedStudy', - actions: 'trackSeries', + target: 'promptTrackNewStudy', + cond: 'isNewStudy', }, { - target: 'awaitShouldTrackNewStudyPrompt', - cond: 'willTrackNewStudy', - actions: ['setPrevTracked', 'clearTrackedSeries', 'trackSeries'], + target: 'promptTrackNewSeries', + cond: 'isNewSeries', }, ], UNTRACK_SERIES: [ { - target: 'notTracking', - cond: 'willBeEmpty', - actions: 'untrackSeries', + target: 'tracking', + actions: ['removeTrackedSeries'], + cond: 'hasRemainingTrackedSeries', }, { - target: 'tracking', - actions: 'untrackSeries', + target: 'idle', }, ], }, }, - awaitShouldTrackNewStudyPrompt: { - initial: 'prompt', - states: { - prompt: { - invoke: { - id: 'shouldTrackPrompt', - src: () => confirmDialog('Should we track new study?'), - onDone: { - target: 'validateResponse', - actions: assign({ promptResponse: (ctx, evt) => evt.data }), - }, - onError: { - target: 'validateResponse', - actions: assign({ promptResponse: (ctx, evt) => evt.data }), - }, + promptTrackNewStudy: { + invoke: { + src: 'promptTrackNewStudy', + onDone: [ + { + target: 'tracking', + actions: ['setTrackedStudyAndSeries'], + cond: 'promptAccepted', }, + { + target: 'tracking', + }, + ], + onError: { + target: 'idle', }, - validateResponse: { - on: { - '': [ - { - target: '#measurementTracking.tracking', - cond: 'acceptResponse', - }, - { - target: '#measurementTracking.tracking', - cond: 'rejectResponse', - actions: 'restorePrevTracked', - }, - ], + }, + }, + promptTrackNewSeries: { + invoke: { + src: 'promptTrackNewSeries', + onDone: [ + { + target: 'tracking', + actions: ['addTrackedSeries'], + cond: 'promptAccepted', }, + { + target: 'tracking', + }, + ], + onError: { + target: 'idle', }, }, }, @@ -126,68 +103,47 @@ const machineConfiguration = { strict: true, }; -function confirmDialog(msg) { - return new Promise(function(resolve, reject) { - let confirmed = window.confirm(msg); - - return confirmed ? resolve(1) : reject(-1); - }); -} - const defaultOptions = { services: { - shouldTrackPrompt: () => { - return confirmDialog('Should we start tracking?'); + promptBeginTracking: (ctx, evt) => { + // return { userResponse, StudyInstanceUID, SeriesInstanceUID } + }, + promptTrackNewStudy: (ctx, evt) => { + // return { userResponse, StudyInstanceUID, SeriesInstanceUID } + }, + promptTrackNewSeries: (ctx, evt) => { + // return { userResponse, StudyInstanceUID, SeriesInstanceUID } }, }, actions: { clearContext: assign({ - prevTrackedStudy: '', - prevTrackedSeries: [], trackedStudy: '', trackedSeries: [], - promptResponse: 0, }), - setPrevTracked: assign(ctx => ({ - prevTrackedStudy: ctx.trackedStudy, - prevTrackedSeries: ctx.trackedSeries.slice(), + // Promise resolves w/ `evt.data.*` + setTrackedStudyAndSeries: assign((ctx, evt) => ({ + trackedStudy: evt.data.StudyInstanceUID, + trackedSeries: [evt.data.SeriesInstanceUID], })), - restorePrevTracked: assign(ctx => ({ - trackedStudy: ctx.prevTrackedStudy, - trackedSeries: ctx.prevTrackedSeries.slice(), + addTrackedSeries: assign((ctx, evt) => ({ + trackedSeries: [...ctx.trackedSeries, evt.data.SeriesInstanceUID], })), - clearTrackedSeries: assign(() => ({ - trackedStudy: '', - trackedSeries: [], + removeTrackedSeries: assign((ctx, evt) => ({ + trackedSeries: [ + ...ctx.trackedSeries(ser => ser !== evt.SeriesInstanceUID), + ], })), - trackSeries: assign((ctx, evt) => { - const prevTrackedSeries = ctx.trackedSeries.slice(); - return { - trackedStudy: evt.StudyInstanceUID || '', - trackedSeries: [...prevTrackedSeries, evt.SeriesInstanceUID], - }; - }), - untrackSeries: assign((ctx, evt) => { - const prevTrackedSeries = ctx.trackedSeries.slice(); - return { - trackedSeries: prevTrackedSeries.filter( - serUid => serUid !== evt.SeriesInstanceUID - ), - }; - }), }, guards: { - hasNewSeriesForTrackedStudy: (ctx, evt) => - evt.StudyInstanceUID === ctx.trackedStudy && - !ctx.trackedSeries.includes(evt.SeriesInstanceUID), - willTrackNewStudy: ctx => ctx.StudyInstanceUID !== ctx.trackedStudy, - willBeEmpty: (ctx, evt) => - evt.SeriesInstanceUID && + promptAccepted: (ctx, evt) => evt.data && evt.data.userResponse === 1, + promptCanceled: (ctx, evt) => evt.data && evt.data.userResponse === 0, + promptDeclined: (ctx, evt) => evt.data && evt.data.userResponse === -1, + hasRemainingTrackedSeries: (ctx, evt) => ctx.trackedSeries.length === 1 && - ctx.trackedSeries[0] === evt.SeriesInstanceUID, - acceptResponse: ctx => ctx.promptResponse === 1, - cancelResponse: ctx => ctx.promptResponse === 0, - rejectResponse: ctx => ctx.promptResponse === -1, + ctx.trackedSeries.includes(evt.SeriesInstanceUID), + isNewStudy: (ctx, evt) => ctx.trackedStudy !== evt.StudyInstanceUID, + isNewSeries: (ctx, evt) => + !ctx.trackedSeries.includes(evt.SeriesInstanceUID), }, };