Files
Oratorian-ComfyUI-Switchboard/nodes.py
T

105 lines
3.4 KiB
Python

"""Backend utility nodes for Switchboard.
Unlike the Group/Node Controllers (which are client-side and only toggle node
*modes*), these are real executing nodes that move data at runtime:
- Value On Boolean: pick one of two numbers from a boolean.
- Boolean Switch: route one of two inputs through, based on a boolean,
evaluating ONLY the chosen branch (lazy) -- the unused
input's whole upstream chain is skipped.
"""
CATEGORY = "🎛️ Switchboard"
class _AnyType(str):
"""A type string that compares equal to every other type, so a ``*`` socket
accepts a connection of any kind. The standard ComfyUI wildcard trick."""
def __eq__(self, _other):
return True
def __ne__(self, _other):
return False
def __hash__(self):
return hash("*")
ANY = _AnyType("*")
class SwitchboardValueOnBoolean:
"""Output one of two values depending on a boolean."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"boolean": ("BOOLEAN", {"default": True}),
"value_if_true": (
"FLOAT",
{"default": 1.0, "min": -1.0e9, "max": 1.0e9, "step": 0.01},
),
"value_if_false": (
"FLOAT",
{"default": 0.0, "min": -1.0e9, "max": 1.0e9, "step": 0.01},
),
}
}
RETURN_TYPES = ("FLOAT", "INT", "STRING", "BOOLEAN")
RETURN_NAMES = ("float", "int", "string", "boolean")
FUNCTION = "run"
CATEGORY = CATEGORY
DESCRIPTION = "Pick value_if_true or value_if_false based on a boolean. " \
"The chosen number is returned as FLOAT/INT/STRING; the boolean passes through."
def run(self, boolean, value_if_true, value_if_false):
value = value_if_true if boolean else value_if_false
return (float(value), int(round(value)), str(value), bool(boolean))
class SwitchboardBooleanSwitch:
"""Route one of two inputs (any type) based on a boolean, lazily."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
# An input socket, not a widget toggle -- wire a BOOLEAN in.
"boolean": ("BOOLEAN", {"forceInput": True}),
},
"optional": {
# Lazy: only the selected branch is ever evaluated.
"on_true": (ANY, {"lazy": True}),
"on_false": (ANY, {"lazy": True}),
},
}
RETURN_TYPES = (ANY,)
RETURN_NAMES = ("output",)
FUNCTION = "run"
CATEGORY = CATEGORY
DESCRIPTION = "Pass on_true through when boolean is True, otherwise on_false. " \
"Accepts any type, and only the selected branch is executed (lazy)."
def check_lazy_status(self, boolean, on_true=None, on_false=None):
# Tell ComfyUI which lazy input we actually need so the other branch's
# upstream graph is never executed.
return ["on_true"] if boolean else ["on_false"]
def run(self, boolean, on_true=None, on_false=None):
return (on_true if boolean else on_false,)
NODE_CLASS_MAPPINGS = {
"SwitchboardValueOnBoolean": SwitchboardValueOnBoolean,
"SwitchboardBooleanSwitch": SwitchboardBooleanSwitch,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"SwitchboardValueOnBoolean": "Value on Boolean",
"SwitchboardBooleanSwitch": "Boolean Switch",
}