Add mergeSelector and numberTypeConverter nodes

This commit is contained in:
samuelxuliu
2025-11-11 14:50:43 +08:00
parent f2d67bf1ad
commit 1e43e9e540
3 changed files with 231 additions and 0 deletions
+6
View File
@@ -14,6 +14,8 @@ from .py.intSplit import PrepackIntSplit
from .py.saveByFileName import PrepackSaveByFileName
from .py.condArea import PrepackCondArea
from .py.calculator import PrepackCalculator
from .py.mergeSelector import PrepackMergeSelector
from .py.numberTypeConverter import PrepackNumberTypeConverter
# Frontend extension directory for virtual nodes
WEB_DIRECTORY = "./js"
@@ -35,6 +37,8 @@ NODE_CLASS_MAPPINGS = {
"💀Prepack Save By File Name": PrepackSaveByFileName,
"PrepackCondArea": PrepackCondArea,
"💀Prepack Calculator": PrepackCalculator,
"💀Prepack Merge Selector": PrepackMergeSelector,
"💀Prepack Number Type Converter": PrepackNumberTypeConverter,
}
NODE_DISPLAY_NAME_MAPPINGS = {
@@ -54,6 +58,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"💀Prepack Save By File Name": "💀Save By File Name",
"PrepackCondArea": "💀Prepack Cond Area",
"💀Prepack Calculator": "💀Prepack Calculator",
"💀Prepack Merge Selector": "💀Prepack Merge Selector",
"💀Prepack Number Type Converter": "💀Prepack Number Type Converter",
}
__all__ = [
+148
View File
@@ -0,0 +1,148 @@
class AlwaysEqualProxy(str):
"""Proxy class to accept any input type"""
def __eq__(self, _):
return True
def __ne__(self, _):
return False
# ANSI color utilities for pretty logging
class _PrepackColors:
RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
BLUE = '\033[34m'
MAGENTA = '\033[35m'
CYAN = '\033[36m'
WHITE = '\033[37m'
RESET = '\033[0m'
BOLD = '\033[1m'
DIM = '\033[2m'
class PrepackLogger:
"""Unified colorful logger for Prepack nodes"""
PREFIX = "Prepack"
@staticmethod
def _fmt(level: str, node: str, message: str) -> str:
# Choose icon and color by level
if level == "ERROR":
icon, color = "❌", _PrepackColors.RED
elif level == "WARNING":
icon, color = "⚠️", _PrepackColors.YELLOW
elif level == "SUCCESS":
icon, color = "✅", _PrepackColors.GREEN
elif level == "INFO":
icon, color = "ℹ️", _PrepackColors.CYAN
elif level == "DEBUG":
icon, color = "🔧", _PrepackColors.DIM
else:
icon, color = "📝", _PrepackColors.WHITE
# Format: [Prepack] ICON Node: message (with color and bold prefix)
return f"{color}{_PrepackColors.BOLD}[{PrepackLogger.PREFIX}]{_PrepackColors.RESET} {icon} {color}{node}:{_PrepackColors.RESET} {message}"
@staticmethod
def info(node: str, message: str):
print(PrepackLogger._fmt("INFO", node, message))
@staticmethod
def debug(node: str, message: str):
print(PrepackLogger._fmt("DEBUG", node, message))
@staticmethod
def warning(node: str, message: str):
print(PrepackLogger._fmt("WARNING", node, message))
@staticmethod
def error(node: str, message: str):
print(PrepackLogger._fmt("ERROR", node, message))
@staticmethod
def success(node: str, message: str):
print(PrepackLogger._fmt("SUCCESS", node, message))
class PrepackMergeSelector:
"""
Merge Selector node that outputs one of 5 arbitrary type inputs based on selector number.
Only outputs the selected input, ignoring all others.
"""
@classmethod
def INPUT_TYPES(cls):
"""
Define input types for the merge selector node.
"""
return {
"required": {
"selector": ("INT", {"default": 1, "min": 1, "max": 5}),
},
"optional": {
"input_1": (AlwaysEqualProxy("*"), {}),
"input_2": (AlwaysEqualProxy("*"), {}),
"input_3": (AlwaysEqualProxy("*"), {}),
"input_4": (AlwaysEqualProxy("*"), {}),
"input_5": (AlwaysEqualProxy("*"), {}),
}
}
RETURN_TYPES = (AlwaysEqualProxy("*"),)
RETURN_NAMES = ("output",)
FUNCTION = "select"
CATEGORY = "💀Prepack"
def select(self, selector, input_1=None, input_2=None, input_3=None, input_4=None, input_5=None):
"""
Select and output one of the 5 inputs based on selector number.
Args:
selector: Integer (1-5) indicating which input to output
input_1: Optional first input of any type
input_2: Optional second input of any type
input_3: Optional third input of any type
input_4: Optional fourth input of any type
input_5: Optional fifth input of any type
Returns:
The selected input based on selector value
"""
# Map selector to corresponding input
inputs = {
1: input_1,
2: input_2,
3: input_3,
4: input_4,
5: input_5
}
# Get the selected input
selected_input = inputs.get(selector)
# Check if the selected input is connected
if selected_input is None:
PrepackLogger.warning(
"MergeSelector",
f"Selector={selector} but input_{selector} is not connected • returning None"
)
return (None,)
# Log successful selection
input_type = type(selected_input).__name__
PrepackLogger.success(
"MergeSelector",
f"Selector={selector} • Selected input_{selector} • Type={input_type}"
)
return (selected_input,)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"💀Prepack Merge Selector": PrepackMergeSelector
}
NODE_DISPLAY_NAME_MAPPINGS = {
"💀Prepack Merge Selector": "💀Prepack Merge Selector"
}
+77
View File
@@ -0,0 +1,77 @@
"""Prepack Number Type Converter: convert between string, int, and float types."""
class AlwaysEqualProxy(str):
"""Proxy class to accept any input type"""
def __eq__(self, _):
return True
def __ne__(self, _):
return False
class PrepackNumberTypeConverter:
"""
Number type converter node that accepts string, int, or float input
and outputs all three types.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"value": (AlwaysEqualProxy("*"), {
"tooltip": "Input value (string, int, or float)"
}),
}
}
RETURN_TYPES = ("STRING", "INT", "FLOAT")
RETURN_NAMES = ("string", "int", "float")
OUTPUT_TOOLTIPS = (
"Value as string",
"Value as integer (rounded if needed)",
"Value as float"
)
FUNCTION = "convert"
CATEGORY = "💀Prepack"
DESCRIPTION = "Convert between string, int, and float types. Accepts any of these types and outputs all three."
def convert(self, value):
"""
Convert input value to string, int, and float.
Args:
value: Input value (string, int, or float)
Returns:
Tuple of (string, int, float)
"""
try:
# Convert to string
str_value = str(value).strip()
# Convert to float
float_value = float(value)
# Convert to int (rounded)
int_value = int(round(float_value))
print(f"[Prepack] 🔄 Number Type Converter: input={value} → string='{str_value}', int={int_value}, float={float_value}")
return (str_value, int_value, float_value)
except (ValueError, TypeError) as e:
print(f"[Prepack] ❌ Number Type Converter: Error converting value '{value}': {str(e)}")
# Return safe defaults on error
return (str(value) if value is not None else "0", 0, 0.0)
# Node class mappings
NODE_CLASS_MAPPINGS = {
"PrepackNumberTypeConverter": PrepackNumberTypeConverter
}
NODE_DISPLAY_NAME_MAPPINGS = {
"PrepackNumberTypeConverter": "💀Prepack Number Type Converter"
}