@@ -90,7 +90,7 @@ def check_lazy_status(self, **kwargs) -> list[str]:
9090 # Check if condition
9191 if kwargs .get ("if" , False ) and kwargs .get ("then" ) is None :
9292 needed .append ("then" )
93- return needed # If main condition is true, we only need "then"
93+ return needed # If the main condition is true, we only need "then"
9494
9595 # Check each elif condition
9696 elif_index = 0
@@ -153,7 +153,7 @@ class SwitchCase(ComfyNodeABC):
153153 def INPUT_TYPES (cls ):
154154 return {
155155 "required" : ContainsDynamicDict ({
156- "selector " : (IO .INT , {"default" : 0 , "min" : 0 }),
156+ "select " : (IO .INT , {"default" : 0 , "min" : 0 }),
157157 "case_0" : (IO .ANY , {"lazy" : True , "_dynamic" : "number" }),
158158 }),
159159 "optional" : {
@@ -167,29 +167,29 @@ def INPUT_TYPES(cls):
167167 DESCRIPTION = cleandoc (__doc__ or "" )
168168 FUNCTION = "execute"
169169
170- def check_lazy_status (self , selector : int , ** kwargs ) -> list [str ]:
170+ def check_lazy_status (self , select : int , ** kwargs ) -> list [str ]:
171171 needed = []
172172
173- # Check for needed case inputs based on selector
173+ # Check for necessary case inputs based on select
174174 case_count = 0
175175 for key , value in kwargs .items ():
176176 if key .startswith ("case_" ):
177177 try :
178178 case_index = int (key .split ("_" )[1 ])
179179 case_count = max (case_count , case_index + 1 )
180- if value is None and selector == case_index :
180+ if value is None and select == case_index :
181181 needed .append (key )
182182 except ValueError :
183183 pass # Not a numeric case key
184184
185- # Check if default is needed when selector is out of range
186- if "default" in kwargs and kwargs ["default" ] is None and not 0 <= selector < case_count :
185+ # Check if default is needed when select is out of range
186+ if "default" in kwargs and kwargs ["default" ] is None and not 0 <= select < case_count :
187187 needed .append ("default" )
188188
189189 return needed
190190
191191 def execute (self , selector : int , ** kwargs ) -> tuple [Any ]:
192- # Build cases array from all case_X inputs
192+ # Build a case array from all case_X inputs
193193 cases = []
194194 for i in range (len (kwargs )):
195195 case_key = f"case_{ i } "
@@ -202,10 +202,44 @@ def execute(self, selector: int, **kwargs) -> tuple[Any]:
202202 if 0 <= selector < len (cases ) and cases [selector ] is not None :
203203 return (cases [selector ],)
204204
205- # If selector is out of range or the selected case is None, return default
205+ # If select is out of range or the selected case is None, return default
206206 return (kwargs .get ("default" ),)
207207
208208
209+ class DisableFlow (ComfyNodeABC ):
210+ """
211+ Conditionally enable or disable a flow.
212+
213+ This node takes a value and either passes it through or blocks execution
214+ based on the 'select' parameter. When 'select' is True, the value passes through;
215+ when False, execution is blocked.
216+ """
217+ @classmethod
218+ def INPUT_TYPES (cls ):
219+ return {
220+ "required" : {
221+ "value" : (IO .ANY , {}),
222+ "select" : (IO .BOOLEAN , {"default" : True }),
223+ }
224+ }
225+
226+ RETURN_TYPES = (IO .ANY ,)
227+ RETURN_NAMES = ("value" ,)
228+ CATEGORY = "Basic/flow control"
229+ DESCRIPTION = cleandoc (__doc__ or "" )
230+ FUNCTION = "execute"
231+
232+ @classmethod
233+ def IS_CHANGED (s , value : Any ):
234+ return float ("NaN" ) # not equal to anything -> trigger recalculation
235+
236+ def execute (self , value : Any , select : bool = True ) -> tuple [Any ]:
237+ if select :
238+ return (value ,)
239+ else :
240+ return (ExecutionBlocker (None ),)
241+
242+
209243class FlowSelect (ComfyNodeABC ):
210244 """
211245 Select the direction of the flow.
@@ -237,6 +271,35 @@ def select(self, value, select = True) -> tuple[Any, Any]:
237271 return ExecutionBlocker (None ), value
238272
239273
274+ class ForceCalculation (ComfyNodeABC ):
275+ """
276+ Forces recalculation of the connected nodes.
277+
278+ This node passes the input directly to the output but prevents caching
279+ by marking itself as an output node and also indicates the out has changed.
280+ Use this when you need to ensure nodes are always recalculated.
281+ """
282+
283+ OUTPUT_NODE = True # Marks as an output node to force calculation
284+
285+ @classmethod
286+ def INPUT_TYPES (cls ):
287+ return {
288+ "required" : {
289+ "value" : (IO .ANY , {}),
290+ }
291+ }
292+
293+ RETURN_TYPES = (IO .ANY ,)
294+ RETURN_NAMES = ("value" ,)
295+ CATEGORY = "Basic/flow control"
296+ DESCRIPTION = cleandoc (__doc__ or "" )
297+ FUNCTION = "execute"
298+
299+ def execute (self , value : Any ) -> tuple [Any , int ]:
300+ return (value ,)
301+
302+
240303class ExecutionOrder (ComfyNodeABC ):
241304 """
242305 Force execution order in the workflow.
@@ -268,14 +331,18 @@ def execute(self, **kwargs) -> tuple[Any]:
268331 "Basic data handling: IfElse" : IfElse ,
269332 "Basic data handling: IfElifElse" : IfElifElse ,
270333 "Basic data handling: SwitchCase" : SwitchCase ,
334+ "Basic data handling: DisableFlow" : DisableFlow ,
271335 "Basic data handling: FlowSelect" : FlowSelect ,
336+ "Basic data handling: ForceCalculation" : ForceCalculation ,
272337 "Basic data handling: ExecutionOrder" : ExecutionOrder ,
273338}
274339
275340NODE_DISPLAY_NAME_MAPPINGS = {
276341 "Basic data handling: IfElse" : "if/else" ,
277342 "Basic data handling: IfElifElse" : "if/elif/.../else" ,
278343 "Basic data handling: SwitchCase" : "switch/case" ,
344+ "Basic data handling: DisableFlow" : "disable flow" ,
279345 "Basic data handling: FlowSelect" : "flow select" ,
346+ "Basic data handling: ForceCalculation" : "force calculation" ,
280347 "Basic data handling: ExecutionOrder" : "force execution order" ,
281348}
0 commit comments