Skip to content

Instantly share code, notes, and snippets.

@Amorano
Created February 12, 2024 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Amorano/9871fb3be1aa75defdfad013e1f95e0e to your computer and use it in GitHub Desktop.
Save Amorano/9871fb3be1aa75defdfad013e1f95e0e to your computer and use it in GitHub Desktop.
Example of How to Add Dynamic Connections to Nodes in ComfyUI
/**
* Make a dynamic Input for ComfyUI
*/
import { app } from "/scripts/app.js"
const _prefix = '➡️'
const TypeSlot = {
Input: 1,
Output: 2,
};
const TypeSlotEvent = {
Connect: true,
Disconnect: false,
};
const dynamic_connection = (node, index, event, prefix='in_', type='*', names = []
) => {
if (!node.inputs[index].name.startsWith(prefix)) {
return
}
// remove all non connected inputs
if (event == TypeSlotEvent.Disconnect && node.inputs.length > 1) {
console.info(`Removing input ${index} (${node.inputs[index].name})`)
if (node.widgets) {
const widget = node.widgets.find((w) => w.name === node.inputs[index].name)
if (widget) {
widget.onRemoved?.()
node.widgets.length = node.widgets.length - 1
}
}
node.removeInput(index)
// make inputs sequential again
for (let i = 0; i < node.inputs.length; i++) {
const name = i < names.length ? names[i] : `${prefix}${i + 1}`
node.inputs[i].label = name
node.inputs[i].name = name
}
}
// add an extra input
if (node.inputs[node.inputs.length - 1].link != undefined) {
const nextIndex = node.inputs.length
const name = nextIndex < names.length
? names[nextIndex]
: `${prefix}${nextIndex + 1}`
console.info(`Adding input ${nextIndex + 1} (${name})`)
node.addInput(name, type)
}
}
const _id = "<NODES_I_AM_FILTERING>"
const my_extension = {
name: 'some.unique.name',
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name !== _id) {
return;
}
const onNodeCreated = nodeType.prototype.onNodeCreated
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined
this.addInput(`${_prefix}_1`, '*')
return r
}
const onConnectionsChange = nodeType.prototype.onConnectionsChange
nodeType.prototype.onConnectionsChange = function (slotType, slot, event, link_info, data) {
const me = onConnectionsChange ? onConnectionsChange.apply(this, arguments) : undefined
if (slotType === TypeSlot.Input) {
dynamic_connection(this, slot, event, `${_prefix}_`, '*')
if (event === TypeSlotEvent.Connect && link_info) {
const fromNode = this.graph._nodes.find(
(otherNode) => otherNode.id == link_info.origin_id
)
const type = fromNode.outputs[link_info.origin_slot].type
this.inputs[slot].type = type
} else if (event === TypeSlotEvent.Disconnect) {
this.inputs[slot].type = '*'
this.inputs[slot].label = `${_prefix}_${slot + 1}`
}
}
return me;
}
}
}
app.registerExtension(my_extension)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment