|
import { app } from "../../../scripts/app.js"; |
|
|
|
const REPEATER = "Repeater|pysssss"; |
|
|
|
app.registerExtension({ |
|
name: "pysssss.Repeater", |
|
init() { |
|
const graphToPrompt = app.graphToPrompt; |
|
app.graphToPrompt = async function () { |
|
const res = await graphToPrompt.apply(this, arguments); |
|
|
|
const id = Date.now() + "_"; |
|
let u = 0; |
|
|
|
let newNodes = {}; |
|
const newRepeaters = {}; |
|
for (const nodeId in res.output) { |
|
let output = res.output[nodeId]; |
|
if (output.class_type === REPEATER) { |
|
const isMulti = output.inputs.output === "multi"; |
|
if (output.inputs.node_mode === "create") { |
|
|
|
const orig = res.output[output.inputs.source[0]]; |
|
if (isMulti) { |
|
if (!newRepeaters[nodeId]) { |
|
newRepeaters[nodeId] = []; |
|
newRepeaters[nodeId][output.inputs.repeats - 1] = nodeId; |
|
} |
|
} |
|
for (let i = 0; i < output.inputs.repeats - 1; i++) { |
|
const clonedInputId = id + ++u; |
|
|
|
if (isMulti) { |
|
|
|
newNodes[clonedInputId] = structuredClone(orig); |
|
|
|
output = structuredClone(output); |
|
|
|
const clonedRepeaterId = id + ++u; |
|
newNodes[clonedRepeaterId] = output; |
|
output.inputs["source"][0] = clonedInputId; |
|
|
|
newRepeaters[nodeId][i] = clonedRepeaterId; |
|
} else { |
|
newNodes[clonedInputId] = orig; |
|
} |
|
output.inputs[clonedInputId] = [clonedInputId, output.inputs.source[1]]; |
|
} |
|
} else if (isMulti) { |
|
newRepeaters[nodeId] = Array(output.inputs.repeats).fill(nodeId); |
|
} |
|
} |
|
} |
|
|
|
Object.assign(res.output, newNodes); |
|
newNodes = {}; |
|
|
|
for (const nodeId in res.output) { |
|
const output = res.output[nodeId]; |
|
for (const k in output.inputs) { |
|
const v = output.inputs[k]; |
|
if (v instanceof Array) { |
|
const repeaterId = v[0]; |
|
const source = newRepeaters[repeaterId]; |
|
if (source) { |
|
v[0] = source.pop(); |
|
v[1] = 0; |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
return res; |
|
}; |
|
}, |
|
beforeRegisterNodeDef(nodeType, nodeData, app) { |
|
if (nodeData.name === REPEATER) { |
|
const SETUP_OUTPUTS = Symbol(); |
|
nodeType.prototype[SETUP_OUTPUTS] = function (repeats) { |
|
if (repeats == null) { |
|
repeats = this.widgets[0].value; |
|
} |
|
while (this.outputs.length > repeats) { |
|
this.removeOutput(repeats); |
|
} |
|
const id = Date.now() + "_"; |
|
let u = 0; |
|
while (this.outputs.length < repeats) { |
|
this.addOutput(id + ++u, "*", { label: "*" }); |
|
} |
|
}; |
|
|
|
const onAdded = nodeType.prototype.onAdded; |
|
nodeType.prototype.onAdded = function () { |
|
const self = this; |
|
const repeatsCb = this.widgets[0].callback; |
|
this.widgets[0].callback = async function () { |
|
const v = (await repeatsCb?.apply(this, arguments)) ?? this.value; |
|
if (self.widgets[1].value === "multi") { |
|
self[SETUP_OUTPUTS](v); |
|
} |
|
return v; |
|
}; |
|
|
|
const outputCb = this.widgets[1].callback; |
|
this.widgets[1].callback = async function () { |
|
const v = (await outputCb?.apply(this, arguments)) ?? this.value; |
|
if (v === "single") { |
|
self.outputs[0].shape = 6; |
|
self[SETUP_OUTPUTS](1); |
|
} else { |
|
delete self.outputs[0].shape; |
|
self[SETUP_OUTPUTS](); |
|
} |
|
return v; |
|
}; |
|
return onAdded?.apply(this, arguments); |
|
}; |
|
} |
|
}, |
|
}); |
|
|