Skip to content

Commit fafd374

Browse files
committed
Add linkDropOrchestrator
1 parent d2f3051 commit fafd374

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import type { LGraph } from '@/lib/litegraph/src/LGraph'
2+
import type { LinkConnectorAdapter } from '@/renderer/core/canvas/links/linkConnectorAdapter'
3+
import type { SlotDropCandidate } from '@/renderer/core/canvas/links/slotLinkDragState'
4+
import { getSlotKey } from '@/renderer/core/layout/slots/slotIdentifier'
5+
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
6+
import type { SlotLinkDragSession } from '@/renderer/extensions/vueNodes/composables/slotLinkDragSession'
7+
8+
interface DropResolutionContext {
9+
adapter: LinkConnectorAdapter | null
10+
graph: LGraph | null
11+
session: SlotLinkDragSession
12+
}
13+
14+
export const resolveSlotTargetCandidate = (
15+
target: EventTarget | null,
16+
{ adapter, graph, session }: DropResolutionContext
17+
): SlotDropCandidate | null => {
18+
if (!(target instanceof HTMLElement)) return null
19+
20+
const elWithKey = target.closest<HTMLElement>('[data-slot-key]')
21+
const key = elWithKey?.dataset['slotKey']
22+
if (!key) return null
23+
24+
const layout = layoutStore.getSlotLayout(key)
25+
if (!layout) return null
26+
27+
const candidate: SlotDropCandidate = { layout, compatible: false }
28+
29+
if (adapter && graph) {
30+
const cached = session.compatCache.get(key)
31+
if (cached != null) {
32+
candidate.compatible = cached
33+
} else {
34+
const nodeId = Number(layout.nodeId)
35+
const compatible =
36+
layout.type === 'input'
37+
? adapter.isInputValidDrop(nodeId, layout.index)
38+
: adapter.isOutputValidDrop(nodeId, layout.index)
39+
40+
session.compatCache.set(key, compatible)
41+
candidate.compatible = compatible
42+
}
43+
}
44+
45+
return candidate
46+
}
47+
48+
export const resolveNodeSurfaceCandidate = (
49+
target: EventTarget | null,
50+
{ adapter, graph, session }: DropResolutionContext
51+
): SlotDropCandidate | null => {
52+
if (!(target instanceof HTMLElement)) return null
53+
54+
const elWithNode = target.closest<HTMLElement>('[data-node-id]')
55+
const nodeIdStr = elWithNode?.dataset['nodeId']
56+
if (!nodeIdStr) return null
57+
58+
if (!adapter || !graph) return null
59+
60+
const nodeId = Number(nodeIdStr)
61+
62+
const cachedPreferred = session.nodePreferred.get(nodeId)
63+
if (cachedPreferred !== undefined) {
64+
return cachedPreferred
65+
? { layout: cachedPreferred.layout, compatible: true }
66+
: null
67+
}
68+
69+
const node = graph.getNodeById(nodeId)
70+
if (!node) return null
71+
72+
const firstLink = adapter.renderLinks[0]
73+
if (!firstLink) return null
74+
75+
const connectingTo = adapter.linkConnector.state.connectingTo
76+
if (connectingTo !== 'input' && connectingTo !== 'output') return null
77+
78+
const isInput = connectingTo === 'input'
79+
const slotType = firstLink.fromSlot.type
80+
81+
const result = isInput
82+
? node.findInputByType(slotType)
83+
: node.findOutputByType(slotType)
84+
85+
const index = result?.index
86+
if (index == null) {
87+
session.nodePreferred.set(nodeId, null)
88+
return null
89+
}
90+
91+
const key = getSlotKey(String(nodeId), index, isInput)
92+
const layout = layoutStore.getSlotLayout(key)
93+
if (!layout) {
94+
session.nodePreferred.set(nodeId, null)
95+
return null
96+
}
97+
98+
const compatible = isInput
99+
? adapter.isInputValidDrop(nodeId, index)
100+
: adapter.isOutputValidDrop(nodeId, index)
101+
102+
session.compatCache.set(key, compatible)
103+
104+
if (!compatible) {
105+
session.nodePreferred.set(nodeId, null)
106+
return null
107+
}
108+
109+
const preferred = { index, key, layout }
110+
session.nodePreferred.set(nodeId, preferred)
111+
112+
return { layout, compatible: true }
113+
}

0 commit comments

Comments
 (0)