Adapt to new ComfyUI frontend and topological execution
This commit is contained in:
@@ -29,21 +29,25 @@ from . import utils as lib0246
|
||||
import aiohttp.web
|
||||
import natsort
|
||||
import regex
|
||||
import torch
|
||||
|
||||
# ComfyUI
|
||||
import server
|
||||
import execution
|
||||
import nodes
|
||||
import comfy.sd1_clip
|
||||
import comfy.samplers
|
||||
|
||||
comfy_graph = None
|
||||
comfy_graph_utils = None
|
||||
wat = None
|
||||
|
||||
try:
|
||||
import comfy_execution.graph as temp_graph
|
||||
import comfy_execution.graph_utils as temp_graph_utils
|
||||
comfy_graph = temp_graph
|
||||
comfy_graph_utils = temp_graph_utils
|
||||
# import comfy.graph as temp_graph
|
||||
# import comfy.graph_utils as temp_graph_utils
|
||||
wat = wat = __import__("wat.inspection.inspection").inspection.inspection.inspect_format
|
||||
comfy_graph = __import__("comfy_execution.graph").graph
|
||||
comfy_graph_utils = __import__("comfy_execution.graph_utils").graph_utils
|
||||
print("\033[95m" + f"{lib0246.HEAD_LOG}Topological Execution is detected." + "\033[0m")
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
@@ -90,10 +94,12 @@ def highway_impl(_prompt, _id, _workflow, _way_in, flag, kwargs):
|
||||
res = []
|
||||
|
||||
for i, curr_output in enumerate(curr_node["outputs"]):
|
||||
if curr_output.get("links") and curr_output["name"] not in lib0246.BLACKLIST:
|
||||
if curr_output["name"] not in lib0246.BLACKLIST:
|
||||
name = _workflow["workflow"]["extra"]["0246.__NAME__"][_id]["outputs"][str(i)]["name"][1:]
|
||||
if ("data", name) in _way_in:
|
||||
if curr_output["type"] == "*" or _way_in[("type", name)] == "*" or curr_output["type"] == _way_in[("type", name)]:
|
||||
if curr_output.get("links") is None:
|
||||
res.append([None])
|
||||
elif curr_output["type"] == "*" or _way_in[("type", name)] == "*" or curr_output["type"] == _way_in[("type", name)]:
|
||||
res.append(_way_in[("data", name)])
|
||||
else:
|
||||
raise Exception(f"Output \"{name}\" is not defined or is not of type \"{curr_output['type']}\". Expected \"{_way_in[('type', name)]}\".")
|
||||
@@ -542,16 +548,6 @@ def group_query_inst(group_dict, group_id, group_list = None, inst_curr = None):
|
||||
class CloudFunc:
|
||||
def __init__(self, kind):
|
||||
self.func = getattr(CloudFunc, f"func_{kind}")
|
||||
|
||||
@classmethod
|
||||
def func_text(cls, obj, hold, state):
|
||||
return obj.inst[state["index"]]["widgets_values"][0]
|
||||
|
||||
@classmethod
|
||||
def func_weight(cls, obj, hold, state):
|
||||
hold["data"] = list(map(lambda _: f"({re.sub(STR_BRACKET, STR_REPLACE, _[0])}: {lib0246.snap_place(_[1], round, 2)})", itertools.product(hold["data"], obj.inst[state["index"]]["widgets_values"][0])))
|
||||
state["index"] = None
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def func_rand(cls, obj, hold, state):
|
||||
@@ -661,6 +657,16 @@ class CloudFunc:
|
||||
hold["index"][i] = None
|
||||
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def func_text(cls, obj, hold, state):
|
||||
return obj.inst[state["index"]]["widgets_values"][0]
|
||||
|
||||
@classmethod
|
||||
def func_weight(cls, obj, hold, state):
|
||||
hold["data"] = list(map(lambda _: f"({re.sub(STR_BRACKET, STR_REPLACE, _[0])}: {lib0246.snap_place(_[1], round, 2)})", itertools.product(hold["data"], obj.inst[state["index"]]["widgets_values"][0])))
|
||||
state["index"] = None
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def func_merge(cls, obj, hold, state):
|
||||
@@ -687,6 +693,18 @@ class CloudData:
|
||||
self.order = None
|
||||
self.id = None
|
||||
|
||||
@classmethod
|
||||
def full_dict_to_data(cls, curr_id, inst_list, group_dict, db_dict = None, kwargs = None):
|
||||
dict_dupe = dict(filter(lambda item: item[0].split(":")[0].isnumeric(), kwargs.items()))
|
||||
if len(dict_dupe) == 0:
|
||||
return [
|
||||
CloudData().dict_to_data(curr_id, inst_list, group_dict, db_dict, dict_dupe)
|
||||
]
|
||||
return [
|
||||
CloudData().dict_to_data(curr_id, inst_list, group_dict, db_dict, dupe[0]) for dupe in
|
||||
lib0246.dict_product(dict_dupe)
|
||||
]
|
||||
|
||||
def dict_to_data(self, curr_id, inst_list, group_dict, db_dict = None, kwargs = None):
|
||||
if kwargs is not None:
|
||||
self.track = PROMPT_COUNT
|
||||
@@ -694,6 +712,7 @@ class CloudData:
|
||||
if db_dict is not None:
|
||||
self.db.update(db_dict)
|
||||
self.db[curr_id] = self.db.get(curr_id, {})
|
||||
|
||||
for inst in inst_list:
|
||||
old_id = inst["id"]
|
||||
new_id = str(uuid.uuid4())
|
||||
@@ -703,7 +722,7 @@ class CloudData:
|
||||
for key in kwargs:
|
||||
curr_int = key.split(":")[0]
|
||||
if curr_int.isnumeric() and int(curr_int) == inst["widgets_values"][0]:
|
||||
curr_value = kwargs[key][0]
|
||||
curr_value = kwargs[key]
|
||||
break
|
||||
match curr_value:
|
||||
case CloudData():
|
||||
@@ -779,6 +798,8 @@ class CloudData:
|
||||
else:
|
||||
self.db[curr_id][new_id] = old_id
|
||||
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def text_to_dict(cls, text):
|
||||
old_func = comfy.sd1_clip.parse_parentheses
|
||||
@@ -1071,6 +1092,28 @@ if not hasattr(execution, "recursive_execute") or \
|
||||
lib0246.hijack(comfy_graph, "get_input_info", get_input_info_param_handle, get_input_info_res_handle)
|
||||
lib0246.hijack(execution, "get_input_info", get_input_info_param_handle, get_input_info_res_handle)
|
||||
|
||||
def merge_result_data_func_handle(func, *args, **kwargs):
|
||||
old_output_is_list = args[1].OUTPUT_IS_LIST
|
||||
args[1].OUTPUT_IS_LIST = itertools.islice(args[1].OUTPUT_IS_LIST, len(args[0][0]))
|
||||
res = func(*args, **kwargs)
|
||||
args[1].OUTPUT_IS_LIST = old_output_is_list
|
||||
return res
|
||||
|
||||
def merge_result_data_param_handle(*args, **kwargs):
|
||||
if hasattr(args[1], "OUTPUT_IS_LIST") and isinstance(args[1].OUTPUT_IS_LIST, lib0246.OutputHandle):
|
||||
return merge_result_data_func_handle, tuple(), {}
|
||||
return None, tuple(), {}
|
||||
|
||||
lib0246.hijack(execution, "merge_result_data", merge_result_data_param_handle)
|
||||
|
||||
DEFAULT_JSON_ENCODER = json.JSONEncoder.default
|
||||
def wrapper_encoder_func_handle(self, obj):
|
||||
if isinstance(obj, lib0246.Wrapper):
|
||||
return obj.__wrapped__
|
||||
return DEFAULT_JSON_ENCODER(self, obj)
|
||||
|
||||
json.JSONEncoder.default = wrapper_encoder_func_handle
|
||||
|
||||
#####################################################################################
|
||||
######################################## API ########################################
|
||||
#####################################################################################
|
||||
@@ -1201,7 +1244,7 @@ class HighwayBatch:
|
||||
RETURN_TYPES = lib0246.ByPassTypeTuple(("HIGHWAY_PIPE", ))
|
||||
RETURN_NAMES = lib0246.ByPassTypeTuple(("_way_out", ))
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyRest()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyRest
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -1292,7 +1335,7 @@ class JunctionBatch:
|
||||
# To prevent people being stupid and we force them to use correct combination
|
||||
|
||||
if _mode == "batch":
|
||||
setattr(JunctionBatch, "OUTPUT_IS_LIST", lib0246.TautologyRest())
|
||||
setattr(JunctionBatch, "OUTPUT_IS_LIST", lib0246.TautologyRest)
|
||||
return junction_impl(self, _id, _prompt, _workflow, gather_junction_impl(_junc_in, _id), _offset, _in_mode = True, _out_mode = True, _offset_mode = True, **kwargs)
|
||||
else:
|
||||
try:
|
||||
@@ -1301,6 +1344,8 @@ class JunctionBatch:
|
||||
pass
|
||||
return junction_impl(self, _id, _prompt, _workflow, gather_junction_impl(_junc_in, _id), _offset, _in_mode = True, _out_mode = False, **kwargs)
|
||||
|
||||
# [TODO] "hoard" (keep batch when in) and "spread" (keep batch when out, else will spread to junction list and behave like "pluck" or "batch")
|
||||
|
||||
@classmethod
|
||||
def IS_CHANGED(cls, *args, **kwargs):
|
||||
return lib0246.check_update(kwargs["_offset"])
|
||||
@@ -1346,6 +1391,18 @@ class Count:
|
||||
temp = Count.COUNT_DB[_id]
|
||||
Count.COUNT_DB[_id] += 1
|
||||
|
||||
# [TODO] Syntax:
|
||||
# @12, 56, 99, ... # Specific number
|
||||
# (0, 9] # 0 to 9 (exclusive, inclusive)
|
||||
# [0, 9) # 0 to 9 (inclusive, exclusive)
|
||||
# [0, 9] # 0 to 9 (inclusive)
|
||||
# (0, 9) # 0 to 9 (exclusive)
|
||||
# [0, 9, 2] # 0 to 9 (inclusive) with step 2
|
||||
# (0, 9, 2) # 0 to 9 (exclusive) with step 2
|
||||
# [0, 9, 2) # 0 to 9 (inclusive, exclusive) with step 2
|
||||
# (0, 9, 2] # 0 to 9 (exclusive, inclusive) with step 2
|
||||
# @[0, 9], (1, 4, -2), 3, ... # Multiple ranges and numbers
|
||||
|
||||
return {
|
||||
"ui": {
|
||||
"text": [f"Count: {temp}, Track: {Count.COUNT_ID}"]
|
||||
@@ -1561,7 +1618,9 @@ class Hold:
|
||||
Hold.HOLD_DB[_id]["mode"] = _mode
|
||||
Hold.HOLD_DB[_id]["track"] = PROMPT_ID
|
||||
|
||||
match Hold.HOLD_DB[_key_id]["mode"]:
|
||||
# match Hold.HOLD_DB[_key_id]["mode"]:
|
||||
# _key_id can be invalid key
|
||||
match Hold.HOLD_DB.get(_key_id, {}).get("mode", ""):
|
||||
case "save":
|
||||
for curr in Hold.HOLD_DB[Hold.HOLD_DB[_key_id]["id"]]["data"]:
|
||||
Hold.HOLD_DB[_id]["data"].extend(curr)
|
||||
@@ -1570,7 +1629,7 @@ class Hold:
|
||||
case _:
|
||||
Hold.HOLD_DB[_id]["data"].extend(_data_in)
|
||||
|
||||
result = [Hold.HOLD_DB[_id]["data"], [None]]
|
||||
result = [Hold.HOLD_DB[_id]["data"], sum(Hold.HOLD_DB.get(_key_id, {}).get("data", [[None]]), [])]
|
||||
|
||||
ui_text += f"Passed, Size: {len(result[0])}, "
|
||||
elif param_flag:
|
||||
@@ -1588,7 +1647,7 @@ class Hold:
|
||||
[[None]]
|
||||
elif (
|
||||
mode_flag and \
|
||||
Hold.HOLD_DB[_id]["mode"] == "pin"
|
||||
Hold.HOLD_DB[_id].get("mode", "") == "pin"
|
||||
):
|
||||
result = [[None]] if _data_in is None or len(_data_in) == 0 else [_data_in]
|
||||
elif (
|
||||
@@ -1839,7 +1898,7 @@ class Beautify:
|
||||
"data": (lib0246.TautologyStr("*"), ),
|
||||
},
|
||||
"required": {
|
||||
"mode": (["basic", "more", "full", "json"], ),
|
||||
"mode": (["basic", "more", "full", "json", "wat"], ),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1870,6 +1929,8 @@ class Beautify:
|
||||
res_str = json.dumps(data, indent=2)
|
||||
except TypeError:
|
||||
res_str = "Cannot convert to JSON."
|
||||
case "wat":
|
||||
res_str = str(wat(data, dunder=True, long=True))
|
||||
|
||||
if res_str is None:
|
||||
res_str = lib0246.beautify_structure(data, 0, raw_mode)
|
||||
@@ -1903,17 +1964,24 @@ class Stringify:
|
||||
RETURN_TYPES = ("STRING", )
|
||||
RETURN_NAMES = ("_str", )
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = (True, )
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
def execute(self, _delimiter = None, _mode = None, _id = None, _prompt = None, _workflow = None, **kwargs):
|
||||
res = []
|
||||
cloud_delim = None
|
||||
_delimiter = copy.copy(_delimiter)
|
||||
|
||||
for value in kwargs.values():
|
||||
if isinstance(value, list):
|
||||
for item in value:
|
||||
if isinstance(item, CloudData) and (_mode[0] == "basic" or _mode[0] == "value"):
|
||||
item = _delimiter[0].join(map(str, item.data_eval(_id[0], _prompt[0], _workflow[0])))
|
||||
if cloud_delim is None:
|
||||
if _delimiter[-1] is None:
|
||||
raise Exception("Last delimiter in delimiter batch cannot be None if Cloud is present.")
|
||||
cloud_delim = _delimiter.pop()
|
||||
item = cloud_delim.join(map(str, item.data_eval(_id[0], _prompt[0], _workflow[0])))
|
||||
elif _mode[0] == "basic" and type(item).__str__ is object.__str__:
|
||||
continue
|
||||
elif _mode[0] == "value":
|
||||
@@ -1925,8 +1993,9 @@ class Stringify:
|
||||
res.append(item_str)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
res = _delimiter[0].join(res)
|
||||
|
||||
if _delimiter is not None and len(_delimiter) > 0 and all(isinstance(_, str) for _ in _delimiter):
|
||||
res = [curr.join(res) for curr in _delimiter]
|
||||
return {
|
||||
"ui": {
|
||||
"text": [res]
|
||||
@@ -1973,7 +2042,7 @@ class BoxRange:
|
||||
RETURN_TYPES = lib0246.ByPassTypeTuple(("*", ))
|
||||
RETURN_NAMES = lib0246.ByPassTypeTuple(("_data", ))
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyRest()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyRest
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -2189,7 +2258,7 @@ class ScriptNode:
|
||||
RETURN_TYPES = (lib0246.TautologyStr("*"), "SCRIPT_DATA", "SCRIPT_DATA", "SCRIPT_DATA")
|
||||
RETURN_NAMES = ("pipe_out", "script_pin_data", "script_exec_data", "script_res_data")
|
||||
INPUT_IS_LIST = False
|
||||
OUTPUT_IS_LIST = lib0246.ContradictAll()
|
||||
OUTPUT_IS_LIST = lib0246.ContradictAll
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -2579,7 +2648,7 @@ class Script:
|
||||
RETURN_TYPES = lib0246.ByPassTypeTuple(("SCRIPT_PIPE", ))
|
||||
RETURN_NAMES = lib0246.ByPassTypeTuple(("_script_out", ))
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyRest()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyRest
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -2695,7 +2764,7 @@ class Hub:
|
||||
|
||||
RETURN_TYPES = lib0246.TautologyDictStr()
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -2801,19 +2870,17 @@ class Cloud:
|
||||
RETURN_TYPES = lib0246.ByPassTypeTuple(("CLOUD_PIPE", ))
|
||||
RETURN_NAMES = lib0246.ByPassTypeTuple(("_cloud_out", ))
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
def execute(self, _id = None, _prompt = None, _workflow = None, **kwargs):
|
||||
res = CloudData()
|
||||
curr_cloud = copy.deepcopy(kwargs["cloud:cloud"][0])
|
||||
res.dict_to_data(_id[0], curr_cloud["inst"], curr_cloud["group"], None, kwargs)
|
||||
return {
|
||||
"ui": {
|
||||
"text": [""]
|
||||
},
|
||||
"result": [[res]]
|
||||
"result": [[*CloudData.full_dict_to_data(_id[0], curr_cloud["inst"], curr_cloud["group"], None, kwargs)]]
|
||||
}
|
||||
|
||||
######################################################################################
|
||||
@@ -2832,7 +2899,7 @@ class Switch:
|
||||
|
||||
RETURN_TYPES = lib0246.TautologyDictStr()
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -2894,7 +2961,10 @@ class Switch:
|
||||
global PROMPT_ID
|
||||
if Switch.SWITCH_TRACK is None or Switch.SWITCH_TRACK != PROMPT_ID:
|
||||
Switch.SWITCH_TRACK = PROMPT_ID
|
||||
Switch.SWITCH_PROMPT = copy.deepcopy(PROMPT_DATA)
|
||||
Switch.SWITCH_PROMPT = copy.deepcopy(
|
||||
PROMPT_DATA.__wrapped__ if isinstance(PROMPT_DATA, lib0246.Wrapper)
|
||||
else PROMPT_DATA
|
||||
)
|
||||
|
||||
valid_input = set()
|
||||
for key in kwargs:
|
||||
@@ -2916,6 +2986,7 @@ class Switch:
|
||||
######################################################################################
|
||||
|
||||
class Meta:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
@@ -2933,7 +3004,7 @@ class Meta:
|
||||
RETURN_TYPES = ("INT", "INT", "STRING", "STRING", "STRING", "STRING")
|
||||
RETURN_NAMES = ("batch_size", "data_size", "key_list", "type_list", "comfy_type", "py_type")
|
||||
INPUT_IS_LIST = True
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll()
|
||||
OUTPUT_IS_LIST = lib0246.TautologyAll
|
||||
FUNCTION = "execute"
|
||||
CATEGORY = "0246"
|
||||
|
||||
@@ -3149,6 +3220,8 @@ class Tag:
|
||||
# [TODO] CastReroute keep disconnecting when loading workflow
|
||||
# [TODO] Hub node cannot be copy-pasted between each tabs
|
||||
# [TODO] Beautify input pin name got stuck if connected to CastReroute
|
||||
# [TODO] Copy-pasting Cloud with "pin" does not retain position
|
||||
# [TODO] Find ways to hide control widgets in Hub
|
||||
|
||||
NODE_CLASS_MAPPINGS.update({
|
||||
"0246.Highway": Highway,
|
||||
@@ -3162,7 +3235,6 @@ NODE_CLASS_MAPPINGS.update({
|
||||
"0246.Beautify": Beautify,
|
||||
"0246.Stringify": Stringify,
|
||||
"0246.Merge": Merge,
|
||||
# "0246.Convert": Convert,
|
||||
"0246.BoxRange": BoxRange,
|
||||
"0246.ScriptNode": ScriptNode,
|
||||
"0246.ScriptRule": ScriptRule,
|
||||
@@ -3172,7 +3244,6 @@ NODE_CLASS_MAPPINGS.update({
|
||||
"0246.Cloud": Cloud,
|
||||
"0246.Switch": Switch,
|
||||
"0246.Meta": Meta,
|
||||
# "0246.Pick": Pick,
|
||||
"0246.Tag": Tag,
|
||||
})
|
||||
|
||||
@@ -3188,7 +3259,6 @@ NODE_DISPLAY_NAME_MAPPINGS.update({
|
||||
"0246.Beautify": "Beautify",
|
||||
"0246.Stringify": "Stringify",
|
||||
"0246.Merge": "Merge",
|
||||
# "0246.Convert": "Convert",
|
||||
"0246.BoxRange": "Box Range",
|
||||
"0246.ScriptNode": "Script Node",
|
||||
"0246.ScriptRule": "Script Rule",
|
||||
@@ -3198,8 +3268,7 @@ NODE_DISPLAY_NAME_MAPPINGS.update({
|
||||
"0246.Cloud": "Cloud",
|
||||
"0246.Switch": "Switch",
|
||||
"0246.Meta": "Meta",
|
||||
# "0246.Pick": "Pick",
|
||||
"0246.Tag": "Tag",
|
||||
})
|
||||
|
||||
print("\033[95m" + lib0246.HEAD_LOG + "Loaded all nodes and apis." + "\033[0m")
|
||||
print("\033[95m" + lib0246.HEAD_LOG + "Loaded all nodes and apis." + "\033[0m")
|
||||
+2
-1
@@ -1,2 +1,3 @@
|
||||
wrapt
|
||||
natsort
|
||||
natsort
|
||||
wat-inspector
|
||||
@@ -9,6 +9,7 @@ import itertools
|
||||
import math
|
||||
import collections
|
||||
import random
|
||||
import copy
|
||||
|
||||
import PIL
|
||||
import numpy
|
||||
@@ -66,52 +67,26 @@ class WildDict(dict):
|
||||
def __getitem__(self, key):
|
||||
return None
|
||||
|
||||
class TautologyDictStr(dict):
|
||||
class TautologyDictStr(list):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.update(*args, **kwargs)
|
||||
self.extend(args)
|
||||
|
||||
def __getitem__(self, index):
|
||||
if isinstance(index, str) or isinstance(index, int):
|
||||
return TautologyStr("")
|
||||
return super().__getitem__(index)
|
||||
|
||||
class TautologyRest(dict):
|
||||
class OutputHandle(list):
|
||||
def __init__(self, iter):
|
||||
self.iter = iter
|
||||
|
||||
def __iter__(self):
|
||||
yield False
|
||||
while True:
|
||||
yield True
|
||||
return self.iter()
|
||||
|
||||
def __getitem__(self, index):
|
||||
if index == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
class ContradictRest(dict):
|
||||
def __iter__(self):
|
||||
yield True
|
||||
while True:
|
||||
yield False
|
||||
|
||||
def __getitem__(self, index):
|
||||
if index == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
class TautologyAll(dict):
|
||||
def __iter__(self):
|
||||
while True:
|
||||
yield True
|
||||
|
||||
def __getitem__(self, index):
|
||||
return True
|
||||
|
||||
class ContradictAll(dict):
|
||||
def __iter__(self):
|
||||
while True:
|
||||
yield False
|
||||
|
||||
def __getitem__(self, index):
|
||||
return False
|
||||
TautologyRest = OutputHandle(lambda: itertools.chain([False], itertools.cycle([True])))
|
||||
ContradictRest = OutputHandle(lambda: itertools.chain([True], itertools.cycle([False])))
|
||||
TautologyAll = OutputHandle(lambda: itertools.cycle([True]))
|
||||
ContradictAll = OutputHandle(lambda: itertools.cycle([False]))
|
||||
|
||||
######################################################################################
|
||||
######################################## UTIL ########################################
|
||||
@@ -390,6 +365,9 @@ class Wrapper(wrapt.ObjectProxy):
|
||||
super().__init__(wrapped)
|
||||
self._0246 = data
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
return Wrapper(copy.deepcopy(self.__wrapped__, memo), copy.deepcopy(self._0246, memo))
|
||||
|
||||
def check_update(data):
|
||||
if isinstance(data, list):
|
||||
data = data[0]
|
||||
|
||||
@@ -480,6 +480,7 @@ app.registerExtension({
|
||||
if (!this.mark)
|
||||
app.graph.extra["0246.VERSION"] = [0, 0, 4];
|
||||
});
|
||||
window.monitor_array = monitor_array;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+74
-75
@@ -6,87 +6,86 @@ import * as wg0246 from "./widgets.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "0246.Node",
|
||||
async setup (app) {
|
||||
{
|
||||
const reroute_class = lib0246.clone_class(LiteGraph.registered_node_types.Reroute);
|
||||
registerCustomNodes (app) {
|
||||
const reroute_class = lib0246.clone_class(LiteGraph.registered_node_types.Reroute);
|
||||
|
||||
reroute_class.prototype.onNodeCreated = function() {
|
||||
const DATA_TEMP = [];
|
||||
reroute_class.prototype.onNodeCreated = function() {
|
||||
const DATA_TEMP = [];
|
||||
|
||||
lib0246.hijack(this, "onConnectionsChange", function () {
|
||||
if (arguments[2])
|
||||
if (!this.mark) {
|
||||
DATA_TEMP[0] = this.self.inputs[0].type;
|
||||
DATA_TEMP[1] = this.self.outputs[0].type;
|
||||
DATA_TEMP[2] = this.self.size[0];
|
||||
DATA_TEMP[3] = app.graph.getNodeById(arguments[3]?.target_id)?.inputs?.[arguments[3]?.target_slot];
|
||||
if (DATA_TEMP[3]?.type === "*") {
|
||||
DATA_TEMP[4] = DATA_TEMP[3].type;
|
||||
DATA_TEMP[3].type = this.self.widgets[0].value;
|
||||
}
|
||||
this.self.inputs[0].type = this.self.outputs[0].type = this.self.widgets[0].value;
|
||||
} else {
|
||||
this.self.inputs[0].type = DATA_TEMP[0];
|
||||
this.self.outputs[0].type = DATA_TEMP[1];
|
||||
this.self.size[0] = DATA_TEMP[2];
|
||||
if (DATA_TEMP[3])
|
||||
DATA_TEMP[3].type = DATA_TEMP[4];
|
||||
lib0246.hijack(this, "onConnectionsChange", function () {
|
||||
if (arguments[2])
|
||||
if (!this.mark) {
|
||||
DATA_TEMP[0] = this.self.inputs[0].type;
|
||||
DATA_TEMP[1] = this.self.outputs[0].type;
|
||||
DATA_TEMP[2] = this.self.size[0];
|
||||
DATA_TEMP[3] = app.graph.getNodeById(arguments[3]?.target_id)?.inputs?.[arguments[3]?.target_slot];
|
||||
if (DATA_TEMP[3]?.type === "*") {
|
||||
DATA_TEMP[4] = DATA_TEMP[3].type;
|
||||
DATA_TEMP[3].type = this.self.widgets[0].value;
|
||||
}
|
||||
});
|
||||
|
||||
const type_widget = this.addWidget("combo", "", "*", function(value, widget, node) {
|
||||
let curr_input_node = node.getInputNode(0),
|
||||
curr_output_node = node.getOutputNodes(0),
|
||||
prev_input_slot = app.graph.links?.[node.inputs[0].link]?.origin_slot,
|
||||
prev_output_slot = [];
|
||||
|
||||
if (node.outputs[0].links)
|
||||
for (let i = 0; i < node.outputs[0].links.length; ++ i)
|
||||
prev_output_slot.push(app.graph.links[node.outputs[0].links[i]].target_slot);
|
||||
|
||||
node.disconnectInput(0);
|
||||
node.disconnectOutput(0);
|
||||
|
||||
wg0246.process_reroute(node);
|
||||
|
||||
if (curr_output_node && curr_output_node.length > 0) {
|
||||
node.inputs[0].widget = curr_output_node[0].inputs[prev_output_slot[0]].widget;
|
||||
for (let i = 0; i < curr_output_node.length; ++ i)
|
||||
node.connect(0, curr_output_node[i], prev_output_slot[i]);
|
||||
} else
|
||||
node.inputs[0].widget = {};
|
||||
|
||||
if (curr_input_node)
|
||||
curr_input_node.connect(prev_input_slot, node, 0);
|
||||
}, {
|
||||
values: wg0246.type_defs
|
||||
});
|
||||
|
||||
type_widget.y = 3;
|
||||
let prev_size = this.computeSize();
|
||||
prev_size[0] = 100;
|
||||
|
||||
this.serialize_widgets = true;
|
||||
|
||||
this.setSize(prev_size);
|
||||
};
|
||||
|
||||
lib0246.hijack(reroute_class.prototype, "onDrawForeground", function () {
|
||||
if (!this.mark)
|
||||
wg0246.process_reroute(this.self);
|
||||
this.self.inputs[0].type = this.self.outputs[0].type = this.self.widgets[0].value;
|
||||
} else {
|
||||
this.self.inputs[0].type = DATA_TEMP[0];
|
||||
this.self.outputs[0].type = DATA_TEMP[1];
|
||||
this.self.size[0] = DATA_TEMP[2];
|
||||
if (DATA_TEMP[3])
|
||||
DATA_TEMP[3].type = DATA_TEMP[4];
|
||||
}
|
||||
});
|
||||
|
||||
LiteGraph.registerNodeType(
|
||||
"0246.CastReroute",
|
||||
Object.assign(reroute_class, {
|
||||
title_mode: LiteGraph.NO_TITLE,
|
||||
title: "Cast Reroute",
|
||||
collapsable: false,
|
||||
})
|
||||
);
|
||||
const type_widget = this.addWidget("combo", "", "*", function(value, widget, node) {
|
||||
let curr_input_node = node.getInputNode(0),
|
||||
curr_output_node = node.getOutputNodes(0),
|
||||
prev_input_slot = app.graph.links?.[node.inputs[0].link]?.origin_slot,
|
||||
prev_output_slot = [];
|
||||
|
||||
if (node.outputs[0].links)
|
||||
for (let i = 0; i < node.outputs[0].links.length; ++ i)
|
||||
prev_output_slot.push(app.graph.links[node.outputs[0].links[i]].target_slot);
|
||||
|
||||
node.disconnectInput(0);
|
||||
node.disconnectOutput(0);
|
||||
|
||||
reroute_class.category = "0246";
|
||||
}
|
||||
wg0246.process_reroute(node);
|
||||
|
||||
if (curr_output_node && curr_output_node.length > 0) {
|
||||
node.inputs[0].widget = curr_output_node[0].inputs[prev_output_slot[0]].widget;
|
||||
for (let i = 0; i < curr_output_node.length; ++ i)
|
||||
node.connect(0, curr_output_node[i], prev_output_slot[i]);
|
||||
} else
|
||||
node.inputs[0].widget = {};
|
||||
|
||||
if (curr_input_node)
|
||||
curr_input_node.connect(prev_input_slot, node, 0);
|
||||
}, {
|
||||
values: wg0246.type_defs
|
||||
});
|
||||
|
||||
type_widget.y = 3;
|
||||
let prev_size = this.computeSize();
|
||||
prev_size[0] = 100;
|
||||
|
||||
this.serialize_widgets = true;
|
||||
|
||||
this.setSize(prev_size);
|
||||
};
|
||||
|
||||
lib0246.hijack(reroute_class.prototype, "onDrawForeground", function () {
|
||||
if (!this.mark)
|
||||
wg0246.process_reroute(this.self);
|
||||
});
|
||||
|
||||
// [TODO] CastReroute being late registered.
|
||||
LiteGraph.registerNodeType(
|
||||
"0246.CastReroute",
|
||||
Object.assign(reroute_class, {
|
||||
title_mode: LiteGraph.NO_TITLE,
|
||||
title: "Cast Reroute",
|
||||
collapsable: false,
|
||||
})
|
||||
);
|
||||
|
||||
reroute_class.category = "0246";
|
||||
},
|
||||
nodeCreated(node) {
|
||||
switch (node.comfyClass) {
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ export async function try_import(name) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
export async function load_script(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
@@ -25,7 +25,7 @@ export async function load_script(url) {
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
export function compare_version(a, b) {
|
||||
for (let i = 0; i < a.length; ++ i) {
|
||||
if (a[i] > b[i])
|
||||
|
||||
+2
-2
@@ -4576,7 +4576,7 @@ app.registerExtension({
|
||||
// }
|
||||
// calc_flex(node, node.size[0]);
|
||||
// console.log(node.size);
|
||||
node.hubSize();
|
||||
// node.hubSize();
|
||||
// app.canvas.setDirty(true);
|
||||
}
|
||||
}
|
||||
@@ -4814,4 +4814,4 @@ app.registerExtension({
|
||||
|
||||
// window.test = [
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
// ];
|
||||
// ];
|
||||
Reference in New Issue
Block a user