ContinuouslyChanging: Difference between revisions

From Resonite Wiki
misinformation I wrote :( fixing it tho
m link
(One intermediate revision by the same user not shown)
Line 2: Line 2:


<translate>
<translate>
'''ContinuouslyChanging''' is an attribute applied to [[ProtoFlux]] nodes (or outputs to said node) that forces evaluation of any connected listener nodes every [[update]].
<!--T:1-->
'''ContinuouslyChanging''' is an attribute applied to [[ProtoFlux]] nodes (or outputs to said node) that forces evaluation of any connected [[listener nodes]] every [[update]].


<!--T:2-->
Listener nodes are nodes that listen for changes of any kind in the node group it's connected to, updating their state when such changes are made. All listener nodes implement the [[Type:IExecutionChangeListener|IExecutionChangeListener]] interface, and a list of nodes can be found there.
Listener nodes are nodes that listen for changes of any kind in the node group it's connected to, updating their state when such changes are made. All listener nodes implement the [[Type:IExecutionChangeListener|IExecutionChangeListener]] interface, and a list of nodes can be found there.


<!--T:3-->
Usually, listener nodes only evaluate the node chain every time they register a change propagated from an input. These changes are either captured from the [[Data Model]]'s own change handler (such as when one [[ProtoFlux:Write|writes]] to a [[Type:SyncField|SyncField]]) or by forcibly changing the nodes in the node group (such as by adding a new node). However, when <em>any node</em> in the node group connected to the listener is marked as <code>ContinuouslyChanging</code>, the listener will forcibly update <em>all</em> inputs every update.
Usually, listener nodes only evaluate the node chain every time they register a change propagated from an input. These changes are either captured from the [[Data Model]]'s own change handler (such as when one [[ProtoFlux:Write|writes]] to a [[Type:SyncField|SyncField]]) or by forcibly changing the nodes in the node group (such as by adding a new node). However, when <em>any node</em> in the node group connected to the listener is marked as <code>ContinuouslyChanging</code>, the listener will forcibly update <em>all</em> inputs every update.


<!--T:4-->
Inspecting a ProtoFlux node in an inspector will provide more information on what nodes are being evaluated every update. Listener nodes will be marked with <code>ContinuouslyChanging: True</code> in the inspector to indicate that it is evaluating its input every update. If the <code>Group</code> that any given node is part of has <code>ContinuousChanges</code> set to <code>True</code>, then that node is being evaluated every update.
Inspecting a ProtoFlux node in an inspector will provide more information on what nodes are being evaluated every update. Listener nodes will be marked with <code>ContinuouslyChanging: True</code> in the inspector to indicate that it is evaluating its input every update. If the <code>Group</code> that any given node is part of has <code>ContinuousChanges</code> set to <code>True</code>, then that node is being evaluated every update.


<!--T:5-->
Not all listener nodes in a chain will be marked ContinuouslyChanging, even if the entire node group is being evaluated from another listener node. See the example to the right.
Not all listener nodes in a chain will be marked ContinuouslyChanging, even if the entire node group is being evaluated from another listener node. See the example to the right.


<!--T:6-->
[[File:ProtoFlux Example ContinuouslyChanging.webp|thumb|right|In this example, a [[ProtoFlux:Continuously Changing Relay|Continuously Changing Relay]] is connected to one root slot, getting its name, and plugged into an [[ProtoFlux:Add|Add]] node with a [[ProtoFlux:Find Child By Name|Find Child By Name]]. The string display is flagged as ContinuouslyChanging due to being a listener of a node with the ContinuouslyChanging attribute. Because of this, the Find Child By Name node is evaluated every frame, even if its output itself is not being plugged into its own ContinuouslyChanging node. Additionally, despite the node chain being evaluated every frame, the slot display will <em>not</em> be evaluated every frame, and is not marked ContinuouslyChanging]]
[[File:ProtoFlux Example ContinuouslyChanging.webp|thumb|right|In this example, a [[ProtoFlux:Continuously Changing Relay|Continuously Changing Relay]] is connected to one root slot, getting its name, and plugged into an [[ProtoFlux:Add|Add]] node with a [[ProtoFlux:Find Child By Name|Find Child By Name]]. The string display is flagged as ContinuouslyChanging due to being a listener of a node with the ContinuouslyChanging attribute. Because of this, the Find Child By Name node is evaluated every frame, even if its output itself is not being plugged into its own ContinuouslyChanging node. Additionally, despite the node chain being evaluated every frame, the slot display will <em>not</em> be evaluated every frame, and is not marked ContinuouslyChanging]]
</translate>
</translate>


== <translate>Practical Usage</translate> ==
== <translate><!--T:7--> Practical Usage</translate> ==


<translate>
<translate>
<!--T:8-->
The existence of ContinuouslyChanging nodes is generally not necessary knowledge to excel at ProtoFlux (as a [[Core Concepts|Core Concept]]). However, there are a few cases where knowing its existence can be useful:
The existence of ContinuouslyChanging nodes is generally not necessary knowledge to excel at ProtoFlux (as a [[Core Concepts|Core Concept]]). However, there are a few cases where knowing its existence can be useful:
</translate>
</translate>


* <translate>Node groups that are not marked with ContinuousChanges can be forced into such by using a [[ProtoFlux:Continuously Changing Relay|Continuously Changing Relay]] node. This is only useful in niche cases where the output of a non-ContinuouslyChanging node can be changed irrespective of its inputs, such as a [[ProtoFlux:Find Child By Name|Find Child By Name]] node, or if the node exists outside of the data model, such as a [[ProtoFlux:Store|Store]] node.</translate>
* <translate><!--T:9--> Node groups that are not marked with ContinuousChanges can be forced into such by using a [[ProtoFlux:Continuously Changing Relay|Continuously Changing Relay]] node. This is only useful in niche cases where the output of a non-ContinuouslyChanging node can be changed irrespective of its inputs, such as a [[ProtoFlux:Find Child By Name|Find Child By Name]] node, or if the node exists outside of the data model, such as a [[ProtoFlux:Store|Store]] node.</translate>
* <translate>Because a single ContinuouslyChanging node forces the entire node group to evaluate every frame, it can cause innocent-looking code to cause major performance loss in certain contexts.</translate>
* <translate><!--T:10--> Because a single ContinuouslyChanging node forces the entire node group to evaluate every frame, it can cause innocent-looking code to cause major performance loss in certain contexts.</translate>
** <translate>One nasty example might be a large [[ProtoFlux:Find Child By Name|Find Child By Name]] being combined into a [[ProtoFlux:Get Forward|Get Forward]] node. Because Get Forward is marked as ContinuouslyChanging, it will force the Find Child By Name to evaluate every update, which can exceptionally hurt framerate. A way to avoid this frame loss would be writing the result of the Find Child By Name into a [[ProtoFlux:Data Model Store|Data Model Store]] whenever necessary.</translate>
** <translate><!--T:11--> One nasty example might be a large [[ProtoFlux:Find Child By Name|Find Child By Name]] being combined into a [[ProtoFlux:Get Forward|Get Forward]] node. Because Get Forward is marked as ContinuouslyChanging, it will force the Find Child By Name to evaluate every update, which can exceptionally hurt framerate. A way to avoid this frame loss would be writing the result of the Find Child By Name into a [[ProtoFlux:Data Model Store|Data Model Store]] whenever necessary.</translate>


[[Category:Core concepts]]
[[Category:Core concepts]]

Revision as of 14:07, 23 April 2025

ContinuouslyChanging is an attribute applied to ProtoFlux nodes (or outputs to said node) that forces evaluation of any connected listener nodes every update.

Listener nodes are nodes that listen for changes of any kind in the node group it's connected to, updating their state when such changes are made. All listener nodes implement the IExecutionChangeListener interface, and a list of nodes can be found there.

Usually, listener nodes only evaluate the node chain every time they register a change propagated from an input. These changes are either captured from the Data Model's own change handler (such as when one writes to a SyncField) or by forcibly changing the nodes in the node group (such as by adding a new node). However, when any node in the node group connected to the listener is marked as ContinuouslyChanging, the listener will forcibly update all inputs every update.

Inspecting a ProtoFlux node in an inspector will provide more information on what nodes are being evaluated every update. Listener nodes will be marked with ContinuouslyChanging: True in the inspector to indicate that it is evaluating its input every update. If the Group that any given node is part of has ContinuousChanges set to True, then that node is being evaluated every update.

Not all listener nodes in a chain will be marked ContinuouslyChanging, even if the entire node group is being evaluated from another listener node. See the example to the right.

In this example, a Continuously Changing Relay is connected to one root slot, getting its name, and plugged into an Add node with a Find Child By Name. The string display is flagged as ContinuouslyChanging due to being a listener of a node with the ContinuouslyChanging attribute. Because of this, the Find Child By Name node is evaluated every frame, even if its output itself is not being plugged into its own ContinuouslyChanging node. Additionally, despite the node chain being evaluated every frame, the slot display will not be evaluated every frame, and is not marked ContinuouslyChanging

Practical Usage

The existence of ContinuouslyChanging nodes is generally not necessary knowledge to excel at ProtoFlux (as a Core Concept). However, there are a few cases where knowing its existence can be useful:

  • Node groups that are not marked with ContinuousChanges can be forced into such by using a Continuously Changing Relay node. This is only useful in niche cases where the output of a non-ContinuouslyChanging node can be changed irrespective of its inputs, such as a Find Child By Name node, or if the node exists outside of the data model, such as a Store node.
  • Because a single ContinuouslyChanging node forces the entire node group to evaluate every frame, it can cause innocent-looking code to cause major performance loss in certain contexts.
    • One nasty example might be a large Find Child By Name being combined into a Get Forward node. Because Get Forward is marked as ContinuouslyChanging, it will force the Find Child By Name to evaluate every update, which can exceptionally hurt framerate. A way to avoid this frame loss would be writing the result of the Find Child By Name into a Data Model Store whenever necessary.