Merge pull request #1101 from xodio/doc-1069-variadic-guides

Add variadic node guide articles
This commit is contained in:
Evgeny Kochetkov
2018-03-02 14:21:25 +03:00
committed by GitHub
15 changed files with 1188 additions and 38 deletions

View File

@@ -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/)
Users 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 @@ Users 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/)

View File

@@ -5,6 +5,14 @@ title: Users Guide
Users 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 @@ Users 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/)

View File

@@ -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 youre 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 youre 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -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"
}
}
}

View File

@@ -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 ANDing or ORing, 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)
<div class="ui segment note">
<span class="ui ribbon label">Pro</span>
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.
</div>
## 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 youll 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, youll 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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -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"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -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/)