Les Impulsions, aussi appelées appels, sont une action présente dans le ExecutionContext de ProtoFlux et l'une des deux types de chaînes à construire. En contraste des chaînes d'entrées, qui sont généralement continues, les impulsions poussent une tâche dans la chaîne d'impulsions, comme dans la programmation impérative.
Aperçu
Dans le contexte d'exécution Protoflux et ses dérivés, les nodes qui exécutent une action discrète demandent une impulsion pour s'exécuter. Par example, dupliquer un slot ne peut pas s'exécuter quand il veux car il serait impossible de le controller. Dans ce cas, une entrée spéciale *
de type Call (ou appel) est utilisée pour exécuter l'action. cette chaîne peut être continuée via la sortie Next
.
Quand une node d'action reçoit une impulsion, elle évalue toutes les nodes connectées en entrée. Cela contextualise les relations entre impulsions et autres chaînes de nodes: les impulsions poussent une exécution de tâche, les nodes d'action rassemblent leurs entrées, et ce jusqu'à ce que l'entrée originale puisse être évaluée.
Impulses are a local runtime by default within ProtoFlux. If interacting with the FrooxEngine data model in any fashion, however, the actions they perform get synced across users. This includes, but is not limited to, writing to a non-driven synced field, managing slots, and setting non-driven dynamic variables.
Impulses can come from a variety of sources. Most commonly, when building ProtoFlux, a Call Input can be created by dragging out an impulse input and pressing secondary. Impulses may also come from events, or impulse chains that start once receiving some sort of signal. These include, but are not limited to, dynamic impulses, button events, fire on events, and world/item events.
Context
Impulses are attached to a particular instance of an ExecutionContext. This is not to be confused with the general concept of contexts in ProtoFlux, as all impulses are from an ExecutionContext, but rather refers to the specific values and variables that the impulse sees.
Context is picked up by the trigger of the original impulse and carried until the chain completes. Contexts carry certain values with them throughout the duration of the chain, including local values and outputs to action nodes. Outside of the specific context (and nested contexts) that they are used, it is impossible to access the underlying value of one of these context-sensitive values.
Context is kept when passing through the same node group and lost if there is a disconnect of execution to a different node group. Node groups are the nodes that are all connected in some way or another, whether through direct wire connections or by references to another node, such as referencing a variable for a write node.
For example, if a dynamic impulse is pulsed, and that dynamic impulse pulses another one, and that third dynamic impulse writes to a local, the change will not be seen by the Next
path of the first dynamic impulse trigger. This is because the execution leaves the node group of the first trigger after the first dynamic impulse is pulsed, causing the second dynamic impulse to not be within the same context as the initial chain. If the second dynamic impulse wrote to the same local, then all the node groups are connected, and the change will be seen by the initial Next
path.
Impulse flow
Impulse flow dictates how the impulse will be executed in relation to the runtime of the engine. There are two types of impulse flows: non-async and async.
A non-async impulse chain will run entirely in one engine update, halting the engine for as long as it takes to complete. If the impulse does actions that are synced across users, only the difference between the initial state the end of the engine update is synced. For example, if one duplicates and removes a load of slots in one non-async impulse chain, no data will be synced over the network.
Async
When an action has the potential to take multiple engine updates to complete, an async impulse flow is required. Otherwise, the node chain will raise an exception and refuse to execute.
Async impulse flow is generally the same as normal impulse flow, though with the added flexibility of being able to suspend and resume certain chains of execution at will. In essence, it is ProtoFlux's way of being able to use coroutines within the language. One can either explicitly suspend execution with nodes such as Delay, or one can implicitly wait for an action to complete before resuming execution, such as using the Play One Shot And Wait node.
An async impulse flow is able to preserve locals and action node outputs across multiple engine updates, something not possible with normal impulse flow.
It is possible to start an async impulse chain from a normal impulse chain using the Start Async Task node. This node actually creates a branched ExecutionContext at OnTriggered
that is distinct from the context that triggered it. Every value used by the triggered ExecutionContext gets duplicated into the new context, but after that point, neither context is able to affect the other.
In contrast, all the other async nodes share the same context. For example, a local variable modified within the OnTriggered
chain of a Delay node will be reflected in the Next
chain of the same node, and vice versa if the node gets triggered twice in one context. This is what makes async impulse flow so powerful.
If processing a lot of data using ProtoFlux, it may be desirable to use async impulse flow and spread execution across multiple frames, as it will prevent a massive framerate hitch when executing at the cost of taking slightly longer.
See Also
- ProtoFlux:Local, ProtoFlux:Store, and ProtoFlux:Data Model Store for the three types of variables one can access in ProtoFlux.
- Category:ProtoFlux:Flow for nodes that can control how an impulse flows.