@@ -4,8 +4,8 @@
|
|||||||
import Accordion from "./gradio/app/Accordion.svelte";
|
import Accordion from "./gradio/app/Accordion.svelte";
|
||||||
import uiState from '$lib/stores/uiState';
|
import uiState from '$lib/stores/uiState';
|
||||||
import type { ComfyNodeDefInputType } from "$lib/ComfyNodeDef";
|
import type { ComfyNodeDefInputType } from "$lib/ComfyNodeDef";
|
||||||
import type { INodeInputSlot, LGraphNode, Subgraph } from "@litegraph-ts/core";
|
import type { INodeInputSlot, LGraphNode, LLink, Subgraph } from "@litegraph-ts/core";
|
||||||
import { UpstreamNodeLocator } from "./ComfyPromptSerializer";
|
import { UpstreamNodeLocator, getUpstreamLink } from "./ComfyPromptSerializer";
|
||||||
import JsonView from "./JsonView.svelte";
|
import JsonView from "./JsonView.svelte";
|
||||||
|
|
||||||
export let app: ComfyApp;
|
export let app: ComfyApp;
|
||||||
@@ -43,7 +43,10 @@
|
|||||||
// TODO multiple tags?
|
// TODO multiple tags?
|
||||||
const tag: string | null = error.queueEntry.extraData.extra_pnginfo.comfyBoxPrompt.subgraphs[0];
|
const tag: string | null = error.queueEntry.extraData.extra_pnginfo.comfyBoxPrompt.subgraphs[0];
|
||||||
|
|
||||||
const test = (node: LGraphNode) => (node as any).isBackendNode
|
const test = (node: LGraphNode, currentLink: LLink) => {
|
||||||
|
const [nextGraph, nextLink, nextInputSlot, nextNode] = getUpstreamLink(node, currentLink)
|
||||||
|
return nextLink == null;
|
||||||
|
};
|
||||||
const nodeLocator = new UpstreamNodeLocator(test)
|
const nodeLocator = new UpstreamNodeLocator(test)
|
||||||
const [_, foundLink, foundInputSlot, foundPrevNode] = nodeLocator.locateUpstream(node, inputIndex, tag);
|
const [_, foundLink, foundInputSlot, foundPrevNode] = nodeLocator.locateUpstream(node, inputIndex, tag);
|
||||||
|
|
||||||
|
|||||||
@@ -71,13 +71,9 @@ export function isActiveBackendNode(node: LGraphNode, tag: string | null = null)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpstreamResult = [LGraph | null, LLink | null, number | null, LGraphNode | null];
|
export type UpstreamResult = [LGraph | null, LLink | null, number | null, LGraphNode | null];
|
||||||
|
|
||||||
export class UpstreamNodeLocator {
|
function followSubgraph(subgraph: Subgraph, link: LLink): UpstreamResult {
|
||||||
constructor(private isTheTargetNode: (node: LGraphNode) => boolean) {
|
|
||||||
}
|
|
||||||
|
|
||||||
private followSubgraph(subgraph: Subgraph, link: LLink): UpstreamResult {
|
|
||||||
if (link.origin_id != subgraph.id)
|
if (link.origin_id != subgraph.id)
|
||||||
throw new Error("Invalid link and graph output!")
|
throw new Error("Invalid link and graph output!")
|
||||||
|
|
||||||
@@ -89,7 +85,7 @@ export class UpstreamNodeLocator {
|
|||||||
return [innerGraphOutput.graph, nextLink, 0, innerGraphOutput];
|
return [innerGraphOutput.graph, nextLink, 0, innerGraphOutput];
|
||||||
}
|
}
|
||||||
|
|
||||||
private followGraphInput(graphInput: GraphInput, link: LLink): UpstreamResult {
|
function followGraphInput(graphInput: GraphInput, link: LLink): UpstreamResult {
|
||||||
if (link.origin_id != graphInput.id)
|
if (link.origin_id != graphInput.id)
|
||||||
throw new Error("Invalid link and graph input!")
|
throw new Error("Invalid link and graph input!")
|
||||||
|
|
||||||
@@ -105,14 +101,14 @@ export class UpstreamNodeLocator {
|
|||||||
return [outerSubgraph.graph, nextLink, outerInputIndex, outerSubgraph];
|
return [outerSubgraph.graph, nextLink, outerInputIndex, outerSubgraph];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getUpstreamLink(parent: LGraphNode, currentLink: LLink): UpstreamResult {
|
export function getUpstreamLink(parent: LGraphNode, currentLink: LLink): UpstreamResult {
|
||||||
if (parent.is(Subgraph)) {
|
if (parent.is(Subgraph)) {
|
||||||
console.debug("FollowSubgraph")
|
console.debug("FollowSubgraph")
|
||||||
return this.followSubgraph(parent, currentLink);
|
return followSubgraph(parent, currentLink);
|
||||||
}
|
}
|
||||||
else if (parent.is(GraphInput)) {
|
else if (parent.is(GraphInput)) {
|
||||||
console.debug("FollowGraphInput")
|
console.debug("FollowGraphInput")
|
||||||
return this.followGraphInput(parent, currentLink);
|
return followGraphInput(parent, currentLink);
|
||||||
}
|
}
|
||||||
else if ("getUpstreamLink" in parent) {
|
else if ("getUpstreamLink" in parent) {
|
||||||
const link = (parent as ComfyGraphNode).getUpstreamLink();
|
const link = (parent as ComfyGraphNode).getUpstreamLink();
|
||||||
@@ -129,6 +125,10 @@ export class UpstreamNodeLocator {
|
|||||||
return [null, null, null, null];
|
return [null, null, null, null];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class UpstreamNodeLocator {
|
||||||
|
constructor(private isTheTargetNode: (node: LGraphNode, currentLink: LLink) => boolean) {
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Traverses the graph upstream from outputs towards inputs across
|
* Traverses the graph upstream from outputs towards inputs across
|
||||||
* a sequence of nodes dependent on a condition.
|
* a sequence of nodes dependent on a condition.
|
||||||
@@ -146,8 +146,8 @@ export class UpstreamNodeLocator {
|
|||||||
let currentInputSlot = inputIndex;
|
let currentInputSlot = inputIndex;
|
||||||
let currentNode = fromNode;
|
let currentNode = fromNode;
|
||||||
|
|
||||||
const shouldFollowParent = (parent: LGraphNode) => {
|
const shouldFollowParent = (parent: LGraphNode, currentLink: LLink) => {
|
||||||
return isActiveNode(parent, tag) && !this.isTheTargetNode(parent);
|
return isActiveNode(parent, tag) && !this.isTheTargetNode(parent, currentLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are non-target nodes between us and another
|
// If there are non-target nodes between us and another
|
||||||
@@ -156,8 +156,8 @@ export class UpstreamNodeLocator {
|
|||||||
// will simply follow their single input, while branching
|
// will simply follow their single input, while branching
|
||||||
// nodes have conditional logic that determines which link
|
// nodes have conditional logic that determines which link
|
||||||
// to follow backwards.
|
// to follow backwards.
|
||||||
while (shouldFollowParent(parent)) {
|
while (shouldFollowParent(parent, currentLink)) {
|
||||||
const [nextGraph, nextLink, nextInputSlot, nextNode] = this.getUpstreamLink(parent, currentLink);
|
const [nextGraph, nextLink, nextInputSlot, nextNode] = getUpstreamLink(parent, currentLink);
|
||||||
|
|
||||||
currentInputSlot = nextInputSlot;
|
currentInputSlot = nextInputSlot;
|
||||||
currentNode = nextNode;
|
currentNode = nextNode;
|
||||||
@@ -183,7 +183,7 @@ export class UpstreamNodeLocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isActiveNode(parent, tag) || !this.isTheTargetNode(parent) || currentLink == null)
|
if (!isActiveNode(parent, tag) || !this.isTheTargetNode(parent, currentLink) || currentLink == null)
|
||||||
return [null, currentLink, currentInputSlot, currentNode];
|
return [null, currentLink, currentInputSlot, currentNode];
|
||||||
|
|
||||||
return [parent, currentLink, currentInputSlot, currentNode]
|
return [parent, currentLink, currentInputSlot, currentNode]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import ComfyGraphNode, { type ComfyGraphNodeProperties } from "./ComfyGraphNode"
|
|||||||
import { Watch } from "@litegraph-ts/nodes-basic";
|
import { Watch } from "@litegraph-ts/nodes-basic";
|
||||||
import { nextLetter } from "$lib/utils";
|
import { nextLetter } from "$lib/utils";
|
||||||
|
|
||||||
export type PickFirstMode = "anyActiveLink" | "truthy" | "dataNonNull"
|
export type PickFirstMode = "anyActiveLink" | "dataTruthy" | "dataNonNull"
|
||||||
|
|
||||||
export interface ComfyPickFirstNodeProperties extends ComfyGraphNodeProperties {
|
export interface ComfyPickFirstNodeProperties extends ComfyGraphNodeProperties {
|
||||||
mode: PickFirstMode
|
mode: PickFirstMode
|
||||||
@@ -12,7 +12,7 @@ export interface ComfyPickFirstNodeProperties extends ComfyGraphNodeProperties {
|
|||||||
export default class ComfyPickFirstNode extends ComfyGraphNode {
|
export default class ComfyPickFirstNode extends ComfyGraphNode {
|
||||||
override properties: ComfyPickFirstNodeProperties = {
|
override properties: ComfyPickFirstNodeProperties = {
|
||||||
tags: [],
|
tags: [],
|
||||||
mode: "dataNonNull"
|
mode: "anyActiveLink"
|
||||||
}
|
}
|
||||||
|
|
||||||
static slotLayout: SlotLayout = {
|
static slotLayout: SlotLayout = {
|
||||||
@@ -36,7 +36,7 @@ export default class ComfyPickFirstNode extends ComfyGraphNode {
|
|||||||
super(title);
|
super(title);
|
||||||
this.displayWidget = this.addWidget("text", "Value", "")
|
this.displayWidget = this.addWidget("text", "Value", "")
|
||||||
this.displayWidget.disabled = true;
|
this.displayWidget.disabled = true;
|
||||||
this.modeWidget = this.addWidget("combo", "Mode", this.properties.mode, null, { property: "mode", values: ["anyActiveLink", "truthy", "dataNonNull"] })
|
this.modeWidget = this.addWidget("combo", "Mode", this.properties.mode, null, { property: "mode", values: ["anyActiveLink", "dataTruthy", "dataNonNull"] })
|
||||||
}
|
}
|
||||||
|
|
||||||
override onDrawBackground(ctx: CanvasRenderingContext2D) {
|
override onDrawBackground(ctx: CanvasRenderingContext2D) {
|
||||||
@@ -45,7 +45,7 @@ export default class ComfyPickFirstNode extends ComfyGraphNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.selected === -1) {
|
if (this.selected === -1) {
|
||||||
// Draw an X
|
// Draw an X indicating nothing matched the selection criteria
|
||||||
const y = LiteGraph.NODE_SLOT_HEIGHT + 6;
|
const y = LiteGraph.NODE_SLOT_HEIGHT + 6;
|
||||||
ctx.lineWidth = 5;
|
ctx.lineWidth = 5;
|
||||||
ctx.strokeStyle = "red";
|
ctx.strokeStyle = "red";
|
||||||
@@ -60,6 +60,7 @@ export default class ComfyPickFirstNode extends ComfyGraphNode {
|
|||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Draw an arrow pointing to the selected input
|
||||||
ctx.fillStyle = "#AFB";
|
ctx.fillStyle = "#AFB";
|
||||||
const y = (this.selected) * LiteGraph.NODE_SLOT_HEIGHT + 6;
|
const y = (this.selected) * LiteGraph.NODE_SLOT_HEIGHT + 6;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -130,7 +131,7 @@ export default class ComfyPickFirstNode extends ComfyGraphNode {
|
|||||||
else {
|
else {
|
||||||
if (this.properties.mode === "dataNonNull")
|
if (this.properties.mode === "dataNonNull")
|
||||||
return link.data != null;
|
return link.data != null;
|
||||||
else if (this.properties.mode === "truthy")
|
else if (this.properties.mode === "dataTruthy")
|
||||||
return Boolean(link.data)
|
return Boolean(link.data)
|
||||||
else // anyActiveLink
|
else // anyActiveLink
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user