Merge pull request #9 from StableLlama/dynamic_nodes2
Add flow selection nodes
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "basic_data_handling"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
description = """NOTE: Still in development! Expect breaking changes!
|
||||
Basic Python functions for manipulating data that every programmer is used to.
|
||||
Currently supported ComfyUI data types: BOOLEAN, FLOAT, INT, STRING and data lists.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from typing import Any
|
||||
from inspect import cleandoc
|
||||
from comfy.comfy_types.node_typing import IO, ComfyNodeABC
|
||||
from comfy_execution.graph import ExecutionBlocker
|
||||
|
||||
|
||||
class IfElse(ComfyNodeABC):
|
||||
"""
|
||||
@@ -53,11 +55,11 @@ class IfElifElse(ComfyNodeABC):
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"if": (IO.BOOLEAN, {}),
|
||||
"if": (IO.BOOLEAN, {"forceInput": True}),
|
||||
"then": (IO.ANY, {"lazy": True}),
|
||||
},
|
||||
"optional": {
|
||||
"elif_0": (IO.BOOLEAN, {"lazy": True, "_dynamic": "number", "_dynamicGroup": 0}),
|
||||
"elif_0": (IO.BOOLEAN, {"forceInput": True, "lazy": True, "_dynamic": "number", "_dynamicGroup": 0}),
|
||||
"then_0": (IO.ANY, {"lazy": True, "_dynamic": "number", "_dynamicGroup": 0}),
|
||||
"else": (IO.ANY, {"lazy": True}),
|
||||
}
|
||||
@@ -191,6 +193,38 @@ class SwitchCase(ComfyNodeABC):
|
||||
# If selector is out of range or the selected case is None, return default
|
||||
return (kwargs.get("default"),)
|
||||
|
||||
|
||||
class FlowSelect(ComfyNodeABC):
|
||||
"""
|
||||
Select the direction of the flow.
|
||||
|
||||
This node takes a value and directs it to either the "true" or "false" output.
|
||||
|
||||
Note: for dynamic switching in a Data Flow you might want to use
|
||||
"filter select" instead.
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": (IO.ANY, {}),
|
||||
"select": (IO.BOOLEAN, {}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = (IO.ANY, IO.ANY)
|
||||
RETURN_NAMES = ("true", "false")
|
||||
CATEGORY = "Basic/flow control"
|
||||
DESCRIPTION = cleandoc(__doc__ or "")
|
||||
FUNCTION = "select"
|
||||
|
||||
def select(self, value, select = True) -> tuple[Any, Any]:
|
||||
if select:
|
||||
return value, ExecutionBlocker(None)
|
||||
else:
|
||||
return ExecutionBlocker(None), value
|
||||
|
||||
|
||||
class ExecutionOrder(ComfyNodeABC):
|
||||
"""
|
||||
Force execution order in the workflow.
|
||||
@@ -222,6 +256,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"Basic data handling: IfElse": IfElse,
|
||||
"Basic data handling: IfElifElse": IfElifElse,
|
||||
"Basic data handling: SwitchCase": SwitchCase,
|
||||
"Basic data handling: FlowSelect": FlowSelect,
|
||||
"Basic data handling: ExecutionOrder": ExecutionOrder,
|
||||
}
|
||||
|
||||
@@ -229,5 +264,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Basic data handling: IfElse": "if/else",
|
||||
"Basic data handling: IfElifElse": "if/elif/.../else",
|
||||
"Basic data handling: SwitchCase": "switch/case",
|
||||
"Basic data handling: FlowSelect": "flow select",
|
||||
"Basic data handling: ExecutionOrder": "force execution order",
|
||||
}
|
||||
|
||||
@@ -295,6 +295,46 @@ class DataListFilter(ComfyNodeABC):
|
||||
return (result,)
|
||||
|
||||
|
||||
class DataListFilterSelect(ComfyNodeABC):
|
||||
"""
|
||||
Filters a Data List using boolean values.
|
||||
|
||||
This node takes a value Data List and a filter Data List (containing only boolean values).
|
||||
It returns two new Data Lists containing only the elements from the value list where the
|
||||
corresponding element in the filter list is true or false.
|
||||
|
||||
If the lists have different lengths, the last element of the shorter list is repeated
|
||||
till the lengths are matching.
|
||||
"""
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": (IO.ANY, {}),
|
||||
"select": (IO.BOOLEAN, {}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = (IO.ANY, IO.ANY)
|
||||
RETURN_NAMES = ("true", "false")
|
||||
CATEGORY = "Basic/Data List"
|
||||
DESCRIPTION = cleandoc(__doc__ or "")
|
||||
FUNCTION = "select"
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = (True, True,)
|
||||
|
||||
def select(self, **kwargs: list[Any]) -> tuple[list[Any]]:
|
||||
values = kwargs.get('value', [])
|
||||
selects = kwargs.get('select', [])
|
||||
|
||||
# Create a new list with only items where the filter is False
|
||||
result_true, result_false = [], []
|
||||
for value, select in zip(values, selects):
|
||||
(result_true if select else result_false).append(value)
|
||||
|
||||
return result_true, result_false
|
||||
|
||||
|
||||
class DataListGetItem(ComfyNodeABC):
|
||||
"""
|
||||
Retrieves an item at a specified position in a list.
|
||||
@@ -771,7 +811,7 @@ class DataListToList(ComfyNodeABC):
|
||||
INPUT_IS_LIST = True
|
||||
|
||||
def convert(self, **kwargs: list[Any]) -> tuple[list[Any]]:
|
||||
return (kwargs.get('list', []).copy(),)
|
||||
return (list(kwargs.get('list', [])).copy(),)
|
||||
|
||||
|
||||
class DataListToSet(ComfyNodeABC):
|
||||
@@ -810,6 +850,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"Basic data handling: DataListCount": DataListCount,
|
||||
"Basic data handling: DataListExtend": DataListExtend,
|
||||
"Basic data handling: DataListFilter": DataListFilter,
|
||||
"Basic data handling: DataListFilterSelect": DataListFilterSelect,
|
||||
"Basic data handling: DataListGetItem": DataListGetItem,
|
||||
"Basic data handling: DataListIndex": DataListIndex,
|
||||
"Basic data handling: DataListInsert": DataListInsert,
|
||||
@@ -838,6 +879,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Basic data handling: DataListCount": "count",
|
||||
"Basic data handling: DataListExtend": "extend",
|
||||
"Basic data handling: DataListFilter": "filter",
|
||||
"Basic data handling: DataListFilterSelect": "filter select",
|
||||
"Basic data handling: DataListGetItem": "get item",
|
||||
"Basic data handling: DataListIndex": "index",
|
||||
"Basic data handling: DataListInsert": "insert",
|
||||
|
||||
Reference in New Issue
Block a user