191 lines
6.5 KiB
JavaScript
191 lines
6.5 KiB
JavaScript
import { app } from "../../scripts/app.js";
|
|
import { api } from "../../scripts/api.js";
|
|
|
|
function formatExecutionTime(time) {
|
|
return `${(time / 1000.0).toFixed(2)}s`;
|
|
}
|
|
|
|
function getNodeName(node) {
|
|
return node.displayName || node.name || node.title || node.type || node.constructor.name || "Unknown";
|
|
}
|
|
|
|
function drawBadge(node, orig, restArgs, totalTime, isLastNode) {
|
|
let ctx = restArgs[0];
|
|
const r = orig?.apply?.(node, restArgs);
|
|
|
|
if (!node.flags.collapsed && node.constructor.title_mode != LiteGraph.NO_TITLE) {
|
|
let text = "";
|
|
let bgColor = "#ffa500"; // 正在执行时为橙色
|
|
|
|
if (isLastNode && totalTime !== undefined) {
|
|
text = `Total: ${formatExecutionTime(totalTime)}`;
|
|
bgColor = "#EF596E"; // 高亮的红色
|
|
} else if (node.ty_et_execution_time !== undefined) {
|
|
text = formatExecutionTime(node.ty_et_execution_time); // 直接显示时间值
|
|
bgColor = "#29b560"; // 执行完成后为绿色
|
|
}
|
|
|
|
if (!text) {
|
|
return r;
|
|
}
|
|
|
|
ctx.save();
|
|
ctx.font = "12px sans-serif";
|
|
const textSize = ctx.measureText(text);
|
|
const paddingHorizontal = 6;
|
|
const badgeWidth = textSize.width + paddingHorizontal * 2;
|
|
const badgeHeight = 20;
|
|
|
|
// 清除当前节点的绘制内容
|
|
ctx.clearRect(0, -LiteGraph.NODE_TITLE_HEIGHT - badgeHeight, badgeWidth, badgeHeight);
|
|
ctx.fillStyle = bgColor;
|
|
ctx.beginPath();
|
|
ctx.roundRect(0, -LiteGraph.NODE_TITLE_HEIGHT - badgeHeight, badgeWidth, badgeHeight, 5);
|
|
ctx.fill();
|
|
|
|
ctx.fillStyle = "white";
|
|
ctx.fillText(text, paddingHorizontal, -LiteGraph.NODE_TITLE_HEIGHT - paddingHorizontal);
|
|
ctx.restore();
|
|
}
|
|
return r;
|
|
}
|
|
|
|
let updateInterval;
|
|
let totalExecutionStartTime;
|
|
let totalExecutionEndTime;
|
|
let lastExecutedNode;
|
|
let isExecuting = false;
|
|
|
|
function resetExecutionTimes() {
|
|
totalExecutionStartTime = null;
|
|
totalExecutionEndTime = null;
|
|
lastExecutedNode = null;
|
|
// 重置所有节点的执行时间
|
|
app.graph._nodes.forEach(node => {
|
|
node.ty_et_execution_time = undefined;
|
|
node.ty_et_start_time = undefined;
|
|
});
|
|
}
|
|
|
|
function startUpdateInterval() {
|
|
if (!updateInterval) {
|
|
updateInterval = setInterval(() => {
|
|
app.graph.setDirtyCanvas(true, false);
|
|
}, 100); // 每100毫秒更新一次
|
|
}
|
|
}
|
|
|
|
function stopUpdateInterval() {
|
|
if (updateInterval) {
|
|
clearInterval(updateInterval);
|
|
updateInterval = null;
|
|
}
|
|
}
|
|
|
|
app.registerExtension({
|
|
name: "DW-Utils.ExecutionTime",
|
|
async setup() {
|
|
app.ui.settings.addSetting({
|
|
id: "DW.ExecutionTime.Enabled",
|
|
name: "Show Execution Time",
|
|
type: "boolean",
|
|
defaultValue: true,
|
|
});
|
|
|
|
api.addEventListener("executing", ({ detail }) => {
|
|
const nodeId = detail;
|
|
if (!nodeId) {
|
|
if (isExecuting) {
|
|
// 只有当之前正在执行时,才重置执行时间
|
|
resetExecutionTimes();
|
|
}
|
|
isExecuting = true;
|
|
stopUpdateInterval();
|
|
return;
|
|
}
|
|
|
|
if (!totalExecutionStartTime) {
|
|
totalExecutionStartTime = performance.now();
|
|
}
|
|
|
|
const node = app.graph.getNodeById(nodeId);
|
|
if (node) {
|
|
// 重置节点的执行时间
|
|
node.ty_et_execution_time = undefined;
|
|
node.ty_et_start_time = performance.now();
|
|
startUpdateInterval();
|
|
}
|
|
});
|
|
|
|
api.addEventListener("executed", () => {
|
|
stopUpdateInterval();
|
|
totalExecutionEndTime = performance.now();
|
|
isExecuting = false;
|
|
|
|
// 在执行完成后打印所有节点的执行时间
|
|
app.graph._nodes.forEach(node => {
|
|
if (node.ty_et_execution_time !== undefined) {
|
|
console.log(`#${node.id} [${getNodeName(node)}]: ${formatExecutionTime(node.ty_et_execution_time)}`);
|
|
}
|
|
});
|
|
|
|
if (totalExecutionStartTime && totalExecutionEndTime) {
|
|
const totalTime = totalExecutionEndTime - totalExecutionStartTime;
|
|
console.log(`Prompt executed in ${formatExecutionTime(totalTime)}`);
|
|
// 更新最后一个节点的执行时间
|
|
if (lastExecutedNode) {
|
|
lastExecutedNode.ty_et_execution_time = totalTime;
|
|
app.graph.setDirtyCanvas(true, false);
|
|
}
|
|
}
|
|
});
|
|
|
|
api.addEventListener("DW-Utils.ExecutionTime.executed", ({ detail }) => {
|
|
const node = app.graph.getNodeById(detail.node);
|
|
if (node) {
|
|
node.ty_et_execution_time = detail.execution_time;
|
|
node.ty_et_start_time = undefined;
|
|
lastExecutedNode = node;
|
|
app.graph.setDirtyCanvas(true, false);
|
|
}
|
|
});
|
|
},
|
|
async nodeCreated(node) {
|
|
if (!node.ty_et_swizzled) {
|
|
let orig = node.onDrawForeground;
|
|
if (!orig) {
|
|
orig = node.__proto__.onDrawForeground;
|
|
}
|
|
|
|
node.onDrawForeground = function (ctx) {
|
|
let totalTime;
|
|
if (totalExecutionStartTime && totalExecutionEndTime) {
|
|
totalTime = totalExecutionEndTime - totalExecutionStartTime;
|
|
}
|
|
if (app.ui.settings.getSettingValue("DW.ExecutionTime.Enabled", true)) {
|
|
drawBadge(node, orig, arguments, totalTime, node === lastExecutedNode);
|
|
} else {
|
|
orig?.apply?.(node, arguments);
|
|
}
|
|
};
|
|
node.ty_et_swizzled = true;
|
|
}
|
|
},
|
|
async loadedGraphNode(node) {
|
|
if (!node.ty_et_swizzled) {
|
|
const orig = node.onDrawForeground;
|
|
node.onDrawForeground = function (ctx) {
|
|
let totalTime;
|
|
if (totalExecutionStartTime && totalExecutionEndTime) {
|
|
totalTime = totalExecutionEndTime - totalExecutionStartTime;
|
|
}
|
|
if (app.ui.settings.getSettingValue("DW.ExecutionTime.Enabled", true)) {
|
|
drawBadge(node, orig, arguments, totalTime, node === lastExecutedNode);
|
|
} else {
|
|
orig?.apply?.(node, arguments);
|
|
}
|
|
};
|
|
node.ty_et_swizzled = true;
|
|
}
|
|
}
|
|
}); |