Show executing status/progress on subgraphs
This commit is contained in:
@@ -104,7 +104,7 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
|
|||||||
let state = get(queueState);
|
let state = get(queueState);
|
||||||
let ss = get(selectionState);
|
let ss = get(selectionState);
|
||||||
|
|
||||||
const isRunningNode = node.id == state.runningNodeID
|
const isExecuting = state.executingNodes.has(node.id);
|
||||||
const nodeErrors = this.activeErrors?.errorsByID[node.id];
|
const nodeErrors = this.activeErrors?.errorsByID[node.id];
|
||||||
const isHighlightedNode = this.highlightNodeAndInput && this.highlightNodeAndInput[0].id === node.id;
|
const isHighlightedNode = this.highlightNodeAndInput && this.highlightNodeAndInput[0].id === node.id;
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
|
|||||||
else if (ss.currentHoveredNodes.has(node.id)) {
|
else if (ss.currentHoveredNodes.has(node.id)) {
|
||||||
color = "lightblue";
|
color = "lightblue";
|
||||||
}
|
}
|
||||||
else if (isRunningNode) {
|
else if (isExecuting) {
|
||||||
color = "#0f0";
|
color = "#0f0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ export default class ComfyGraphCanvas extends LGraphCanvas {
|
|||||||
this.drawNodeOutline(node, ctx, size, mouseOver, fgColor, bgColor, color, thickness)
|
this.drawNodeOutline(node, ctx, size, mouseOver, fgColor, bgColor, color, thickness)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRunningNode && state.progress) {
|
if (isExecuting && state.progress) {
|
||||||
ctx.fillStyle = "green";
|
ctx.fillStyle = "green";
|
||||||
ctx.fillRect(0, 0, size[0] * (state.progress.value / state.progress.max), 6);
|
ctx.fillRect(0, 0, size[0] * (state.progress.value / state.progress.max), 6);
|
||||||
ctx.fillStyle = bgColor;
|
ctx.fillStyle = bgColor;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { v4 as uuidv4 } from "uuid";
|
|||||||
import workflowState, { type WorkflowError, type WorkflowExecutionError, type WorkflowInstID, type WorkflowValidationError } from "./workflowState";
|
import workflowState, { type WorkflowError, type WorkflowExecutionError, type WorkflowInstID, type WorkflowValidationError } from "./workflowState";
|
||||||
import configState from "./configState";
|
import configState from "./configState";
|
||||||
import uiQueueState from "./uiQueueState";
|
import uiQueueState from "./uiQueueState";
|
||||||
|
import type { NodeID } from "@litegraph-ts/core";
|
||||||
|
|
||||||
export type QueueEntryStatus = "success" | "validation_failed" | "error" | "interrupted" | "all_cached" | "unknown";
|
export type QueueEntryStatus = "success" | "validation_failed" | "error" | "interrupted" | "all_cached" | "unknown";
|
||||||
|
|
||||||
@@ -81,7 +82,21 @@ export type QueueState = {
|
|||||||
queuePending: Writable<QueueEntry[]>,
|
queuePending: Writable<QueueEntry[]>,
|
||||||
queueCompleted: Writable<CompletedQueueEntry[]>,
|
queueCompleted: Writable<CompletedQueueEntry[]>,
|
||||||
queueRemaining: number | "X" | null;
|
queueRemaining: number | "X" | null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently executing node if any
|
||||||
|
*/
|
||||||
runningNodeID: ComfyNodeID | null;
|
runningNodeID: ComfyNodeID | null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nodes which should be rendered as "executing" in the frontend (green border).
|
||||||
|
* This includes the running node and all its parent subgraphs
|
||||||
|
*/
|
||||||
|
executingNodes: Set<NodeID>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Progress for the current node reported by the frontend
|
||||||
|
*/
|
||||||
progress: Progress | null,
|
progress: Progress | null,
|
||||||
/**
|
/**
|
||||||
* If true, user pressed the "Interrupt" button in the frontend. Disable the
|
* If true, user pressed the "Interrupt" button in the frontend. Disable the
|
||||||
@@ -98,6 +113,7 @@ const store: Writable<QueueState> = writable({
|
|||||||
queueCompleted: writable([]),
|
queueCompleted: writable([]),
|
||||||
queueRemaining: null,
|
queueRemaining: null,
|
||||||
runningNodeID: null,
|
runningNodeID: null,
|
||||||
|
executingNodes: new Set(),
|
||||||
progress: null,
|
progress: null,
|
||||||
isInterrupting: false
|
isInterrupting: false
|
||||||
})
|
})
|
||||||
@@ -272,6 +288,7 @@ function executingUpdated(promptID: PromptID, runningNodeID: ComfyNodeID | null)
|
|||||||
|
|
||||||
store.update((s) => {
|
store.update((s) => {
|
||||||
s.progress = null;
|
s.progress = null;
|
||||||
|
s.executingNodes.clear();
|
||||||
|
|
||||||
const [index, entry, queue] = findEntryInPending(promptID);
|
const [index, entry, queue] = findEntryInPending(promptID);
|
||||||
if (runningNodeID != null) {
|
if (runningNodeID != null) {
|
||||||
@@ -279,6 +296,17 @@ function executingUpdated(promptID: PromptID, runningNodeID: ComfyNodeID | null)
|
|||||||
entry.nodesRan.add(runningNodeID)
|
entry.nodesRan.add(runningNodeID)
|
||||||
}
|
}
|
||||||
s.runningNodeID = runningNodeID;
|
s.runningNodeID = runningNodeID;
|
||||||
|
|
||||||
|
if (entry?.extraData?.workflowID) {
|
||||||
|
const workflow = workflowState.getWorkflow(entry.extraData.workflowID);
|
||||||
|
if (workflow != null) {
|
||||||
|
let node = workflow.graph.getNodeByIdRecursive(s.runningNodeID);
|
||||||
|
while (node != null) {
|
||||||
|
s.executingNodes.add(node.id);
|
||||||
|
node = node.graph?._subgraph_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Prompt finished executing.
|
// Prompt finished executing.
|
||||||
@@ -310,6 +338,7 @@ function executingUpdated(promptID: PromptID, runningNodeID: ComfyNodeID | null)
|
|||||||
}
|
}
|
||||||
s.progress = null;
|
s.progress = null;
|
||||||
s.runningNodeID = null;
|
s.runningNodeID = null;
|
||||||
|
s.executingNodes.clear();
|
||||||
}
|
}
|
||||||
entry_ = entry;
|
entry_ = entry;
|
||||||
return s
|
return s
|
||||||
@@ -334,6 +363,7 @@ function executionCached(promptID: PromptID, nodes: ComfyNodeID[]) {
|
|||||||
s.isInterrupting = false; // TODO move to start
|
s.isInterrupting = false; // TODO move to start
|
||||||
s.progress = null;
|
s.progress = null;
|
||||||
s.runningNodeID = null;
|
s.runningNodeID = null;
|
||||||
|
s.executingNodes.clear();
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -351,6 +381,7 @@ function executionError(error: ComfyExecutionError): CompletedQueueEntry | null
|
|||||||
}
|
}
|
||||||
s.progress = null;
|
s.progress = null;
|
||||||
s.runningNodeID = null;
|
s.runningNodeID = null;
|
||||||
|
s.executingNodes.clear();
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
return entry_;
|
return entry_;
|
||||||
@@ -384,6 +415,8 @@ function executionStart(promptID: PromptID) {
|
|||||||
moveToRunning(index, queue)
|
moveToRunning(index, queue)
|
||||||
}
|
}
|
||||||
s.isInterrupting = false;
|
s.isInterrupting = false;
|
||||||
|
s.runningNodeID = null;
|
||||||
|
s.executingNodes.clear();
|
||||||
return s
|
return s
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -448,6 +481,7 @@ function queueCleared(type: QueueItemType) {
|
|||||||
s.queueRemaining = 0;
|
s.queueRemaining = 0;
|
||||||
s.runningNodeID = null;
|
s.runningNodeID = null;
|
||||||
s.progress = null;
|
s.progress = null;
|
||||||
|
s.executingNodes.clear();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
s.queueCompleted.set([])
|
s.queueCompleted.set([])
|
||||||
|
|||||||
Reference in New Issue
Block a user