Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

ProtoFlux:Write

Write writes it's input value to a variable or field when it receives an impulse
Write
*
OnWritten
Value
OnFail
Variable
null
∅
Actions

Writes take Variable (Variable) as an input, and the type that Variable wraps will determine what Value (Generic) will take as a value. The node will then write Value (Generic) to the field Variable (Variable) wraps.

To set the target variable, drag out a wire from a source onto the Variable field, as if connecting it. Alternatively, you can create one by grabbing the "Variable" label, opening the context menu, and choosing between Local, Store, or Data Model Store. This can save considerable time over trying to find the type you want in the node menu.

A write only evaluates when it receives a pulse.

Writes simply change a value (like dropping a number into an inspector field), unlike drives which block writes and each user takes exclusive control of their own value.

Writes are often used where drives would wastefully evaluate their input every update due to ContinuouslyChanging nodes. This is particularly noticeable when drives are connected to heavy nodes such as FindChildByName.

If a value in the world is written to, it will be eventually replicated across the network to other users as part of the data model state, unless that field is localized or it is not a data model field such as stores, locals or particular component fields.

Writes are typically only seen used with Sources, but some other nodes can be written to by dragging their output wire to the Variable field on the write node:

  • DataModelBooleanToggle uses a data model field on the node's slot, which can be written to by writing to it's boolean output connector.
  • The output connector of FieldAsVariable can be written to directly, this replaces the functionality of Indirect Write but uses less CPU time.
  • The output connector of GlobalToOutput can be written to, as a way of writing to that global.

Inputs

* (Call)

Call this to write the value.

Value (Generic)

Value to write to the value pointed to by Variable (Variable)

Outputs

OnWritten (Continuation)

sends an impulse after * (Call) has been impulsed and the value has been written.

OnFail (Continuation)

sends an impulse after * (Call) has been impulsed and the value wasn't able to be written due to a missing target or a missing Variable (Variable) value

Globals

Variable (Variable Generic)

The Variable to write to.

This is drag-and-drop compatible with the output wires of DataModelBooleanToggle, FieldAsVariable, and GlobalToOutput.

Examples

Optimizations

In cases where a drive may evaluate it's input value every update due to ContinuousChanges, a write can be used instead to write the value only when necessary by sending it an impulse. This is particularly noticeable when a drive is connected to a search node as searching can be a very heavy operation. However in cases where a value will be evaluated every frame no matter what, a drive is often faster simply by requiring less nodes.

The CPU time of Write is rarely significant (typically less than 100ns), but in cases where it's a large part of an extremely hot loop (for instance FFT output), there are some available optimizations.

  • Faster indirect write
    • Write can be used indirectly by writing to the output connector of a FieldAsVariable node. This is faster than Indirect Write.
  • Use Stores when a variable isn't used outside of protoflux
    • Writing to a typical component field or data model field incurs change tracking overhead on each impulse and network replication per update. For internal variables, Stores are the fastest variable aside from a Global. Note that Stores can lose their value or become zero if the node group is edited or >10s of lag causes the protoflux to abort. The value will become zero which can cause divide by zero or invalid output; if this will require filtering then there is likely no speed advantage to using a Store. A variable constructor can ensure this doesn't happen as long as it runs earlier in the update loop than the protoflux in question.
  • In situations where variables are interchangeable, Stores usually test the fastest with Locals being very slightly slower.
    • This is most likely because of change tracking overhead, because data model writes are almost as fast if the value isn't being changed. In benchmarks WriteToGlobal can seem like the fastest write operation if the writes don't change it's value. If the value is being changed (any real use case), then GlobalValue components still incur change tracking overhead as they must update their data model field.
  • End an impulse loop when the write target no longer exists
    • If the target field for the Write node is destroyed, impulses will come out of OnFailed instead of OnWritten. This can be used to end a loop or handle a destroyed object without having a check in the protoflux loop. However this may fail silently if the impulse was started before the object was destroyed, even for async contexts, subject to Github issue #7283.

See Also

ProtoFlux:FieldHook - A drive that can be switched on/off using impulses.