Files
2024-08-23 11:40:00 +08:00

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;
}
}
});