diff --git a/src/datasource/catmaid/spatial_skeleton_commands.ts b/src/datasource/catmaid/spatial_skeleton_commands.ts index 367762a09..7df290bc7 100644 --- a/src/datasource/catmaid/spatial_skeleton_commands.ts +++ b/src/datasource/catmaid/spatial_skeleton_commands.ts @@ -52,20 +52,18 @@ import { addSegmentToVisibleSets, removeSegmentFromVisibleSets, } from "#src/segmentation_display_state/base.js"; -import { - SpatialSkeletonActions, - type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; import type { SpatiallyIndexedSkeletonNode, SpatialSkeletonSourceState, SpatialSkeletonVector, } from "#src/skeleton/api.js"; import type { SpatialSkeletonEditCommandFactory } from "#src/skeleton/command_factories.js"; -import type { - SpatialSkeletonCommand, - SpatialSkeletonCommandContext, -} from "#src/skeleton/command_history.js"; +import { + SpatialSkeletonActions, + type SpatialSkeletonAction, + type SpatialSkeletonCommand, + type SpatialSkeletonCommandContext, +} from "#src/skeleton/command_protocol.js"; import type { SpatiallyIndexedSkeletonLayer } from "#src/skeleton/frontend.js"; import { findSpatiallyIndexedSkeletonNode, diff --git a/src/layer/segmentation/index.spec.ts b/src/layer/segmentation/index.spec.ts index a0066483d..eb835e8fd 100644 --- a/src/layer/segmentation/index.spec.ts +++ b/src/layer/segmentation/index.spec.ts @@ -17,7 +17,7 @@ import { describe, expect, it, vi } from "vitest"; import type { RenderLayerTransform } from "#src/render_coordinate_transform.js"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; import { WatchableValue } from "#src/trackable_value.js"; if (!("WebGL2RenderingContext" in globalThis)) { diff --git a/src/layer/segmentation/index.ts b/src/layer/segmentation/index.ts index 5ef75d3f1..4cd9b41fa 100644 --- a/src/layer/segmentation/index.ts +++ b/src/layer/segmentation/index.ts @@ -95,17 +95,26 @@ import type { import { SegmentationGraphSourceTab } from "#src/segmentation_graph/source.js"; import { SharedDisjointUint64Sets } from "#src/shared_disjoint_sets.js"; import { SharedWatchableValue } from "#src/shared_watchable_value.js"; +import type { + SpatiallyIndexedSkeletonNode, + SpatialSkeletonSourceState, +} from "#src/skeleton/api.js"; import { DEFAULT_SPATIAL_SKELETON_EDIT_ACTIONS, getSpatialSkeletonActionSupportLabel, isSpatialSkeletonEditAction, SpatialSkeletonActions, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { - SpatiallyIndexedSkeletonNode, - SpatialSkeletonSourceState, -} from "#src/skeleton/api.js"; +} from "#src/skeleton/command_protocol.js"; +import { + executeSpatialSkeletonDeleteNode, + executeSpatialSkeletonNodeConfidenceUpdate, + executeSpatialSkeletonNodeDescriptionUpdate, + executeSpatialSkeletonNodeRadiusUpdate, + executeSpatialSkeletonReroot, + executeSpatialSkeletonNodeTrueEndUpdate, + showSpatialSkeletonActionError, +} from "#src/skeleton/commands.js"; import { PerspectiveViewSkeletonLayer, SkeletonLayer, @@ -129,15 +138,6 @@ import { SpatialSkeletonDisplayNodeType, SpatialSkeletonNodeFilterType, } from "#src/skeleton/node_types.js"; -import { - executeSpatialSkeletonDeleteNode, - executeSpatialSkeletonNodeConfidenceUpdate, - executeSpatialSkeletonNodeDescriptionUpdate, - executeSpatialSkeletonNodeRadiusUpdate, - executeSpatialSkeletonReroot, - executeSpatialSkeletonNodeTrueEndUpdate, - showSpatialSkeletonActionError, -} from "#src/skeleton/spatial_skeleton_commands.js"; import { editableSpatiallyIndexedSkeletonSourceSupportsAction, getEditableSpatiallyIndexedSkeletonSource, diff --git a/src/skeleton/command_factories.ts b/src/skeleton/command_factories.ts index f889601bc..5803a85a6 100644 --- a/src/skeleton/command_factories.ts +++ b/src/skeleton/command_factories.ts @@ -17,9 +17,9 @@ import type { SegmentationUserLayer } from "#src/layer/segmentation/index.js"; import { SpatialSkeletonActions, + type SpatialSkeletonCommand, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { SpatialSkeletonCommand } from "#src/skeleton/command_history.js"; +} from "#src/skeleton/command_protocol.js"; export type SpatialSkeletonCommandPayload = object; diff --git a/src/skeleton/command_history.spec.ts b/src/skeleton/command_history.spec.ts index ef3d36aaa..a7f2467d9 100644 --- a/src/skeleton/command_history.spec.ts +++ b/src/skeleton/command_history.spec.ts @@ -16,10 +16,8 @@ import { describe, expect, it } from "vitest"; -import { - SpatialSkeletonCommandHistory, - type SpatialSkeletonCommand, -} from "#src/skeleton/command_history.js"; +import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; +import { type SpatialSkeletonCommand } from "#src/skeleton/command_protocol.js"; function deferred() { let resolve: (() => void) | undefined; diff --git a/src/skeleton/command_history.ts b/src/skeleton/command_history.ts index 4ca709321..c81aa1801 100644 --- a/src/skeleton/command_history.ts +++ b/src/skeleton/command_history.ts @@ -14,22 +14,12 @@ * limitations under the License. */ +import type { SpatialSkeletonCommand } from "#src/skeleton/command_protocol.js"; import { WatchableValue } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; export const SPATIAL_SKELETON_COMMAND_HISTORY_MAX_ENTRIES = 100; -export interface SpatialSkeletonCommandContext { - readonly mappings: SpatialSkeletonCommandMappings; -} - -export interface SpatialSkeletonCommand { - readonly label: string; - execute(context: SpatialSkeletonCommandContext): Promise; - undo(context: SpatialSkeletonCommandContext): Promise; - redo?(context: SpatialSkeletonCommandContext): Promise; -} - interface SpatialSkeletonCommandMappingSnapshot { nodeIdMappings: Array<[number, number]>; segmentIdMappings: Array<[number, number]>; diff --git a/src/skeleton/actions.ts b/src/skeleton/command_protocol.ts similarity index 72% rename from src/skeleton/actions.ts rename to src/skeleton/command_protocol.ts index 283cb7a7a..77aaa775a 100644 --- a/src/skeleton/actions.ts +++ b/src/skeleton/command_protocol.ts @@ -72,3 +72,29 @@ export function getSpatialSkeletonActionSupportLabel( return "skeleton splitting"; } } + +export interface SpatialSkeletonCommandContext { + readonly mappings: { + resolveNodeId(nodeId: number | undefined): number | undefined; + resolveSegmentId(segmentId: number | undefined): number | undefined; + getStableNodeId(nodeId: number | undefined): number | undefined; + getStableSegmentId(segmentId: number | undefined): number | undefined; + getStableOrCurrentNodeId(nodeId: number | undefined): number | undefined; + getStableOrCurrentSegmentId(segmentId: number | undefined): number | undefined; + remapNodeId( + originalNodeId: number | undefined, + currentNodeId: number, + ): boolean; + remapSegmentId( + originalSegmentId: number | undefined, + currentSegmentId: number, + ): boolean; + }; +} + +export interface SpatialSkeletonCommand { + readonly label: string; + execute(context: SpatialSkeletonCommandContext): Promise; + undo(context: SpatialSkeletonCommandContext): Promise; + redo?(context: SpatialSkeletonCommandContext): Promise; +} diff --git a/src/skeleton/spatial_skeleton_commands.spec.ts b/src/skeleton/commands.spec.ts similarity index 99% rename from src/skeleton/spatial_skeleton_commands.spec.ts rename to src/skeleton/commands.spec.ts index 26db38d87..9987713a1 100644 --- a/src/skeleton/spatial_skeleton_commands.spec.ts +++ b/src/skeleton/commands.spec.ts @@ -19,14 +19,9 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { makeCatmaidNodeSourceState } from "#src/datasource/catmaid/api.js"; import { buildCatmaidNeighborhoodEditContext } from "#src/datasource/catmaid/edit_state.js"; import { CatmaidSpatialSkeletonEditCommands } from "#src/datasource/catmaid/spatial_skeleton_commands.js"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; -import { - findSpatiallyIndexedSkeletonNode, - getSpatiallyIndexedSkeletonDirectChildren, - getSpatiallyIndexedSkeletonNodeParent, -} from "#src/skeleton/node_traversal.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; import { executeSpatialSkeletonAddNode, executeSpatialSkeletonDeleteNode, @@ -41,7 +36,12 @@ import { executeSpatialSkeletonSplit, redoSpatialSkeletonCommand, undoSpatialSkeletonCommand, -} from "#src/skeleton/spatial_skeleton_commands.js"; +} from "#src/skeleton/commands.js"; +import { + findSpatiallyIndexedSkeletonNode, + getSpatiallyIndexedSkeletonDirectChildren, + getSpatiallyIndexedSkeletonNodeParent, +} from "#src/skeleton/node_traversal.js"; import { SpatialSkeletonState } from "#src/skeleton/spatial_skeleton_manager.js"; import { StatusMessage } from "#src/status.js"; diff --git a/src/skeleton/spatial_skeleton_commands.ts b/src/skeleton/commands.ts similarity index 98% rename from src/skeleton/spatial_skeleton_commands.ts rename to src/skeleton/commands.ts index 83731a5f0..73798994e 100644 --- a/src/skeleton/spatial_skeleton_commands.ts +++ b/src/skeleton/commands.ts @@ -14,10 +14,6 @@ * limitations under the License. */ -import { - SpatialSkeletonActions, - type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; import type { EditableSpatiallyIndexedSkeletonSource, SpatiallyIndexedSkeletonNode, @@ -26,7 +22,11 @@ import type { SpatialSkeletonCommandPayload, SpatialSkeletonEditCommandFactory, } from "#src/skeleton/command_factories.js"; -import type { SpatialSkeletonCommand } from "#src/skeleton/command_history.js"; +import { + SpatialSkeletonActions, + type SpatialSkeletonAction, + type SpatialSkeletonCommand, +} from "#src/skeleton/command_protocol.js"; import { getSpatialSkeletonActionErrorMessage } from "#src/skeleton/edit_errors.js"; import { getEditableSpatiallyIndexedSkeletonSource, @@ -69,7 +69,7 @@ function executeCommand( return layer.spatialSkeletonState.commandHistory.execute(command); } -function executeCommandWithPendingMessage( +async function executeCommandWithPendingMessage( promise: Promise, message: string, ) { diff --git a/src/skeleton/spatial_skeleton_manager.spec.ts b/src/skeleton/spatial_skeleton_manager.spec.ts index 64b7b4f54..02fa70e9c 100644 --- a/src/skeleton/spatial_skeleton_manager.spec.ts +++ b/src/skeleton/spatial_skeleton_manager.spec.ts @@ -16,7 +16,7 @@ import { describe, expect, it, vi } from "vitest"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; import { buildSpatiallyIndexedSkeletonNavigationGraph, getFlatListNodeIds, diff --git a/src/skeleton/spatial_skeleton_manager.ts b/src/skeleton/spatial_skeleton_manager.ts index d8d1c6538..ba3999613 100644 --- a/src/skeleton/spatial_skeleton_manager.ts +++ b/src/skeleton/spatial_skeleton_manager.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import type { SpatialSkeletonAction } from "#src/skeleton/actions.js"; import type { EditableSpatiallyIndexedSkeletonSource, SpatialSkeletonConfidenceConfiguration, @@ -29,6 +28,7 @@ import { SPATIAL_SKELETON_EDIT_COMMAND_METADATA, } from "#src/skeleton/command_factories.js"; import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; +import type { SpatialSkeletonAction } from "#src/skeleton/command_protocol.js"; import type { SpatiallyIndexedSkeletonLayer } from "#src/skeleton/frontend.js"; import { WatchableValue } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; diff --git a/src/ui/skeleton_edit_tools.spec.ts b/src/ui/skeleton_edit_tools.spec.ts index 4c60a6c76..340953cb5 100644 --- a/src/ui/skeleton_edit_tools.spec.ts +++ b/src/ui/skeleton_edit_tools.spec.ts @@ -18,16 +18,16 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { makeCatmaidNodeSourceState } from "#src/datasource/catmaid/api.js"; import { CatmaidSpatialSkeletonEditCommands } from "#src/datasource/catmaid/spatial_skeleton_commands.js"; +import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; +import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; import { SpatialSkeletonActions, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; -import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; +} from "#src/skeleton/command_protocol.js"; import { executeSpatialSkeletonAddNode, executeSpatialSkeletonMerge, -} from "#src/skeleton/spatial_skeleton_commands.js"; +} from "#src/skeleton/commands.js"; import { StatusMessage } from "#src/status.js"; if (!("WebGL2RenderingContext" in globalThis)) { diff --git a/src/ui/skeleton_edit_tools.ts b/src/ui/skeleton_edit_tools.ts index d93f385cd..b4ba8f486 100644 --- a/src/ui/skeleton_edit_tools.ts +++ b/src/ui/skeleton_edit_tools.ts @@ -25,11 +25,19 @@ import { PerspectivePanel } from "#src/perspective_view/panel.js"; import { getChunkPositionFromCombinedGlobalLocalPositions } from "#src/render_coordinate_transform.js"; import { RenderedDataPanel } from "#src/rendered_data_panel.js"; import { getVisibleSegments } from "#src/segmentation_display_state/base.js"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; import type { SpatialSkeletonSourceState, SpatialSkeletonVector, } from "#src/skeleton/api.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; +import { + executeSpatialSkeletonAddNode, + executeSpatialSkeletonDeleteNode, + executeSpatialSkeletonMerge, + executeSpatialSkeletonMoveNode, + executeSpatialSkeletonSplit, + showSpatialSkeletonActionError, +} from "#src/skeleton/commands.js"; import { type SpatiallyIndexedSkeletonLayer, setSpatialSkeletonModesToLinesAndPoints, @@ -38,14 +46,6 @@ import { PerspectiveViewSpatiallyIndexedSkeletonLayer, SliceViewPanelSpatiallyIndexedSkeletonLayer, } from "#src/skeleton/frontend.js"; -import { - executeSpatialSkeletonAddNode, - executeSpatialSkeletonDeleteNode, - executeSpatialSkeletonMerge, - executeSpatialSkeletonMoveNode, - executeSpatialSkeletonSplit, - showSpatialSkeletonActionError, -} from "#src/skeleton/spatial_skeleton_commands.js"; import { StatusMessage } from "#src/status.js"; import type { SpatialSkeletonToolPointInfo } from "#src/ui/skeleton_edit_tool_messages.js"; import { diff --git a/src/ui/skeleton_tab.ts b/src/ui/skeleton_tab.ts index 262816967..1c75f7f2c 100644 --- a/src/ui/skeleton_tab.ts +++ b/src/ui/skeleton_tab.ts @@ -36,11 +36,18 @@ import { getVisibleSegments, } from "#src/segmentation_display_state/base.js"; import { getBaseObjectColor } from "#src/segmentation_display_state/frontend.js"; +import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; import { SpatialSkeletonActions, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; +} from "#src/skeleton/command_protocol.js"; +import { + executeSpatialSkeletonDeleteNode, + executeSpatialSkeletonNodeTrueEndUpdate, + redoSpatialSkeletonCommand, + showSpatialSkeletonActionError, + undoSpatialSkeletonCommand, +} from "#src/skeleton/commands.js"; import { buildSpatiallyIndexedSkeletonNavigationGraph, getBranchEnd as getBranchEndFromGraph, @@ -60,13 +67,6 @@ import { SpatialSkeletonDisplayNodeType, SpatialSkeletonNodeFilterType, } from "#src/skeleton/node_types.js"; -import { - executeSpatialSkeletonDeleteNode, - executeSpatialSkeletonNodeTrueEndUpdate, - redoSpatialSkeletonCommand, - showSpatialSkeletonActionError, - undoSpatialSkeletonCommand, -} from "#src/skeleton/spatial_skeleton_commands.js"; import { StatusMessage } from "#src/status.js"; import { observeWatchable, registerNested } from "#src/trackable_value.js"; import { SPATIAL_SKELETON_EDIT_MODE_TOOL_ID } from "#src/ui/skeleton_edit_tools.js";