mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-06 16:10:09 +00:00
- Splits link connect logic out of `LinkConnector` to individual `RenderLink` classes - Add support for connecting / reconnecting reroutes in various configurations - Adds support for moving existing floating links from outputs / inputs - Fixes numerous corruption issues when reconnecting reroutes / moving links - Tests in separate PR #816
83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
import type { RenderLink } from "./RenderLink"
|
|
import type { LinkConnectorEventTarget } from "@/infrastructure/LinkConnectorEventTarget"
|
|
import type { LinkNetwork, Point } from "@/interfaces"
|
|
import type { LGraphNode } from "@/LGraphNode"
|
|
import type { INodeInputSlot, INodeOutputSlot, LLink } from "@/litegraph"
|
|
import type { Reroute } from "@/Reroute"
|
|
|
|
import { LinkDirection } from "@/types/globalEnums"
|
|
|
|
/** Connecting TO an input slot. */
|
|
|
|
export class ToInputRenderLink implements RenderLink {
|
|
readonly toType = "input"
|
|
readonly fromPos: Point
|
|
readonly fromSlotIndex: number
|
|
fromDirection: LinkDirection = LinkDirection.RIGHT
|
|
|
|
constructor(
|
|
readonly network: LinkNetwork,
|
|
readonly node: LGraphNode,
|
|
readonly fromSlot: INodeOutputSlot,
|
|
readonly fromReroute?: Reroute,
|
|
public dragDirection: LinkDirection = LinkDirection.CENTER,
|
|
) {
|
|
const outputIndex = node.outputs.indexOf(fromSlot)
|
|
if (outputIndex === -1) throw new Error(`Creating render link for node [${this.node.id}] failed: Slot index not found.`)
|
|
|
|
this.fromSlotIndex = outputIndex
|
|
this.fromPos = fromReroute
|
|
? fromReroute.pos
|
|
: this.node.getOutputPos(outputIndex)
|
|
}
|
|
|
|
connectToInput(node: LGraphNode, input: INodeInputSlot, events: LinkConnectorEventTarget) {
|
|
const { node: outputNode, fromSlot, fromReroute } = this
|
|
if (node === outputNode) return
|
|
|
|
const newLink = outputNode.connectSlots(fromSlot, node, input, fromReroute?.id)
|
|
events.dispatch("link-created", newLink)
|
|
}
|
|
|
|
connectToRerouteInput(
|
|
reroute: Reroute,
|
|
{
|
|
node: inputNode,
|
|
input,
|
|
link: existingLink,
|
|
}: { node: LGraphNode, input: INodeInputSlot, link: LLink },
|
|
events: LinkConnectorEventTarget,
|
|
originalReroutes: Reroute[],
|
|
) {
|
|
const { node: outputNode, fromSlot, fromReroute } = this
|
|
|
|
// Check before creating new link overwrites the value
|
|
const floatingTerminus = fromReroute?.floating?.slotType === "output"
|
|
|
|
// Set the parentId of the reroute we dropped on, to the reroute we dragged from
|
|
reroute.parentId = fromReroute?.id
|
|
|
|
const newLink = outputNode.connectSlots(fromSlot, inputNode, input, existingLink.parentId)
|
|
|
|
// Connecting from the final reroute of a floating reroute chain
|
|
if (floatingTerminus) fromReroute.removeAllFloatingLinks()
|
|
|
|
// Clean up reroutes
|
|
for (const reroute of originalReroutes) {
|
|
if (reroute.id === fromReroute?.id) break
|
|
|
|
reroute.removeLink(existingLink)
|
|
if (reroute.totalLinks === 0) reroute.remove()
|
|
}
|
|
events.dispatch("link-created", newLink)
|
|
}
|
|
|
|
connectToOutput() {
|
|
throw new Error("ToInputRenderLink cannot connect to an output.")
|
|
}
|
|
|
|
connectToRerouteOutput() {
|
|
throw new Error("ToInputRenderLink cannot connect to an output.")
|
|
}
|
|
}
|