- Follow-up on #862
- Corrects issues with floating reroute switch logic
- Updates test expectations
This commit is contained in:
filtered
2025-03-28 09:00:58 +11:00
committed by GitHub
parent 59317bcda7
commit 7b3ea64714
3 changed files with 53 additions and 6 deletions

View File

@@ -59,6 +59,18 @@ export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
this.#color = value === "" ? null : value
}
public get isFloatingOutput(): boolean {
return this.origin_id === -1 && this.origin_slot === -1
}
public get isFloatingInput(): boolean {
return this.target_id === -1 && this.target_slot === -1
}
public get isFloating(): boolean {
return this.isFloatingOutput || this.isFloatingInput
}
constructor(
id: LinkId,
type: ISlotType,
@@ -183,6 +195,28 @@ export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
return this.target_id === nodeId && this.target_slot === inputIndex
}
/**
* Creates a floating link from this link.
* @param slotType The side of the link that is still connected
* @param parentId The parent reroute ID of the link
* @returns A new LLink that is floating
*/
toFloating(slotType: "input" | "output", parentId: RerouteId): LLink {
const exported = this.asSerialisable()
exported.id = -1
exported.parentId = parentId
if (slotType === "input") {
exported.origin_id = -1
exported.origin_slot = -1
} else {
exported.target_id = -1
exported.target_slot = -1
}
return LLink.create(exported)
}
/**
* Disconnects a link and removes it from the graph, cleaning up any reroutes that are no longer used
* @param network The container (LGraph) where reroutes should be updated

View File

@@ -65,8 +65,6 @@ export class ToInputRenderLink implements RenderLink {
// Set the parentId of the reroute we dropped on, to the reroute we dragged from
reroute.parentId = fromReroute?.id
// Keep reroutes when disconnecting the original link
existingLink.disconnect(this.network, "output")
const newLink = outputNode.connectSlots(fromSlot, inputNode, input, existingLink.parentId)
// Connecting from the final reroute of a floating reroute chain
@@ -77,7 +75,17 @@ export class ToInputRenderLink implements RenderLink {
if (reroute.id === fromReroute?.id) break
reroute.removeLink(existingLink)
if (reroute.totalLinks === 0) reroute.remove()
if (reroute.totalLinks === 0) {
if (existingLink.isFloating) {
// Cannot float from both sides - remove
reroute.remove()
} else {
// Convert to floating
const cl = existingLink.toFloating("output", reroute.id)
this.network.addFloatingLink(cl)
reroute.floating = { slotType: "output" }
}
}
}
events.dispatch("link-created", newLink)
}

View File

@@ -734,7 +734,7 @@ describe("LinkConnector Integration", () => {
for (const [index, parentId] of parentIds.entries()) {
const reroute = graph.reroutes.get(parentId)!
if (linksAfter[index] === undefined) {
expect(reroute).toBeUndefined()
expect(reroute).not.toBeUndefined()
} else {
expect(reroute.linkIds.size).toBe(linksAfter[index])
}
@@ -852,10 +852,15 @@ describe("LinkConnector Integration", () => {
expect([...toReroute.linkIds.values()]).toEqual(nextLinkIds)
// Parent reroutes should have lost the links or been removed
for (const rerouteId of shouldBeRemoved) {
const reroute = graph.reroutes.get(rerouteId)!
expect(reroute).toBeUndefined()
if (testFloatingInputs) {
// Already-floating reroutes should be removed
expect(reroute).toBeUndefined()
} else {
// Non-floating reroutes should still exist
expect(reroute).not.toBeUndefined()
}
}
for (const rerouteId of shouldHaveLinkIdsRemoved) {