Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 15 additions & 26 deletions src/machines/sketchSolve/sketchSolveMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const equipTools = Object.freeze({
pointTool,
})

const CHILD_TOOL_ID = 'child tool'
const CHILD_TOOL_DONE_EVENT = `xstate.done.actor.${CHILD_TOOL_ID}`

export type EquipTool = keyof typeof equipTools

// Type for the spawn function used in XState setup actions
Expand All @@ -37,15 +40,9 @@ export type SketchSolveMachineEvent =
| { type: 'update selection'; data?: SetSelections }
| { type: 'unequip tool' }
| { type: 'equip tool'; data: { tool: EquipTool } }
| { type: 'xstate.done.actor.tool' }

type ToolActorRef =
| ActorRefFrom<typeof dimensionTool>
| ActorRefFrom<typeof centerRectTool>
| ActorRefFrom<typeof pointTool>
| { type: typeof CHILD_TOOL_DONE_EVENT }

type SketchSolveContext = ModelingMachineContext & {
toolActor?: ToolActorRef
sketchSolveToolName: EquipTool | null
pendingToolName?: EquipTool
}
Expand All @@ -56,18 +53,10 @@ export const sketchSolveMachine = setup({
events: {} as SketchSolveMachineEvent,
},
actions: {
'send unequip to tool': sendTo(
({ context }) => context.toolActor || 'moveTool',
{
type: 'unequip',
}
),
'send update selection to equipped tool': sendTo(
({ context }) => context.toolActor || 'moveTool',
{
type: 'update selection',
}
),
'send unequip to tool': sendTo(CHILD_TOOL_ID, { type: 'unequip' }),
'send update selection to equipped tool': sendTo(CHILD_TOOL_ID, {
type: 'update selection',
}),
'send updated selection to move tool': sendTo('moveTool', {
type: 'update selection',
}),
Expand All @@ -84,26 +73,26 @@ export const sketchSolveMachine = setup({
data: { tool: null },
}),
'spawn tool': assign(({ event, spawn, context }) => {
// this type-annotation informs spawn tool of the association between the EquipTools type and the machines in equipTools
// It's not an type assertion. TS still checks that _spawn is assignable to SpawnToolActor.
const typedSpawn: SpawnToolActor = spawn
// Determine which tool to spawn based on event type
let nameOfToolToSpawn: EquipTool

if (event.type === 'equip tool') {
nameOfToolToSpawn = event.data.tool
} else if (
event.type === 'xstate.done.actor.tool' &&
event.type === CHILD_TOOL_DONE_EVENT &&
context.pendingToolName
) {
nameOfToolToSpawn = context.pendingToolName
} else {
console.error('Cannot determine tool to spawn')
return {}
}
// this type-annotation informs spawn tool of the association between the EquipTools type and the machines in equipTools
// It's not an type assertion. TS still checks that _spawn is assignable to SpawnToolActor.
const typedSpawn: SpawnToolActor = spawn
typedSpawn(nameOfToolToSpawn, { id: CHILD_TOOL_ID })

return {
toolActor: typedSpawn(nameOfToolToSpawn, { id: 'tool' }),
sketchSolveToolName: nameOfToolToSpawn,
pendingToolName: undefined, // Clear the pending tool after spawning
}
Expand Down Expand Up @@ -188,7 +177,7 @@ export const sketchSolveMachine = setup({

'switching tool': {
on: {
'xstate.done.actor.tool': {
[CHILD_TOOL_DONE_EVENT]: {
target: 'using tool',
actions: [
() => console.log('switched tools with xstate.done.actor.tool'),
Expand All @@ -209,7 +198,7 @@ export const sketchSolveMachine = setup({

'unequipping tool': {
on: {
'xstate.done.actor.tool': {
[CHILD_TOOL_DONE_EVENT]: {
target: 'move and select',
actions: ['send tool unequipped to parent'],
},
Expand Down
Loading