Hunt Info

This commit is contained in:
Chris
2023-10-20 16:21:23 +11:00
parent 0134542743
commit 6d1db0392e
3 changed files with 81 additions and 2 deletions
+2
View File
@@ -24,6 +24,8 @@ That's where the first two nodes come in. Load an image using the `Load Image Wi
The outputs of the `Extract Info` node contain the displayed value as a string, and, if it can be parsed, as a float and an int - so you can use the values you've extracted.
To see what information is available more conveniently, use the `Hunt Info` node instead.
## *Adding more info
You'll quickly notice that only input values are available, and then only if they were widgets (not inputs). That's all that's stored in the prompt - it's all Comfy needed to do the run. But what if the prompt depended on external files that might have changed, or used random numbers? Or had some really complicated flow so it's hard to get the information you want?
+54 -1
View File
@@ -2,6 +2,12 @@ import { app } from "../../../scripts/app.js";
import { api } from "../../../scripts/api.js";
import { ComfyWidgets } from "../../../scripts/widgets.js";
function impose_min_width() {
const sz = this.origComputeSize();
if (sz[0]<250) sz[0]=250;
return sz;
}
function displayMessage(message) {
var w = this.widgets?.find((w) => w.name === "display_text_widget");
if (w === undefined) {
@@ -14,6 +20,49 @@ function displayMessage(message) {
this.onResize?.(this.size);
};
function handleThingChoice(selection, _, node) {
node.widgets.forEach((w) => { if (w != this && w != this.parent && w.onRemove) { w.onRemove(); } } )
node.widgets = [this.parent, this,]
if (selection=="Select Value") { return; }
const split = selection.split(' ');
const value = node.message[node.chosen][`${split[0]}puts`][split[1]];
displayMessage.apply(node, [value]);
}
function handleNodeChoice(selection, _, node) {
node.widgets.forEach((w) => { if (w != this && w.onRemove) { w.onRemove(); } } )
node.widgets = [this,];
if (selection=="Select Node") { return; }
const chosen = selection.split(' ')[0];
node.chosen = chosen;
const options = ["Select Value",];
for (const [key, value] of Object.entries(node.message[chosen].inputs)) {
options.push(`in ${key}`)
}
for (const [key, value] of Object.entries(node.message[chosen].outputs)) {
options.push(`out ${key}`)
}
const w = ComfyWidgets["COMBO"](node, " ", [options,]).widget;
w.callback = handleThingChoice;
w.parent = this;
}
function handleThingMessage(message) {
if (!this.origComputeSize) {
this.origComputeSize = this.computeSize;
this.computeSize = impose_min_width;
}
this.message = message;
if (this.widgets) { this.widgets.forEach((w) => { if (w.onRemove) { w.onRemove(); } } ) }
this.widgets = [];
const node_labels = ["Select Node",]
for (const [key, value] of Object.entries(message)) {
node_labels.push(`${key} (${value.type})`);
}
const w = ComfyWidgets["COMBO"](this, " ", [node_labels,]).widget;
w.callback = handleNodeChoice;
}
app.registerExtension({
name: "cg.info.textmessage",
async setup() {
@@ -21,14 +70,18 @@ app.registerExtension({
const id = event.detail.id;
const message = event.detail.message;
const node = app.graph._nodes_by_id[id];
if (node && node.displayMessage) node.displayMessage(message);
if (node && node.handleThingMessage) node.handleThingMessage(message);
else (console.log(`node ${id} couldn't handle a message`));
}
api.addEventListener("cg.prompt_info.textmessage", messageHandler);
api.addEventListener("cg.prompt_info.thingmessage", messageHandler);
},
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeType.comfyClass=="ExtractInfo" ) {
nodeType.prototype.displayMessage = displayMessage;
}
if (nodeType.comfyClass=="HuntInfo") {
nodeType.prototype.handleThingMessage = handleThingMessage;
}
}
})
+25 -1
View File
@@ -138,5 +138,29 @@ class ExtractInfo():
return (thing, flt, None)
return (thing, flt, nt)
class HuntInfo():
CATEGORY = "prompt_info"
FUNCTION = "func"
OUTPUT_NODE = True
CLAZZES = [AddInfo, LoadImageWithInfo, ExtractInfo]
@classmethod
def INPUT_TYPES(s):
return {"required": {
"info": ("STRING", {"forceInput": True}),
}, "hidden": {"id":"UNIQUE_ID"}}
RETURN_TYPES = ()
RETURN_NAMES = ()
def func(self, info, id):
try:
thing = json.loads(info)
PromptServer.instance.send_sync("cg.prompt_info.thingmessage", {"id": id, "message":thing})
except json.JSONDecodeError:
print("JSONDecodeError")
return ()
CLAZZES = [AddInfo, LoadImageWithInfo, ExtractInfo, HuntInfo]