diff --git a/docs/README.md b/docs/README.md index 5d0b0555..fc642285 100644 --- a/docs/README.md +++ b/docs/README.md @@ -42,21 +42,17 @@ Tutorials * [Complex projects?](./tutorial/complex-projects/) -### Contributed tutorials - -* [Découvrir et utiliser XOD](http://formations.open-elearning.fr/modules/electronique/xod/decouverte/) (French, by [@pepe](https://forum.xod.io/u/pepe/summary)) - -### Obsolete tutorials - -The articles which are going to be superseeded by the crash course above. - -1. [Nodes and Links](./tutorial/nodes-and-links/) -1. [Data Types and Conversions](./tutorial/data-types-and-conversions/) -1. [Patch Nodes](./tutorial/patch-nodes/) - User’s guide ------------ +### Concepts + +* [Program structure](./guide/program-structure/) +* [Data types](./guide/data-types/) +* [Linking rules](./guide/linking-rules/) +* [Execution model](./guide/execution-model/) +* [Variadic nodes](./guide/variadics/) + ### Making your own nodes * [Creating nodes for XOD in XOD](./guide/nodes-for-xod-in-xod/) @@ -65,18 +61,12 @@ User’s guide * [Creating nodes for XOD in C++](./guide/nodes-for-xod-in-cpp/) * [Dealing with state in C++](./guide/cpp-state/) * [Dealing with time in C++](./guide/cpp-time/) +* [Creating variadic patch nodes](./guide/creating-variadics/) ### Doing things sequentially * [Simple traffic light example](./guide/simple-traffic-light/) -### Concepts - -* [Program structure](./guide/program-structure/) -* [Data types](./guide/data-types/) -* [Linking rules](./guide/linking-rules/) -* [Execution model](./guide/execution-model/) - ### Projects and libraries * [Working on projects](./guide/projects/) diff --git a/docs/guide/README.md b/docs/guide/README.md index 9dbc4d4d..dc37bc9f 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -5,6 +5,14 @@ title: User’s Guide User’s Guide ============ +## Concepts + +* [Program structure](./program-structure/) +* [Data types](./data-types/) +* [Linking rules](./linking-rules/) +* [Execution model](./execution-model/) +* [Variadic nodes](./variadics/) + ## Making your own nodes * [Creating nodes for XOD in XOD](./nodes-for-xod-in-xod/) @@ -13,18 +21,12 @@ User’s Guide * [Creating nodes for XOD in C++](./nodes-for-xod-in-cpp/) * [Dealing with state in C++](./cpp-state/) * [Dealing with time in C++](./cpp-time/) +* [Creating variadic patch nodes](./creating-variadics/) ## Doing things sequentially * [Simple traffic light example](./simple-traffic-light/) -## Concepts - -* [Program structure](./program-structure/) -* [Data types](./data-types/) -* [Linking rules](./linking-rules/) -* [Execution model](./execution-model/) - ### Projects and libraries * [Working on projects](./projects/) diff --git a/docs/guide/creating-variadics/README.md b/docs/guide/creating-variadics/README.md new file mode 100644 index 00000000..d50841c4 --- /dev/null +++ b/docs/guide/creating-variadics/README.md @@ -0,0 +1,84 @@ +--- +title: Creating Variadic Patch Nodes +--- + +# Creating Variadic Patch Nodes + +Declaring your patch node to be variadic allows its user to add or remove +similar input pins dynamically. For you, it is a way to avoid creating a list +of mechanical variations to support the various number of inputs like: + +* `foobar` +* `foobar-2` +* `foobar-3` +* … +* `foobar-8` + +Make sure you’re familiar with the [variadic nodes](../variadics/) concept +and understand how the expansion process works. + +## Markers + +To make your patch node variadic, you should place a special marker node on it. +Find the marker node under the `xod/patch-nodes` library. You need +`variadic-1`, `variadic-2`, or `variadic-3`. The number defines the arity step, +that is the group size by which the rightmost input pins replicate. + +The `variadic-*` node itself does nothing and is stripped out during +compilation. It exists solely to define indefinite arity support. + +## Pin assignments + +Whenever you place a variadic node marker, the input pins get roles depending +on their position relative to each other. Consider a patch node draft with a +`variadic-2` marker: + +![Pin assignments](./assignments.patch.png) + +To make the expansion XOD split pins of a variadic patch node into three +groups. + +**Variadic pins** (aka value pins). The rightmost pins get this role. Their +number equals to the arity step. In the example above they are `V1` and +`V2`. Values for the inputs on each level are provided by a node user. + +**Accumulator pins**. Pins in the middle get this role. Their number equals the +output number. In the example they are `A1`, `A2`, and `A3`. The user provides +values only for the top level of the cascade; all other levels get accumulator +values straightly from output pins of the respective upstream node. + +**Shared pins**. The leftmost pins which are not variadic nor accumulator get +this role. In the example they are `S1` and `S2`. The values are provided by +the user, and they are delivered to each level in the cascade as is. In many +cases there will be no shared pins. + +Finally, consider a string join node example. We want a node which takes an +arbitrary number (two or more) of input strings and joins them together +inserting a delimiter between each. For example, it joins `"foo"`, `"bar"`, +`"baz"` with delimiter `"; "` into `"foo; bar; baz"`. The delimiter is shared +between all levels of expansion, so its input terminal goes left. We want the +arity to increment one by one, so we use the `variadic-1` marker. Finally, a +possible patch node implementation may look like this: + +![Join node implementation](./join.patch.png) + + +## Rules + +To let XOD properly expand your variadic node when transpiling you must satisfy +several natural restrictions: + +1. There should be no more than a single `variadic-*` marker. +2. A variadic patch node should have at least one output. +3. The total number of inputs should be equal or greater than the number of + outputs plus the arity step. +4. The types of accumulator inputs must strictly match the types of the outputs + even if an implicit cast is allowed in other cases. + +On the patch board, the variadic marker nodes either render usually or in red +color. The later case tells you’re breaking some rules. + +![Marker error](./marker-error.png) + +Hover the node to see the error. You have to resolve all issues or remove the +marker node to make the program compile successfully. diff --git a/docs/guide/creating-variadics/assignments.patch.png b/docs/guide/creating-variadics/assignments.patch.png new file mode 100644 index 00000000..e9a4e8d4 Binary files /dev/null and b/docs/guide/creating-variadics/assignments.patch.png differ diff --git a/docs/guide/creating-variadics/join.patch.png b/docs/guide/creating-variadics/join.patch.png new file mode 100644 index 00000000..b14bdeef Binary files /dev/null and b/docs/guide/creating-variadics/join.patch.png differ diff --git a/docs/guide/creating-variadics/marker-error.png b/docs/guide/creating-variadics/marker-error.png new file mode 100644 index 00000000..35addff6 Binary files /dev/null and b/docs/guide/creating-variadics/marker-error.png differ diff --git a/docs/guide/creating-variadics/samples.xodball b/docs/guide/creating-variadics/samples.xodball new file mode 100644 index 00000000..7dd0cbdd --- /dev/null +++ b/docs/guide/creating-variadics/samples.xodball @@ -0,0 +1,122 @@ +{ + "name": "", + "patches": { + "@/pin-assignments": { + "nodes": { + "BJWCx5LOf": { + "id": "BJWCx5LOf", + "label": "V1", + "position": { + "x": 68, + "y": -306 + }, + "type": "xod/patch-nodes/input-number" + }, + "Bk_ie9U_G": { + "id": "Bk_ie9U_G", + "label": "S2", + "position": { + "x": -102, + "y": -306 + }, + "type": "xod/patch-nodes/input-boolean" + }, + "HJmbW9Udz": { + "id": "HJmbW9Udz", + "position": { + "x": 34, + "y": -102 + }, + "type": "xod/patch-nodes/output-number" + }, + "HkKneq8Oz": { + "id": "HkKneq8Oz", + "label": "A1", + "position": { + "x": -68, + "y": -306 + }, + "type": "xod/patch-nodes/input-string" + }, + "Hy4TgcIdz": { + "id": "Hy4TgcIdz", + "label": "V2", + "position": { + "x": 102, + "y": -306 + }, + "type": "xod/patch-nodes/input-pulse" + }, + "HyTTlqUOz": { + "id": "HyTTlqUOz", + "label": "A4", + "position": { + "x": 34, + "y": -306 + }, + "type": "xod/patch-nodes/input-number" + }, + "S1rl-5Iuz": { + "id": "S1rl-5Iuz", + "position": { + "x": 0, + "y": -102 + }, + "type": "xod/patch-nodes/output-boolean" + }, + "SkgjecUOf": { + "id": "SkgjecUOf", + "label": "S1", + "position": { + "x": -136, + "y": -306 + }, + "type": "xod/patch-nodes/input-number" + }, + "SyR2g5LdG": { + "id": "SyR2g5LdG", + "label": "A2", + "position": { + "x": -34, + "y": -306 + }, + "type": "xod/patch-nodes/input-string" + }, + "SySAe9LuM": { + "id": "SySAe9LuM", + "label": "A3", + "position": { + "x": 0, + "y": -306 + }, + "type": "xod/patch-nodes/input-boolean" + }, + "r1n0lq8Oz": { + "id": "r1n0lq8Oz", + "position": { + "x": -68, + "y": -102 + }, + "type": "xod/patch-nodes/output-string" + }, + "ryCCx9IuG": { + "id": "ryCCx9IuG", + "position": { + "x": -34, + "y": -102 + }, + "type": "xod/patch-nodes/output-string" + }, + "rydW-cIOf": { + "id": "rydW-cIOf", + "position": { + "x": 204, + "y": -204 + }, + "type": "xod/patch-nodes/variadic-2" + } + }, + "path": "@/pin-assignments" + } + } +} diff --git a/docs/guide/variadics/README.md b/docs/guide/variadics/README.md new file mode 100644 index 00000000..e5a9df54 --- /dev/null +++ b/docs/guide/variadics/README.md @@ -0,0 +1,90 @@ +--- +title: Variadic Nodes +--- + +# Variadic Nodes + +There are operations which can be applied to an arbitrary number of input +values. For example, consider the addition operation. Sure, intuitively you +know how it works for two values, three values, or 42 values: + +* 1 + 6 = 7 +* 1 + 6 + 3 = 10 +* 1 + 6 + 3 + …more summands… = someNumber + +Other examples of such functions include number multiplication, string +concatenation or joining, booleans AND’ing or OR’ing, n-th element choice, and +so on. + +To natively support such operations, XOD offers a mechanism called *variadic* +nodes. The variadic nodes can scale the number of their input pins to accept +more or fewer values. + +In XOD IDE the variadic nodes have a little gripper on the right, and the pins +which can scale are marked with the ellipsis (⋯) on mouse hover. Drag the right +border of the node to add as many groups of variadic pins as you need. + +![Overview](./overview.patch.png) + +The variadic pins replication count is called *arity level*. By default, the +arity level for a node is 1. When you add a pin to, for example, the `multiply` +node, the arity level becomes 2, etc. + +## Expansion + +A variadic node developer is responsible only for creating a node +implementation for the first arity level. All subsequent arity level +implementations are induced automatically by XOD. To achieve it, when +transpiling the program each particular variadic node passes an *expansion* +stage in which the system replaces it with a cascade of primitive level-1 +nodes. The replacement principle is better illustrated with an example. + +![Expansion](./expansion.patch.png) + +
+Pro +Developers with functional programming experience could note the expansion is +nothing more but a reduce/fold operation. Indeed! XOD variadics work through +input value list folding. +
+ +## Bigger arity steps + +In the examples above the nodes have exactly one variadic pin. It is not always +the case. Nodes may have two or three variadic pins. An example of such node is +[`select`](/libs/xod/core/select/) which have two. Every time you increment an +arity level of the `select` node it gets two additional input pins. + +![Select node with arity step 2](./select-a2.patch.png) + +Formally speaking, the number of variadic input pins which replicate together +in a group is called *arity step*. + +Expansion process for the nodes with an arity step greater than one looks +similar. + +![Select node expansion](./select-a2-expansion.patch.png) + +## Shared pins + +When a variadic node has more inputs than necessary to expand it, the leftmost +extraneous pins are shared between all nodes in the cascade. + +For example, consider textual string join operation which concatenates input +strings placing a specified delimiter between them (e.g., space or comma). The +delimiter will be shared between all expanded nodes, so you’ll get the result +you expect. + +![Join node expansion](./join-expansion.patch.png) + +In the example above there was a single shared pin. However, there can be more +if the author decided the node to be so. + +--- + +As a node user, you’ll rarely meditate on which pins are shared, and which are +not. The usage pattern should be pretty apparent from the node designation. + +Arranging pins properly is a puzzle for the node creator. Read about all rules +and nuances if you want to [create a new variadic +node](../creating-variadics/) by yourself. diff --git a/docs/guide/variadics/expansion.patch.png b/docs/guide/variadics/expansion.patch.png new file mode 100644 index 00000000..8ad6cd36 Binary files /dev/null and b/docs/guide/variadics/expansion.patch.png differ diff --git a/docs/guide/variadics/join-expansion.patch.png b/docs/guide/variadics/join-expansion.patch.png new file mode 100644 index 00000000..9830c70e Binary files /dev/null and b/docs/guide/variadics/join-expansion.patch.png differ diff --git a/docs/guide/variadics/overview.patch.png b/docs/guide/variadics/overview.patch.png new file mode 100644 index 00000000..fcb947e0 Binary files /dev/null and b/docs/guide/variadics/overview.patch.png differ diff --git a/docs/guide/variadics/samples.xodball b/docs/guide/variadics/samples.xodball new file mode 100644 index 00000000..11b01e3d --- /dev/null +++ b/docs/guide/variadics/samples.xodball @@ -0,0 +1,874 @@ +{ + "name": "", + "patches": { + "@/01-overview": { + "comments": { + "Byl9xSNdM": { + "content": "As many pins as necessary", + "id": "Byl9xSNdM", + "position": { + "x": 68, + "y": -204 + }, + "size": { + "height": 51, + "width": 136 + } + }, + "HkJ3lrVuf": { + "content": "Works for any data types", + "id": "HkJ3lrVuf", + "position": { + "x": 68, + "y": 102 + }, + "size": { + "height": 51, + "width": 238 + } + }, + "r1XKgBN_f": { + "content": "The same `add` node\n🔻🔻🔻", + "id": "r1XKgBN_f", + "position": { + "x": -374, + "y": -204 + }, + "size": { + "height": 51, + "width": 170 + } + } + }, + "nodes": { + "B1HIeBNdf": { + "arityLevel": 4, + "id": "B1HIeBNdf", + "position": { + "x": -374, + "y": 204 + }, + "type": "xod/core/add" + }, + "B1TMgSEuf": { + "arityLevel": 3, + "id": "B1TMgSEuf", + "position": { + "x": -374, + "y": 102 + }, + "type": "xod/core/add" + }, + "BkUGlS4Of": { + "arityLevel": 9, + "id": "BkUGlS4Of", + "position": { + "x": -34, + "y": -102 + }, + "type": "xod/core/multiply" + }, + "ByC31SNuM": { + "id": "ByC31SNuM", + "position": { + "x": -374, + "y": -102 + }, + "type": "xod/core/add" + }, + "H1j9fBEdz": { + "id": "H1j9fBEdz", + "position": { + "x": -34, + "y": 102 + }, + "type": "xod/core/or" + }, + "r1BggH4uf": { + "arityLevel": 2, + "id": "r1BggH4uf", + "position": { + "x": -374, + "y": 0 + }, + "type": "xod/core/add" + }, + "rJmjfrVuf": { + "arityLevel": 9, + "id": "rJmjfrVuf", + "position": { + "x": -34, + "y": 204 + }, + "type": "xod/core/or" + }, + "ry3ZgB4uG": { + "id": "ry3ZgB4uG", + "position": { + "x": -34, + "y": -204 + }, + "type": "xod/core/multiply" + } + }, + "path": "@/01-overview" + }, + "@/02-expansion": { + "links": { + "B1l-7SNdz": { + "id": "B1l-7SNdz", + "input": { + "nodeId": "S16J7BNuz", + "pinKey": "HkqmLAOrD1W" + }, + "output": { + "nodeId": "SkaxXrVdM", + "pinKey": "__out__" + } + }, + "B1qemrVdM": { + "id": "B1qemrVdM", + "input": { + "nodeId": "rk8ymBEuf", + "pinKey": "BJnQUR_BwyZ" + }, + "output": { + "nodeId": "B1_l7rEuM", + "pinKey": "__out__" + } + }, + "BykWmBV_G": { + "id": "BykWmBV_G", + "input": { + "nodeId": "SJke7rV_G", + "pinKey": "HkqmLAOrD1W" + }, + "output": { + "nodeId": "SkeTl7HVuG", + "pinKey": "__out__" + } + }, + "H14xmBV_G": { + "id": "H14xmBV_G", + "input": { + "nodeId": "S16J7BNuz", + "pinKey": "BJnQUR_BwyZ" + }, + "output": { + "nodeId": "B1tkXBNdG", + "pinKey": "SyomIRurDJ-" + } + }, + "HJmZQHNdM": { + "id": "HJmZQHNdM", + "input": { + "nodeId": "rk8ymBEuf", + "pinKey": "HkqmLAOrD1W" + }, + "output": { + "nodeId": "SynxmSVdG", + "pinKey": "__out__" + } + }, + "HyzZQH4dz": { + "id": "HyzZQH4dz", + "input": { + "nodeId": "B1tkXBNdG", + "pinKey": "HkqmLAOrD1W" + }, + "output": { + "nodeId": "H1e2gXBEuM", + "pinKey": "__out__" + } + }, + "SyMl7HNuM": { + "id": "SyMl7HNuM", + "input": { + "nodeId": "B1tkXBNdG", + "pinKey": "BJnQUR_BwyZ" + }, + "output": { + "nodeId": "rk8ymBEuf", + "pinKey": "SyomIRurDJ-" + } + }, + "SyYZQBEOz": { + "id": "SyYZQBEOz", + "input": { + "nodeId": "Byv-7BNuG", + "pinKey": "__in__" + }, + "output": { + "nodeId": "SJke7rV_G", + "pinKey": "SyomIRurDJ-" + } + }, + "rkHemHVuM": { + "id": "rkHemHVuM", + "input": { + "nodeId": "SJke7rV_G", + "pinKey": "BJnQUR_BwyZ" + }, + "output": { + "nodeId": "S16J7BNuz", + "pinKey": "SyomIRurDJ-" + } + } + }, + "nodes": { + "B1_l7rEuM": { + "id": "B1_l7rEuM", + "position": { + "x": 34, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "B1tkXBNdG": { + "id": "B1tkXBNdG", + "position": { + "x": 68, + "y": 204 + }, + "type": "xod/core/add" + }, + "Byv-7BNuG": { + "id": "Byv-7BNuG", + "position": { + "x": 136, + "y": 510 + }, + "type": "xod/patch-nodes/output-number" + }, + "H1e2gXBEuM": { + "id": "H1e2gXBEuM", + "position": { + "x": 102, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "S16J7BNuz": { + "id": "S16J7BNuz", + "position": { + "x": 102, + "y": 306 + }, + "type": "xod/core/add" + }, + "SJke7rV_G": { + "id": "SJke7rV_G", + "position": { + "x": 136, + "y": 408 + }, + "type": "xod/core/add" + }, + "SkaxXrVdM": { + "id": "SkaxXrVdM", + "position": { + "x": 136, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "SkeTl7HVuG": { + "id": "SkeTl7HVuG", + "position": { + "x": 170, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "SynxmSVdG": { + "id": "SynxmSVdG", + "position": { + "x": 68, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "rk8ymBEuf": { + "id": "rk8ymBEuf", + "position": { + "x": 34, + "y": 102 + }, + "type": "xod/core/add" + } + }, + "path": "@/02-expansion" + }, + "@/03-select-a2": { + "comments": { + "SJeRmH4uz": { + "content": "`select` inputs grow in pairs", + "id": "SJeRmH4uz", + "position": { + "x": 204, + "y": 102 + }, + "size": { + "height": 51, + "width": 238 + } + } + }, + "nodes": { + "B1Y3mBNOM": { + "id": "B1Y3mBNOM", + "position": { + "x": 34, + "y": 102 + }, + "type": "xod/core/select" + }, + "S1Bp7B4uG": { + "arityLevel": 4, + "id": "S1Bp7B4uG", + "position": { + "x": 34, + "y": 408 + }, + "type": "xod/core/select" + }, + "SJ3nQHEdG": { + "arityLevel": 2, + "id": "SJ3nQHEdG", + "position": { + "x": 34, + "y": 204 + }, + "type": "xod/core/select" + }, + "r1eTXH4_M": { + "arityLevel": 3, + "id": "r1eTXH4_M", + "position": { + "x": 34, + "y": 306 + }, + "type": "xod/core/select" + } + }, + "path": "@/03-select-a2" + }, + "@/04-expansion-a2": { + "links": { + "B14MzSNOf": { + "id": "B14MzSNOf", + "input": { + "nodeId": "r1Y-MSEOG", + "pinKey": "S10qrR6UZ" + }, + "output": { + "nodeId": "ryIbfHEdM", + "pinKey": "S1yaHC6UW" + } + }, + "BkHGzSNOf": { + "id": "BkHGzSNOf", + "input": { + "nodeId": "r1Y-MSEOG", + "pinKey": "rkmiHCaIZ" + }, + "output": { + "nodeId": "ryIbfHEdM", + "pinKey": "rkWHDAW_f" + } + }, + "BkPSfSVdM": { + "id": "BkPSfSVdM", + "input": { + "nodeId": "SJWZzHVuf", + "pinKey": "rJUjrCTUb" + }, + "output": { + "nodeId": "HJlTQfHVOz", + "pinKey": "__out__" + } + }, + "BkQMGH4uG": { + "id": "BkQMGH4uG", + "input": { + "nodeId": "ryIbfHEdM", + "pinKey": "rkmiHCaIZ" + }, + "output": { + "nodeId": "SJWZzHVuf", + "pinKey": "rkWHDAW_f" + } + }, + "ByArzB4uf": { + "id": "ByArzB4uf", + "input": { + "nodeId": "r1Y-MSEOG", + "pinKey": "rygjH06LW" + }, + "output": { + "nodeId": "BygNfHNuz", + "pinKey": "__out__" + } + }, + "H1iHfHEdz": { + "id": "H1iHfHEdz", + "input": { + "nodeId": "ryIbfHEdM", + "pinKey": "rygjH06LW" + }, + "output": { + "nodeId": "BJJ4zSVdG", + "pinKey": "__out__" + } + }, + "HJHSMSNOG": { + "id": "HJHSMSNOG", + "input": { + "nodeId": "SJWZzHVuf", + "pinKey": "rygjH06LW" + }, + "output": { + "nodeId": "rkaQfrEuG", + "pinKey": "__out__" + } + }, + "HJKrfBEuf": { + "id": "HJKrfBEuf", + "input": { + "nodeId": "SJWZzHVuf", + "pinKey": "rkmiHCaIZ" + }, + "output": { + "nodeId": "BJH7fSNdf", + "pinKey": "__out__" + } + }, + "HkdHMH4Of": { + "id": "HkdHMH4Of", + "input": { + "nodeId": "SJWZzHVuf", + "pinKey": "S10qrR6UZ" + }, + "output": { + "nodeId": "SyazMr4uM", + "pinKey": "__out__" + } + }, + "HycIGSNOG": { + "id": "HycIGSNOG", + "input": { + "nodeId": "Hy_LMSEOf", + "pinKey": "__in__" + }, + "output": { + "nodeId": "r1Y-MSEOG", + "pinKey": "S1yaHC6UW" + } + }, + "SJezzBN_f": { + "id": "SJezzBN_f", + "input": { + "nodeId": "ryIbfHEdM", + "pinKey": "S10qrR6UZ" + }, + "output": { + "nodeId": "SJWZzHVuf", + "pinKey": "S1yaHC6UW" + } + }, + "SyhSGB4_f": { + "id": "SyhSGB4_f", + "input": { + "nodeId": "ryIbfHEdM", + "pinKey": "rJUjrCTUb" + }, + "output": { + "nodeId": "rklkNMHN_M", + "pinKey": "__out__" + } + }, + "rJyvfB4dM": { + "id": "rJyvfB4dM", + "input": { + "nodeId": "rk6IMrEdf", + "pinKey": "__in__" + }, + "output": { + "nodeId": "r1Y-MSEOG", + "pinKey": "rkWHDAW_f" + } + }, + "rklLzrEdM": { + "id": "rklLzrEdM", + "input": { + "nodeId": "r1Y-MSEOG", + "pinKey": "rJUjrCTUb" + }, + "output": { + "nodeId": "SyexEMrV_f", + "pinKey": "__out__" + } + } + }, + "nodes": { + "BJH7fSNdf": { + "id": "BJH7fSNdf", + "label": "S1", + "position": { + "x": 68, + "y": 0 + }, + "type": "xod/patch-nodes/input-pulse" + }, + "BJJ4zSVdG": { + "id": "BJJ4zSVdG", + "label": "X3", + "position": { + "x": 170, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "BygNfHNuz": { + "id": "BygNfHNuz", + "label": "X4", + "position": { + "x": 238, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "HJlTQfHVOz": { + "id": "HJlTQfHVOz", + "label": "S2", + "position": { + "x": 136, + "y": 0 + }, + "type": "xod/patch-nodes/input-pulse" + }, + "Hy_LMSEOf": { + "id": "Hy_LMSEOf", + "position": { + "x": 170, + "y": 408 + }, + "type": "xod/patch-nodes/output-number" + }, + "SJWZzHVuf": { + "id": "SJWZzHVuf", + "position": { + "x": 34, + "y": 102 + }, + "type": "xod/core/select" + }, + "SyazMr4uM": { + "id": "SyazMr4uM", + "label": "X1", + "position": { + "x": 34, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "SyexEMrV_f": { + "id": "SyexEMrV_f", + "label": "S4", + "position": { + "x": 272, + "y": 0 + }, + "type": "xod/patch-nodes/input-pulse" + }, + "r1Y-MSEOG": { + "id": "r1Y-MSEOG", + "position": { + "x": 170, + "y": 306 + }, + "type": "xod/core/select" + }, + "rk6IMrEdf": { + "id": "rk6IMrEdf", + "position": { + "x": 204, + "y": 408 + }, + "type": "xod/patch-nodes/output-pulse" + }, + "rkaQfrEuG": { + "id": "rkaQfrEuG", + "label": "X2", + "position": { + "x": 102, + "y": 0 + }, + "type": "xod/patch-nodes/input-number" + }, + "rklkNMHN_M": { + "id": "rklkNMHN_M", + "label": "S3", + "position": { + "x": 204, + "y": 0 + }, + "type": "xod/patch-nodes/input-pulse" + }, + "ryIbfHEdM": { + "id": "ryIbfHEdM", + "position": { + "x": 102, + "y": 204 + }, + "type": "xod/core/select" + } + }, + "path": "@/04-expansion-a2" + }, + "@/05-join-expansion": { + "links": { + "B18ShHE_M": { + "id": "B18ShHE_M", + "input": { + "nodeId": "HkyX2r4_M", + "pinKey": "rJJHNrVuM" + }, + "output": { + "nodeId": "rJeonVHV_f", + "pinKey": "__out__" + } + }, + "BkVrnBN_z": { + "id": "BkVrnBN_z", + "input": { + "nodeId": "By9G2BNdf", + "pinKey": "rJJHNrVuM" + }, + "output": { + "nodeId": "rJonESV_M", + "pinKey": "__out__" + } + }, + "H1sN3rN_f": { + "id": "H1sN3rN_f", + "input": { + "nodeId": "rkMXnBNuf", + "pinKey": "rJGQNB4df" + }, + "output": { + "nodeId": "rywcVS4_f", + "pinKey": "__out__" + } + }, + "HJYEhBVOG": { + "id": "HJYEhBVOG", + "input": { + "nodeId": "HkyX2r4_M", + "pinKey": "rJGQNB4df" + }, + "output": { + "nodeId": "rywcVS4_f", + "pinKey": "__out__" + } + }, + "HygS2H4_z": { + "id": "HygS2H4_z", + "input": { + "nodeId": "S17mnrE_G", + "pinKey": "HynENHNOz" + }, + "output": { + "nodeId": "rkMXnBNuf", + "pinKey": "HJrBNr4dG" + } + }, + "HyzS2rV_f": { + "id": "HyzS2rV_f", + "input": { + "nodeId": "BJrJHSEOf", + "pinKey": "__in__" + }, + "output": { + "nodeId": "S17mnrE_G", + "pinKey": "HJrBNr4dG" + } + }, + "S1hV2SNdz": { + "id": "S1hV2SNdz", + "input": { + "nodeId": "S17mnrE_G", + "pinKey": "rJGQNB4df" + }, + "output": { + "nodeId": "rywcVS4_f", + "pinKey": "__out__" + } + }, + "SktS2BEOG": { + "id": "SktS2BEOG", + "input": { + "nodeId": "rkMXnBNuf", + "pinKey": "rJJHNrVuM" + }, + "output": { + "nodeId": "SyanESVOf", + "pinKey": "__out__" + } + }, + "SkvE2HVOM": { + "id": "SkvE2HVOM", + "input": { + "nodeId": "By9G2BNdf", + "pinKey": "rJGQNB4df" + }, + "output": { + "nodeId": "rywcVS4_f", + "pinKey": "__out__" + } + }, + "Sy6ShBEOz": { + "id": "Sy6ShBEOz", + "input": { + "nodeId": "S17mnrE_G", + "pinKey": "rJJHNrVuM" + }, + "output": { + "nodeId": "rycC4SEdz", + "pinKey": "__out__" + } + }, + "rk7r3HEdf": { + "id": "rk7r3HEdf", + "input": { + "nodeId": "By9G2BNdf", + "pinKey": "HynENHNOz" + }, + "output": { + "nodeId": "Hk72NH4Of", + "pinKey": "__out__" + } + }, + "rkirnS4_M": { + "id": "rkirnS4_M", + "input": { + "nodeId": "rkMXnBNuf", + "pinKey": "HynENHNOz" + }, + "output": { + "nodeId": "HkyX2r4_M", + "pinKey": "HJrBNr4dG" + } + }, + "ryyB2rEOG": { + "id": "ryyB2rEOG", + "input": { + "nodeId": "HkyX2r4_M", + "pinKey": "HynENHNOz" + }, + "output": { + "nodeId": "By9G2BNdf", + "pinKey": "HJrBNr4dG" + } + } + }, + "nodes": { + "BJrJHSEOf": { + "id": "BJrJHSEOf", + "position": { + "x": 136, + "y": 510 + }, + "type": "xod/patch-nodes/output-string" + }, + "By9G2BNdf": { + "id": "By9G2BNdf", + "position": { + "x": 136, + "y": 102 + }, + "type": "xod/core/join" + }, + "Hk72NH4Of": { + "id": "Hk72NH4Of", + "label": "S1", + "position": { + "x": 170, + "y": 0 + }, + "type": "xod/patch-nodes/input-string" + }, + "HkyX2r4_M": { + "id": "HkyX2r4_M", + "position": { + "x": 136, + "y": 204 + }, + "type": "xod/core/join" + }, + "S17mnrE_G": { + "id": "S17mnrE_G", + "position": { + "x": 136, + "y": 408 + }, + "type": "xod/core/join" + }, + "SyanESVOf": { + "id": "SyanESVOf", + "label": "S4", + "position": { + "x": 374, + "y": 0 + }, + "type": "xod/patch-nodes/input-string" + }, + "rJeonVHV_f": { + "id": "rJeonVHV_f", + "label": "S3", + "position": { + "x": 306, + "y": 0 + }, + "type": "xod/patch-nodes/input-string" + }, + "rJonESV_M": { + "id": "rJonESV_M", + "label": "S2", + "position": { + "x": 238, + "y": 0 + }, + "type": "xod/patch-nodes/input-string" + }, + "rkMXnBNuf": { + "id": "rkMXnBNuf", + "position": { + "x": 136, + "y": 306 + }, + "type": "xod/core/join" + }, + "rycC4SEdz": { + "id": "rycC4SEdz", + "label": "S5", + "position": { + "x": 442, + "y": 0 + }, + "type": "xod/patch-nodes/input-string" + }, + "rywcVS4_f": { + "id": "rywcVS4_f", + "label": "D", + "position": { + "x": 0, + "y": 0 + }, + "type": "xod/patch-nodes/input-string" + } + }, + "path": "@/05-join-expansion" + } + } +} diff --git a/docs/guide/variadics/select-a2-expansion.patch.png b/docs/guide/variadics/select-a2-expansion.patch.png new file mode 100644 index 00000000..c2a9ab52 Binary files /dev/null and b/docs/guide/variadics/select-a2-expansion.patch.png differ diff --git a/docs/guide/variadics/select-a2.patch.png b/docs/guide/variadics/select-a2.patch.png new file mode 100644 index 00000000..4328f498 Binary files /dev/null and b/docs/guide/variadics/select-a2.patch.png differ diff --git a/docs/tutorial/README.md b/docs/tutorial/README.md index bdb29f88..33f678b4 100644 --- a/docs/tutorial/README.md +++ b/docs/tutorial/README.md @@ -38,15 +38,3 @@ Tutorials 28. [String concatenation](./28-string-concat/) * [Complex projects?](./complex-projects/) - -### Contributed tutorials - -* [Découvrir et utiliser XOD](http://formations.open-elearning.fr/modules/electronique/xod/decouverte/) (French, by [@pepe](https://forum.xod.io/u/pepe/summary)) - -### Obsolete tutorials - -The articles which are going to be superseeded by the crash course above. - -1. [Nodes and Links](./nodes-and-links/) -1. [Data Types and Conversions](./data-types-and-conversions/) -1. [Patch Nodes](./patch-nodes/)