Seven production pipeline utility nodes for ComfyUI: - PD Project Context: top-level metadata/token source - PD Shot Token: lightweight template string resolver - PD Output Namer: structured output filename builder - PD Network Output: image writer with UNC path support - PD Switch: multi-channel wildcard input router (up to 8×8) - PD Wedge: iteration node with optional auto-queue injection - PD Rasterizer: dry-run wedge cartesian product previewer Core infrastructure: - core/compat.py: legacy + Nodes 2.0 (V3) API compatibility shim - core/tokens.py: standalone token resolution engine - core/utils.py: path normalization and directory helpers - web/pipedream_rasterizer.js: minimal JS for rasterizer preview https://claude.ai/code/session_015UV4rjSvFatMiNtKhd1sT3
79 lines
2.2 KiB
Python
79 lines
2.2 KiB
Python
"""
|
||
PD Switch node.
|
||
|
||
Routes one of N inputs to output per channel. Supports any ComfyUI type
|
||
(wildcard) and multiple independent channels per node instance.
|
||
"""
|
||
|
||
|
||
class PDSwitch:
|
||
"""Multi-channel input switch with wildcard type support."""
|
||
|
||
DISPLAY_NAME = "PD Switch"
|
||
CATEGORY = "Pipedream"
|
||
FUNCTION = "execute"
|
||
|
||
# Max 8 channels, each producing one output. Unused slots pass None.
|
||
RETURN_TYPES = ("*",) * 8
|
||
RETURN_NAMES = tuple(f"ch{c}_out" for c in range(1, 9))
|
||
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
required = {
|
||
"channels": ("INT", {"default": 1, "min": 1, "max": 8}),
|
||
"inputs_per_channel": ("INT", {"default": 2, "min": 2, "max": 8}),
|
||
"mode": (["manual", "value"],),
|
||
}
|
||
|
||
optional = {}
|
||
|
||
# Per-channel manual selector widget
|
||
for c in range(1, 9):
|
||
optional[f"ch{c}_select"] = ("INT", {
|
||
"default": 0,
|
||
"min": 0,
|
||
"max": 7,
|
||
})
|
||
|
||
# Per-channel value-mode index input (driven by upstream INT)
|
||
for c in range(1, 9):
|
||
optional[f"ch{c}_index"] = ("INT", {
|
||
"default": 0,
|
||
"min": 0,
|
||
"max": 7,
|
||
"forceInput": True,
|
||
})
|
||
|
||
# Data inputs — wildcard type, 8 channels × 8 inputs each
|
||
for c in range(1, 9):
|
||
for i in range(1, 9):
|
||
optional[f"ch{c}_in{i}"] = ("*",)
|
||
|
||
return {"required": required, "optional": optional}
|
||
|
||
@classmethod
|
||
def VALIDATE_INPUTS(cls, **kwargs):
|
||
return True
|
||
|
||
def execute(self, channels, inputs_per_channel, mode, **kwargs):
|
||
outputs: list = []
|
||
|
||
for c in range(1, channels + 1):
|
||
# Determine selected index
|
||
if mode == "value":
|
||
idx = kwargs.get(f"ch{c}_index", 0) or 0
|
||
else:
|
||
idx = kwargs.get(f"ch{c}_select", 0) or 0
|
||
|
||
idx = max(0, min(idx, inputs_per_channel - 1))
|
||
|
||
# Retrieve the selected input (1-based input numbering)
|
||
value = kwargs.get(f"ch{c}_in{idx + 1}")
|
||
outputs.append(value)
|
||
|
||
# Pad to 8 outputs
|
||
while len(outputs) < 8:
|
||
outputs.append(None)
|
||
|
||
return tuple(outputs)
|