(node, nodeData)
| 176 | app.registerExtension({ |
| 177 | name: "pysssss.Binding", |
| 178 | beforeRegisterNodeDef(node, nodeData) { |
| 179 | const hasBinding = (v) => { |
| 180 | if (!v) return false; |
| 181 | return Object.values(v).find((c) => c[1]?.["pysssss.binding"]); |
| 182 | }; |
| 183 | const inputs = { ...nodeData.input?.required, ...nodeData.input?.optional }; |
| 184 | if (hasBinding(inputs)) { |
| 185 | const onAdded = node.prototype.onAdded; |
| 186 | node.prototype.onAdded = function () { |
| 187 | const r = onAdded?.apply(this, arguments); |
| 188 | |
| 189 | for (const widget of this.widgets || []) { |
| 190 | const bindings = inputs[widget.name][1]?.["pysssss.binding"]; |
| 191 | if (!bindings) continue; |
| 192 | |
| 193 | for (const binding of bindings) { |
| 194 | /** |
| 195 | * @type {import("../../../../../web/types/litegraph.d.ts").IWidget} |
| 196 | */ |
| 197 | const source = this.widgets.find((w) => w.name === binding.source); |
| 198 | if (!source) { |
| 199 | console.warn( |
| 200 | "%c[🐍 pysssss]", |
| 201 | "color: limegreen", |
| 202 | `[binding ${node.comfyClass}.${widget.name}]`, |
| 203 | "unable to find source binding widget:", |
| 204 | binding.source, |
| 205 | binding |
| 206 | ); |
| 207 | continue; |
| 208 | } |
| 209 | |
| 210 | let lastValue; |
| 211 | async function valueChanged() { |
| 212 | const state = { |
| 213 | $this: widget, |
| 214 | $source: source, |
| 215 | $node: node, |
| 216 | }; |
| 217 | |
| 218 | for (const callback of binding.callback) { |
| 219 | await invokeCallback(callback, state); |
| 220 | } |
| 221 | |
| 222 | app.graph.setDirtyCanvas(true, false); |
| 223 | } |
| 224 | |
| 225 | const cb = source.callback; |
| 226 | source.callback = function () { |
| 227 | const v = cb?.apply(this, arguments) ?? source.value; |
| 228 | if (v !== lastValue) { |
| 229 | lastValue = v; |
| 230 | valueChanged(); |
| 231 | } |
| 232 | return v; |
| 233 | }; |
| 234 | |
| 235 | lastValue = source.value; |
nothing calls this directly
no test coverage detected