Files

174 lines
5.8 KiB
Python

"""
Custom Loop Reset Node for Boyo's Video Workflow
Standalone implementation without EasyUse dependencies
Resets loop counters to zero when triggered by completion signals
"""
import time
# Use ComfyUI's standard any type instead of custom implementation
any_type = "*"
# Simple cache implementation
_cache = {}
def cache_get(key, default=None):
return _cache.get(key, default)
def cache_update(key, value):
_cache[key] = value
def cache_remove(key):
if key in _cache:
del _cache[key]
class BoyoLoopReset:
"""
Master reset node that can force all connected loop nodes back to zero.
Triggered by completion signals from workflow sections.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"trigger": (any_type, {}), # Completion signal from workflow
"reset_mode": (["immediate", "delayed"], {"default": "immediate"}),
},
"optional": {
"loop_id_1": ("STRING", {"default": ""}),
"loop_id_2": ("STRING", {"default": ""}),
"loop_id_3": ("STRING", {"default": ""}),
"loop_id_4": ("STRING", {"default": ""}),
"loop_id_5": ("STRING", {"default": ""}),
"delay_seconds": ("FLOAT", {"default": 0.1, "min": 0.0, "max": 10.0, "step": 0.1}),
}
}
RETURN_TYPES = (any_type, "INT", "STRING")
RETURN_NAMES = ("trigger_out", "reset_count", "status")
FUNCTION = "reset_loops"
CATEGORY = "Boyo/Logic"
def reset_loops(self, trigger, reset_mode, loop_id_1="", loop_id_2="", loop_id_3="",
loop_id_4="", loop_id_5="", delay_seconds=0.1):
"""
Reset specified loop counters to zero
"""
# Collect all non-empty loop IDs
loop_ids = [lid for lid in [loop_id_1, loop_id_2, loop_id_3, loop_id_4, loop_id_5] if lid.strip()]
if not loop_ids:
print("BoyoLoopReset: No loop IDs provided - nothing to reset")
return (trigger, 0, "No loops specified")
# Add delay if requested
if reset_mode == "delayed" and delay_seconds > 0:
time.sleep(delay_seconds)
reset_count = 0
failed_resets = []
# Reset each specified loop
for loop_id in loop_ids:
try:
# Check if cache entry exists
cached_data = cache_get(loop_id, None)
if cached_data is not None:
# Reset the counter to 0
# Based on forLoopEnd implementation, we need to reset the iteration count
if isinstance(cached_data, dict) and 'current_iteration' in cached_data:
cached_data['current_iteration'] = 0
cache_update(loop_id, cached_data)
else:
# Simple counter reset
cache_update(loop_id, 0)
reset_count += 1
print(f"BoyoLoopReset: Reset loop '{loop_id}' to zero")
else:
# Initialize cache entry if it doesn't exist
cache_update(loop_id, 0)
reset_count += 1
print(f"BoyoLoopReset: Initialized loop '{loop_id}' to zero")
except Exception as e:
failed_resets.append(loop_id)
print(f"BoyoLoopReset: Failed to reset loop '{loop_id}': {str(e)}")
# Generate status message
if failed_resets:
status = f"Reset {reset_count} loops, failed: {', '.join(failed_resets)}"
else:
status = f"Successfully reset {reset_count} loops"
log_node_info("BoyoLoopReset", status)
return (trigger, reset_count, status)
class BoyoLoopCounter:
"""
Simple counter that can be reset by the BoyoLoopReset node
Alternative to complex loop nodes when you just need a basic counter
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"trigger": (any_type, {}),
"counter_id": ("STRING", {"default": "counter_1"}),
"increment": ("INT", {"default": 1, "min": 0, "max": 100}),
"max_count": ("INT", {"default": 6, "min": 1, "max": 1000}),
},
"optional": {
"reset_to_zero": ("BOOLEAN", {"default": False}),
}
}
RETURN_TYPES = ("INT", "BOOLEAN", any_type)
RETURN_NAMES = ("count", "is_complete", "trigger_out")
FUNCTION = "count"
CATEGORY = "Boyo/Logic"
def count(self, trigger, counter_id, increment, max_count, reset_to_zero=False):
"""
Increment counter and check if complete
"""
# Handle manual reset
if reset_to_zero:
cache_update(counter_id, 0)
print(f"BoyoLoopCounter: Manually reset counter '{counter_id}' to zero")
return (0, False, trigger)
# Get current count from cache
current_count = cache_get(counter_id, 0)
# Increment counter
new_count = current_count + increment
# Update cache
cache_update(counter_id, new_count)
# Check if complete
is_complete = new_count >= max_count
print(f"BoyoLoopCounter: Counter '{counter_id}': {new_count}/{max_count}")
return (new_count, is_complete, trigger)
# Node mappings for ComfyUI
NODE_CLASS_MAPPINGS = {
"BoyoLoopReset": BoyoLoopReset,
"BoyoLoopCounter": BoyoLoopCounter,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"BoyoLoopReset": "Boyo Loop Reset",
"BoyoLoopCounter": "Boyo Loop Counter",
}