3v324v23's picture
lfs
1e3b872
import { app } from "../../../scripts/app.js";
import { addMenuHandler } from "./common/utils.js";
import { addNode } from "./common/utils.js";
const connectionMap = {
"KSampler (Efficient)": ["input", 5],
"KSampler Adv. (Efficient)": ["input", 5],
"KSampler SDXL (Eff.)": ["input", 3],
"XY Plot": ["output", 0],
"Noise Control Script": ["input & output", 0],
"HighRes-Fix Script": ["input & output", 0],
"Tiled Upscaler Script": ["input & output", 0],
"AnimateDiff Script": ["output", 0]
};
/**
* connect this node output to the input of another node
* @method connect
* @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot)
* @param {LGraphNode} node the target node
* @param {number_or_string} target_slot the input slot of the target node (could be the number of the slot or the string with the name of the slot, or -1 to connect a trigger)
* @return {Object} the link_info is created, otherwise null
LGraphNode.prototype.connect = function(output_slot, target_node, input_slot)
**/
function addAndConnectScriptNode(scriptType, selectedNode) {
const selectedNodeType = connectionMap[selectedNode.type];
const newNodeType = connectionMap[scriptType];
// 1. Create the new node without position adjustments
const newNode = addNode(scriptType, selectedNode, { shiftX: 0, shiftY: 0 });
// 2. Adjust position of the new node based on conditions
if (newNodeType[0].includes("input") && selectedNodeType[0].includes("output")) {
newNode.pos[0] += selectedNode.size[0] + 50;
} else if (newNodeType[0].includes("output") && selectedNodeType[0].includes("input")) {
newNode.pos[0] -= (newNode.size[0] + 50);
}
// 3. Logic for connecting the nodes
switch (selectedNodeType[0]) {
case "output":
if (newNodeType[0] === "input & output") {
// For every node that was previously connected to the selectedNode's output
const connectedNodes = selectedNode.getOutputNodes(selectedNodeType[1]);
if (connectedNodes && connectedNodes.length) {
for (let connectedNode of connectedNodes) {
// Disconnect the node from selectedNode's output
selectedNode.disconnectOutput(selectedNodeType[1]);
// Connect the newNode's output to the previously connected node,
// using the appropriate slot based on the type of the connectedNode
const targetSlot = (connectedNode.type in connectionMap) ? connectionMap[connectedNode.type][1] : 0;
newNode.connect(0, connectedNode, targetSlot);
}
}
// Connect selectedNode's output to newNode's input
selectedNode.connect(selectedNodeType[1], newNode, newNodeType[1]);
}
break;
case "input":
if (newNodeType[0] === "output") {
newNode.connect(0, selectedNode, selectedNodeType[1]);
} else if (newNodeType[0] === "input & output") {
const ogInputNode = selectedNode.getInputNode(selectedNodeType[1]);
if (ogInputNode) {
ogInputNode.connect(0, newNode, 0);
}
newNode.connect(0, selectedNode, selectedNodeType[1]);
}
break;
case "input & output":
if (newNodeType[0] === "output") {
newNode.connect(0, selectedNode, 0);
} else if (newNodeType[0] === "input & output") {
const connectedNodes = selectedNode.getOutputNodes(0);
if (connectedNodes && connectedNodes.length) {
for (let connectedNode of connectedNodes) {
selectedNode.disconnectOutput(0);
newNode.connect(0, connectedNode, connectedNode.type in connectionMap ? connectionMap[connectedNode.type][1] : 0);
}
}
// Connect selectedNode's output to newNode's input
selectedNode.connect(selectedNodeType[1], newNode, newNodeType[1]);
}
break;
}
return newNode;
}
function createScriptEntry(node, scriptType) {
return {
content: scriptType,
callback: function() {
addAndConnectScriptNode(scriptType, node);
},
};
}
function getScriptOptions(nodeType, node) {
const allScriptTypes = [
"XY Plot",
"Noise Control Script",
"HighRes-Fix Script",
"Tiled Upscaler Script",
"AnimateDiff Script"
];
// Filter script types based on node type
const scriptTypes = allScriptTypes.filter(scriptType => {
const scriptBehavior = connectionMap[scriptType][0];
if (connectionMap[nodeType][0] === "output") {
return scriptBehavior.includes("input"); // Includes nodes that are "input" or "input & output"
} else {
return true;
}
});
return scriptTypes.map(script => createScriptEntry(node, script));
}
function showAddScriptMenu(_, options, e, menu, node) {
const scriptOptions = getScriptOptions(node.type, node);
new LiteGraph.ContextMenu(scriptOptions, {
event: e,
callback: null,
parentMenu: menu,
node: node
});
return false;
}
// Extension Definition
app.registerExtension({
name: "efficiency.addScripts",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (connectionMap[nodeData.name]) {
addMenuHandler(nodeType, function(insertOption) {
insertOption({
content: "📜 Add script...",
has_submenu: true,
callback: showAddScriptMenu
});
});
}
},
});