Skip to content

Commit de7d9c9

Browse files
Merge branch 'main' into feat/mediapipe-vision
2 parents 776b2b3 + 97d028b commit de7d9c9

File tree

7 files changed

+930
-15
lines changed

7 files changed

+930
-15
lines changed

.github/workflows/publish.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ on:
88
paths:
99
- "pyproject.toml"
1010

11+
permissions:
12+
issues: write
13+
1114
jobs:
1215
publish-node:
1316
name: Publish Custom Node to registry
1417
runs-on: ubuntu-latest
15-
# if this is a forked repository. Skipping the workflow.
16-
if: github.event.repository.fork == false
18+
if: ${{ github.repository_owner == 'ryanontheinside' }}
1719
steps:
1820
- name: Check out code
1921
uses: actions/checkout@v4
2022
- name: Publish Custom Node
21-
uses: Comfy-Org/publish-node-action@main
23+
uses: Comfy-Org/publish-node-action@v1
2224
with:
2325
## Add your own personal access token to your Github Repository secrets and reference it here.
2426
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}

node_wrappers/realtimenodes/controls/state_management_controls.py

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from ....src.realtimenodes.control_base import ControlNodeBase
2+
import copy
3+
from ....src.utils.general_utils import AlwaysEqualProxy
24

35
class StateResetNode(ControlNodeBase):
46
"""Node that resets all control node states when triggered"""
@@ -21,12 +23,8 @@ def INPUT_TYPES(cls):
2123
CATEGORY = "Realtime Nodes/control/utility"
2224

2325
def update(self, trigger, always_execute=True):
24-
print(f"\n=== StateResetNode UPDATE - node_id: {self.node_id} ===")
25-
print(f"States before potential reset: {self.state_manager._states}")
2626
if trigger:
27-
print("RESETTING ALL STATES")
2827
self.state_manager.clear_all_states()
29-
print(f"States after reset: {self.state_manager._states}")
3028
return (True,)
3129
return (False,)
3230

@@ -52,19 +50,87 @@ def INPUT_TYPES(cls):
5250
CATEGORY = "Realtime Nodes/control/utility"
5351

5452
def update(self, increment, always_execute=True):
55-
print(f"\n=== StateTestNode UPDATE - node_id: {self.node_id} ===")
56-
print(f"All states before get: {self.state_manager._states}")
57-
5853
state = self.get_state({
5954
"counter": 0
6055
})
61-
print(f"Retrieved state: {state}")
6256

6357
state["counter"] += increment
64-
print(f"Updated state before save: {state}")
65-
58+
6659
self.set_state(state)
67-
print(f"All states after save: {self.state_manager._states}")
6860

6961
return (state["counter"],)
7062

63+
64+
65+
class GetStateNode(ControlNodeBase):
66+
"""
67+
Node that retrieves a value from the global state using a user-specified key.
68+
"""
69+
CATEGORY = "utils"
70+
RETURN_TYPES = (AlwaysEqualProxy("*"),)
71+
RETURN_NAMES = ("value",)
72+
FUNCTION = "update"
73+
DESCRIPTION = "Retrieve a value from the global state using the given key. If the key is not found, return the default value."
74+
@classmethod
75+
def INPUT_TYPES(cls):
76+
inputs = super().INPUT_TYPES()
77+
inputs["required"].update({
78+
"key": ("STRING", {"default": "default_key", "tooltip": "The key to retrieve the value from. If not provided, the default value will be returned."}),
79+
"default_value": (AlwaysEqualProxy("*"), {"tooltip": "The value to return if the key is not found."}),
80+
"use_default": ("BOOLEAN", {"default": False, "tooltip": "If True, the default value will be returned if the key is not found."}),
81+
})
82+
return inputs
83+
84+
def update(self, key: str, default_value, use_default: bool, always_execute=True):
85+
"""
86+
Retrieve a value from the global state using the given key.
87+
"""
88+
if not key or use_default:
89+
return (default_value,)
90+
91+
# Get the shared state dictionary
92+
shared_state = self.state_manager.get_state("__shared_keys__", {})
93+
94+
# Check if the key exists
95+
if key in shared_state:
96+
return (shared_state[key],)
97+
98+
# Return default value if key not found
99+
return (default_value,)
100+
101+
class SetStateNode(ControlNodeBase):
102+
"""
103+
Node that stores a value in the global state with a user-specified key.
104+
The value will be accessible in future workflow runs through GetStateNode.
105+
"""
106+
CATEGORY = "utils"
107+
RETURN_TYPES = (AlwaysEqualProxy("*"),)
108+
RETURN_NAMES = ("value",)
109+
FUNCTION = "update"
110+
OUTPUT_NODE = True
111+
DESCRIPTION = "Store a value in the global state with the given key. The value will be accessible in future workflow runs through GetStateNode."
112+
@classmethod
113+
def INPUT_TYPES(cls):
114+
inputs = super().INPUT_TYPES()
115+
inputs["required"].update({
116+
"key": ("STRING", {"default": "default_key", "tooltip": "The key to store the value under. If not provided, the value will not be stored."}),
117+
"value": (AlwaysEqualProxy("*"), {"tooltip": "The value to store in the global state."}),
118+
})
119+
return inputs
120+
121+
def update(self, key: str, value, always_execute=True):
122+
"""
123+
Store a value in the global state with the given key.
124+
"""
125+
if not key:
126+
return (value,)
127+
128+
try:
129+
shared_state = self.state_manager.get_state("__shared_keys__", {})
130+
shared_state[key] = copy.deepcopy(value)
131+
self.state_manager.set_state("__shared_keys__", shared_state)
132+
except Exception as e:
133+
print(f"[State Node] Error storing value: {str(e)}")
134+
135+
return (value,)
136+

node_wrappers/realtimenodes/logic/__init__.py

Whitespace-only changes.

node_wrappers/realtimenodes/media/media_pipe_nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def INPUT_TYPES(cls):
4242
RETURN_NAMES = ("debug_image", "hand_data")
4343
FUNCTION = "track_hands"
4444
CATEGORY = "image/processing"
45-
45+
DESCRIPTION = "(((EXPERIMENTAL))) Track hands in an image using MediaPipe. Returns a debug image with landmarks and a dictionary of hand data."
4646
def __init__(self):
4747
self.last_detection_conf = 0.5
4848
self.last_tracking_conf = 0.5

0 commit comments

Comments
 (0)