comfyui_Bonso_Tools / nodes /bonso_switch.py
willybonso
v1.10.2 - 10 nodos: Switch, Moviola Prompt, fixes
e682b15
Raw History Blame Contribute Delete
6.12 kB
class Bonso_Switch:
"""Interruptor generico para CUALQUIER tipo de dato (imagen, modelo,
clip, vae, string, texto, int, float, latent, mask, ...).
Inspirado en el `Switch any [Crystools]`, pero **resistente a errores**.
switch = True -> pasa 'on true' a la salida
switch = False -> pasa 'on false' a la salida
Pensado para encajar con `Bonso Booleano`: su booleano entra aqui por
`switch`. Una sola salida, del mismo tipo que las entradas.
Tres mecanismos, de los cuales dos los hereda de ComfyUI y uno es
nuestro, y hay que entenderlos para no romperlo:
- **Entradas `lazy`**: la rama que NO toca **no se ejecuta nunca**
(`check_lazy_status` le dice al motor cual es la rama activa). Si la
rama inactiva esta rota o directamente no existe, aqui no pasa nada:
es la mejora sobre Crystools, cuyas entradas son `required` y por
eso exigen las DOS conexiones aunque solo se use una.
- **Entradas `optional`**: una entrada sin conectar no es un error de
validacion (con `required` lo seria: `400 required_input_missing`).
Se puede usar el nodo con una sola rama enchufada.
- **Poda del prompt** (`js/bonso_switch.js`): si el valor de `switch`
se puede saber (casilla literal o enlace desde `Bonso Booleano`), el
JS **borra la rama inactiva del prompt** antes de encolar, asi que
tampoco se VALIDA. Sin eso, un error de validacion en la rama
inactiva (nodo en bypass con entrada requerida vacia, tipo mal
enchufado) revienta el encolado aunque la rama no vaya a correr.
Comportamiento cuando falta la rama que SI toca: error claro en este
nodo (no un `None` que estrelle el nodo de abajo). Si la rama activa
falla aguas arriba con excepcion, el motor para toda la ejecucion ahi
y este nodo ni se ejecuta: eso ya no lo puede arreglar ningun nodo.
El dato pasa tal cual: misma referencia, cero operaciones. La salida
es `*` (ANY), asi que el servidor no puede comprobar que las dos
ramas sean del mismo tipo; la restriccion visual (la segunda entrada
solo admite el tipo de la primera) la pone el JS en el lienzo.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"switch": (
"BOOLEAN",
{
"default": True,
"tooltip": (
"True -> entrada 'on true', False -> entrada "
"'on false'. Se puede cablear desde Bonso "
"Booleano."
),
},
),
},
"optional": {
"on true": (
"*",
{
"lazy": True,
"tooltip": (
"Primer conexion (switch=True). Cualquier tipo; "
"tras conectar la primera, la segunda solo admite "
"ese mismo tipo (restriccion visual del lienzo)."
),
},
),
"on false": (
"*",
{
"lazy": True,
"tooltip": (
"Segunda conexion (switch=False). Cualquier tipo; "
"tras conectar la primera, la segunda solo admite "
"ese mismo tipo (restriccion visual del lienzo)."
),
},
),
},
"hidden": {
"unique_id": "UNIQUE_ID",
"dynprompt": "DYNPROMPT",
},
}
RETURN_TYPES = ("*",)
RETURN_NAMES = ("out",)
FUNCTION = "switch"
CATEGORY = "Bonso Tools"
DESCRIPTION = (
"Devuelve 'on true' si switch es True y 'on false' si es False, de "
"cualquier tipo. La rama que no toca no se ejecuta (lazy) y, si "
"switch se puede saber, tampoco se valida (poda del prompt). El dato "
"sale igual que ha entrado."
)
def check_lazy_status(
self, switch=True, **kwargs
):
"""Pide al motor SOLO la rama activa.
Devuelve el nombre de la entrada elegida si (y solo si) esta
conectada en el prompt. Si no lo esta, devuelve lista vacia: no
hay nada que ejecutar y `switch()` se encargara de dar el error
claro. Pedir una entrada inexistente haria que el motor lanzara
`NodeInputError`, asi que hay que mirar el prompt de verdad
(por eso este nodo esconde `UNIQUE_ID` y `DYNPROMPT`).
"""
elegida = "on true" if switch else "on false"
unique_id = kwargs.get("unique_id")
dynprompt = kwargs.get("dynprompt")
try:
nodo = dynprompt.get_node(unique_id) if dynprompt is not None else None
entradas = (nodo or {}).get("inputs") or {}
except Exception:
entradas = {}
if elegida not in entradas:
return []
return [elegida]
def switch(self, switch=True, **kwargs):
# unique_id y dynprompt llegan ocultos del motor: se absorben aqui
# para no reventar con TypeError, no se usan (el dato pasa tal cual).
a = kwargs.get("on true")
b = kwargs.get("on false")
if switch:
if a is None:
raise ValueError(
"[Bonso Switch] switch=True pero 'on true' no esta "
"conectado: conecta la rama 'on true' o cambia switch "
"a False."
)
return (a,)
if b is None:
raise ValueError(
"[Bonso Switch] switch=False pero 'on false' no esta "
"conectado: conecta la rama 'on false' o cambia switch a "
"True."
)
return (b,)
NODE_CLASS_MAPPINGS = {
"Bonso_Switch": Bonso_Switch,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"Bonso_Switch": "Bonso Switch🎚️",
}