/** 연장·결합·분해·지우기 (조사표 2절) */ import { toast } from 'react-toastify'; import { SELECT_OBJECTS } from '../../commands/prompt'; import type { Entity } from '../../entities/Entity'; import { addEntities, deleteEntities, setSelectedEntityIds } from '../../state'; import { Tool } from '../../tools'; import { createSequenceTool } from '../factories/sequence-tool'; import { explodeEntity, joinEntities } from './modify.helpers'; /** EXTEND 빠른 모드는 TRIM 과 한 머신 꼴(eraser-tool.ts) */ export { extendToolStateMachine } from '../eraser-tool'; export const joinToolStateMachine = createSequenceTool({ tool: Tool.JOIN, helpers: false, steps: [ { kind: 'selection', prompt: { text: '한 번에 결합할 원본 객체 또는 여러 객체 선택', options: SELECT_OBJECTS.options, }, }, ], commit: (input) => { const entities = input.entities(0); const joined = joinEntities(entities); if (!joined) { toast.warn('끝점이 맞닿는 객체가 없어 결합하지 못했습니다.'); return; } deleteEntities(entities, false); addEntities([joined], true); setSelectedEntityIds([]); }, }); export const explodeToolStateMachine = createSequenceTool({ tool: Tool.EXPLODE, helpers: false, steps: [{ kind: 'selection', instructions: '분해할 객체를 선택한 뒤 ENTER.' }], commit: (input) => { const entities = input.entities(0); const exploded: Entity[] = []; const consumed: Entity[] = []; for (const entity of entities) { const parts = explodeEntity(entity); if (parts.length) { exploded.push(...parts); consumed.push(entity); } } if (!consumed.length) { toast.info('분해할 수 있는 복합 객체가 없습니다.'); return; } deleteEntities(consumed, false); addEntities(exploded, true); setSelectedEntityIds([]); }, }); export const eraseToolStateMachine = createSequenceTool({ tool: Tool.ERASE, helpers: false, steps: [{ kind: 'selection', instructions: '지울 객체를 선택한 뒤 ENTER.' }], commit: (input) => { const entities = input.entities(0); if (!entities.length) return; deleteEntities(entities, true); setSelectedEntityIds([]); }, });