task(A4.1): wire dispatcher to canvas - doc bridge, selection bridge, activeTool sync
This commit is contained in:
@@ -14,6 +14,9 @@ import { GroupManager } from '../tools/modification/GroupTool';
|
||||
import { formatCoordinate } from '../utils/format';
|
||||
import { InteractionDispatcher } from '../interaction/dispatcher';
|
||||
import { logger } from '../utils/logger';
|
||||
import { CADDocument } from '../kernel/document/CADDocument';
|
||||
import { YjsDocument } from '../crdt/YjsDocument';
|
||||
import { pluginRegistry } from '../plugins';
|
||||
|
||||
const CanvasArea: React.FC<CanvasAreaProps> = ({
|
||||
cursorPos, viewMode, onViewChange, gridEnabled, orthoEnabled, snapEnabled,
|
||||
@@ -29,6 +32,8 @@ const CanvasArea: React.FC<CanvasAreaProps> = ({
|
||||
const renderEngineRef = useRef<RenderEngine | null>(null);
|
||||
const interactionRef = useRef<InteractionEngine | null>(null);
|
||||
const dispatcherRef = useRef<InteractionDispatcher | null>(null);
|
||||
/** Bereits an onElementCreated gemeldete V2-Element-IDs (verhindert Doppelmeldung bei jedem onChanged-Frame). */
|
||||
const announcedV2Ids = useRef<Set<string>>(new Set());
|
||||
const spatialIndexRef = useRef<SpatialIndex | null>(null);
|
||||
const layerManagerRef = useRef<LayerManager | null>(null);
|
||||
const selectionEngineRef = useRef<SelectionEngine | null>(null);
|
||||
@@ -47,17 +52,38 @@ const CanvasArea: React.FC<CanvasAreaProps> = ({
|
||||
canvas, zoomPan, renderEngine, snapEngine, selectionEngine, spatialIndex, layerManager,
|
||||
);
|
||||
|
||||
// ── Task A2: V2-Tool-Dispatcher hinter Feature-Flag ──
|
||||
// Flag VITE_TOOL_DISPATCHER=v2 (in .env / Shell): aktiviert den neuen
|
||||
// InteractionDispatcher parallel zur Legacy InteractionEngine.
|
||||
// Tools mit handlers werden dann über die Plugin-API v2 geroutet.
|
||||
// ── Task A2/A4: V2-Tool-Dispatcher hinter Feature-Flag ──
|
||||
// Flag VITE_TOOL_DISPATCHER=v2: aktiviert den InteractionDispatcher UND
|
||||
// verdrahtet ihn mit einem lokalen CADDocument + SelectionBridge (Task A4.1).
|
||||
if (import.meta.env.VITE_TOOL_DISPATCHER === 'v2') {
|
||||
const ydoc = new YjsDocument();
|
||||
ydoc.data.layers.set('layer-0', {
|
||||
id: 'layer-0', name: 'Standard', visible: true, locked: false,
|
||||
color: '#ffffff', lineType: 'solid', transparency: 0, sortOrder: 0, parentId: null,
|
||||
} as never);
|
||||
const v2Doc = new CADDocument(ydoc);
|
||||
// Committete V2-Elemente fließen über den etablierten Kanal in UI/State:
|
||||
v2Doc.onChanged(() => {
|
||||
for (const el of v2Doc.getAllElements()) {
|
||||
if (!announcedV2Ids.current.has(el.id)) {
|
||||
announcedV2Ids.current.add(el.id);
|
||||
onElementCreated(el);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dispatcherRef.current = new InteractionDispatcher(canvas, {
|
||||
zoomPan,
|
||||
setStatus: (msg) => {
|
||||
/* StatusBar-Bridge folgt in A3 */
|
||||
/* StatusBar-Bridge folgt in A4 */
|
||||
},
|
||||
setPreview: (el) => renderEngine.setPreviewElement(el as CADElement | null),
|
||||
getDoc: () => v2Doc,
|
||||
getSelectionBridge: () => ({
|
||||
getIds: () => Array.from(selectionEngine.getSelectedIds()),
|
||||
setIds: (ids) => selectionEngine.selectByIds(ids, false),
|
||||
hitTest: (wx, wy, tol) => renderEngine.hitTest(wx, wy, tol),
|
||||
}),
|
||||
});
|
||||
logger.info('InteractionDispatcher v2 aktiviert (VITE_TOOL_DISPATCHER=v2)');
|
||||
}
|
||||
@@ -249,6 +275,11 @@ const CanvasArea: React.FC<CanvasAreaProps> = ({
|
||||
const interaction = interactionRef.current;
|
||||
if (!interaction) return;
|
||||
interaction.setTool(activeTool as ToolType);
|
||||
// Task A4.1: V2-Werkzeuge zusätzlich an den Dispatcher routen (Flag aktiv).
|
||||
// Legacy bleibt parallel aktiv für noch nicht migrierte Tools.
|
||||
dispatcherRef.current?.setActive(
|
||||
pluginRegistry.getToolV2(activeTool) ? activeTool : null,
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeTool]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user