Facepunch.ActionJigs
0.1.40
dotnet add package Facepunch.ActionJigs --version 0.1.40
NuGet\Install-Package Facepunch.ActionJigs -Version 0.1.40
<PackageReference Include="Facepunch.ActionJigs" Version="0.1.40" />
paket add Facepunch.ActionJigs --version 0.1.40
#r "nuget: Facepunch.ActionJigs, 0.1.40"
// Install Facepunch.ActionJigs as a Cake Addin #addin nuget:?package=Facepunch.ActionJigs&version=0.1.40 // Install Facepunch.ActionJigs as a Cake Tool #tool nuget:?package=Facepunch.ActionJigs&version=0.1.40
Facepunch.ActionJigs
Runtime-composable async methods that can be converted to and from JSON.
Overview
An action jig is made out of nodes, links and variables. Nodes either perform actions or evaluate expressions, and links connect them together to shuttle values or signals around. Variables provide storage local to each invocation of the jig, and are used to capture values at specific points during invocation. Arbitrary user data can be stored on each element, which could be used by a visual editor. Validation is performed to find any errors or warnings, and any errors will mean a jig can't be invoked. Node definitions are stored in a node library, and each jig will belong to exactly one such library to supply its node definitions. Action jigs can be serialized to JSON, and Delegate types created using jigs can also be serialized directly.
Node
Nodes have a definition and a binding. Bindings specify which properties, inputs, and outputs a node has. Inputs and outputs may transmit values or signals. A node with signal inputs / outputs is an Action node, which is invoked when an input signal fires. Nodes without any signal inputs / outputs are Expression nodes, which are lazily evaluated when any of their output values are requested by an Action node.
Definition
A node definition describes what the node will do, and provides bindings based
on which property values and input types a node currently has. Each definition
will belong to exactly one node library, and has a unique name
in that library. There are built-in definitions for common nodes like
operators, getting / setting variables, and the event
node which acts as an
entry point.
Binding
Definitions provide bindings, which are specifically typed sets of properties,
inputs, and outputs. Depending on the definition, the binding of a node may
change as you connect inputs or assign properties. For example, the type of the
result
output of an op.add
addition node depends on the types of the
provided inputs.
Property
Properties are constant named values stored in a node, which control its
binding. For example: a var.set
node, which would set a variable when
invoked, has a property specifying which variable it will assign. Changing
that property will change the input value type of the node, to match the
variable type.
Input
A node input will either receive a signal or a value.
Input values can be provided by another node's output through a Link, or a constant value stored inside the input. Input signals can only be provided by an output signal from another node, and control when the receiving node executes.
If an input value accepts an array type, it may be linked to multiple outputs in a specific order to provide the individual items of an array. Otherwise, inputs link to at most one output.
Output
A node output will emit either a signal or a value.
Output signals may fire mutliple times per invocation of the node, for example
the body
output of the loop node control.foreach
will fire once per element
in the items
input value. If multiple input signals are connected to the same
output signal, the receiving nodes will act as independent concurrent tasks.
Output values of Action nodes may be provided by a specific output signal, and can only be used downstream of that output signal.
Output values of expression nodes are always available, and will be evaluated lazily when requested by an Action node.
Link
Links are the connections between an output and an input. An output signal can only connect to input signals, and an output value can only connect to input values. See input and output for more details.
Variable
Variables are provided as a way to capture values at specific points to be read later on.
Each variable has a specific name and type. They are referenced in var.set
and var.get
nodes, and must be set before they can be read. They are local
to each invocation of an action jig, so if multiple instances of the same jig
are running simultaneously they won't share variables.
Node Library
Creating a node library is required to use action jigs. These contain all the
node definitions available when building a jig. An ITypeLoader
must be
provided to wrap any reflection, in case you want to restrict which types can
be used in a jig.
There are some built-in special node definitions that are provided by every
node library. For example, the event
entry point node, var.get
and
var.set
for using variables, and one for each operator like op.add
.
Custom Nodes
Custom nodes can be implemented as static C# methods. An
[ActionNode("ident")]
is used for action node methods, and
[ExpressionNode("ident")]
for expression node methods. Methods marked with
these attributes will be added to a library when calling
NodeLibrary.AddAssembly(asm)
. The parameters of the method will describe
the properties, inputs and outputs of the node.
Properties are defined with parameters marked with a [Property]
attribute.
Action node methods must return either void
or a Task
. Expression node
methods must return a non-Task
, and an output will be generated to emit the
return value. Output signals for action nodes are parameters with a delegate
type, and they will have corresponding output values based on the delegate
parameters. The method can invoke these delegate parameters to emit output
signals. If the delegates return Task
s, they will complete when all control
flow downstream of the emitted signal has finished.
All other parameters will become inputs for the node. An input with type
Input<T>
can be evaluated on demand by the method, allowing for input values
that change during the invocation of the method. All other input values will
be evaluated just before the method is invoked.
Generic methods are largely supported, and will produce a node that can change its binding as input or property types are modified.
User Data
Each main element of an action jig has a UserData
property, which can store
arbitary named values serialized as JSON nodes. This could be used to record
each node's position in a visual editor, for example.
Validation
Each time an action jig is modified, elements will be marked as needing
validation. This validation is performed either when attempting to invoke the
jig, or when accessing the Messages
property. This property will be
populated with a list of information, warnings and errors, each describing
the context and cause. Any error messages will mean the ActionJig can't be
invoked.
You can also access the messages specific to a particular node / link /
property / input / output / variable by using the element.GetMessages()
extension method. Accessing this will also cause validation to occur, if any
elements have changed since the last validation.
Invocation
After validation succeeds, an action jig can be invoked. Special event
nodes
act as the entry point during invocation, which can have named parameters that
provide output values on the event node. If an action jig is created to match
the signature of a particular delegate type, an event node is automatically
created with the right output values.
Invocation is asynchronous, and returns a Task that completes when all action nodes have finished acting. If the same action jig instance is invoked multiple times, the separate invocations act in parallel and have their own local variables.
Action jigs can also be converted to delegate instances, as long as they match that delegate's signature. Invoking the delegate will invoke the jig.
Serialization
To be able to serialize action jigs with System.Text.Json, a
JsonSerializerOptions
instance must have the AddActionJigConverters()
extension method called on it. After that it can convert ActionJig
,
ActionJig<T>
, and even delegate instances that are created from action
jigs.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net7.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
0.1.40 | 208 | 10/21/2023 | |
0.1.39 | 133 | 10/21/2023 | |
0.1.38 | 150 | 10/20/2023 | |
0.1.37 | 158 | 10/20/2023 | |
0.1.36 | 147 | 10/20/2023 | |
0.1.35 | 170 | 10/20/2023 | |
0.1.34 | 157 | 10/20/2023 | |
0.1.33 | 140 | 10/20/2023 | |
0.1.32 | 153 | 10/20/2023 | |
0.1.31 | 162 | 10/20/2023 | |
0.1.30 | 151 | 10/20/2023 | |
0.1.29 | 168 | 10/20/2023 | |
0.1.28 | 152 | 10/19/2023 | |
0.1.27 | 146 | 10/19/2023 | |
0.1.26 | 149 | 10/19/2023 | |
0.1.25 | 159 | 10/18/2023 | |
0.1.24 | 150 | 10/18/2023 | |
0.1.23 | 158 | 10/18/2023 | |
0.1.22 | 153 | 10/18/2023 | |
0.1.21 | 161 | 10/18/2023 | |
0.1.20 | 160 | 10/12/2023 | |
0.1.19 | 151 | 10/12/2023 | |
0.1.18 | 136 | 10/12/2023 | |
0.1.17 | 148 | 10/12/2023 | |
0.1.16 | 161 | 10/12/2023 | |
0.1.15 | 156 | 10/12/2023 | |
0.1.14 | 162 | 10/9/2023 | |
0.1.13 | 170 | 10/9/2023 | |
0.1.12 | 157 | 10/6/2023 | |
0.1.11 | 163 | 10/6/2023 | |
0.1.10 | 168 | 10/6/2023 | |
0.1.9 | 168 | 10/6/2023 | |
0.1.8 | 165 | 10/6/2023 | |
0.1.7 | 171 | 10/5/2023 | |
0.1.6 | 162 | 10/2/2023 | |
0.1.5 | 164 | 10/2/2023 | |
0.1.4 | 169 | 9/30/2023 | |
0.1.3 | 168 | 9/29/2023 | |
0.1.2 | 146 | 9/29/2023 | |
0.1.1 | 144 | 9/26/2023 | |
0.1.0 | 172 | 9/25/2023 | |
0.0.2 | 146 | 9/19/2023 |