Skip to content

Commit 2b83afa

Browse files
committed
Convert single operator xrefs to ref-style links
1 parent 8b18a10 commit 2b83afa

File tree

8 files changed

+42
-22
lines changed

8 files changed

+42
-22
lines changed

articles/editor.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ The most useful action to learn your way around the `Workflow` panel is right-cl
4848
If only one node is selected, the `Output` menu item will display the type of the elements emitted by that operator sequence.
4949

5050
> [!Tip]
51-
> If the output of an operator is a complex type, you can inspect its public data members. Clicking on any of the sub-items will automatically place a new [`MemberSelector`](xref:Bonsai.Expressions.MemberSelectorBuilder) operator to pick the specified data member from the output of the node.
51+
> If the output of an operator is a complex type, you can inspect its public data members. Clicking on any of the sub-items will automatically place a new [`MemberSelector`] operator to pick the specified data member from the output of the node.
5252
5353
The context menu also allows you to externalize public properties of the operator as explicit nodes in the workflow using the `Externalize Property` drop-down menu. Once a property is externalized, you can connect other nodes in the workflow to it so you can change the value of the property dynamically (see the [Property Mapping](xref:property-mapping) section for more information).
5454

@@ -137,7 +137,7 @@ The `Explorer` panel also supports workflow navigation by providing a hierarchic
137137

138138
![Editor Properties Panel](../images/editor-properties.png){width=300}
139139

140-
Each operator exposes a set of configuration properties that parameterize the operator's behaviour (e.g., the [`Timer`](xref:Bonsai.Reactive.Timer) operator exposes the period between generated values, whereas an image [`Threshold`](xref:Bonsai.Vision.Threshold) exposes the brightness cutoff value applied to individual pixels).
140+
Each operator exposes a set of configuration properties that parameterize the operator's behaviour (e.g., the [`Timer`] operator exposes the period between generated values, whereas an image [`Threshold`] exposes the brightness cutoff value applied to individual pixels).
141141

142142
The `Properties` panel will display all the configuration properties which are available for the currently selected operator. A summary description of the currently selected property can be found in the textbox at the bottom of the panel. Similarly, a description of the behaviour of the currently selected operator itself is shown at the top of the panel.
143143

@@ -215,3 +215,10 @@ Below is a summary of the most used actions and shortcuts in the workflow editor
215215
| Open context menu | <kbd>Shift</kbd>+<kbd>F10</kbd> |
216216
| View help | <kbd>F1</kbd> |
217217
| Go to definition | <kbd>F12</kbd> |
218+
219+
<!-- Reference-style links -->
220+
[`GroupWorkflow`]: xref:Bonsai.Expressions.GroupWorkflowBuilder
221+
[`IncludeWorkflow`]: xref:Bonsai.Expressions.IncludeWorkflowBuilder
222+
[`MemberSelector`]: xref:Bonsai.Expressions.MemberSelectorBuilder
223+
[`Threshold`]: xref:Bonsai.Vision.Threshold
224+
[`Timer`]: xref:Bonsai.Reactive.Timer

articles/higher-order.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,6 @@ This behaviour is described by the following marble diagram:
6161

6262
<!-- Reference-style links -->
6363
[`Concat`]: xref:Bonsai.Reactive.Concat
64+
[`CreateObservable`]: xref:Bonsai.Reactive.CreateObservable
6465
[`EnumerateFiles`]: xref:Bonsai.IO.EnumerateFiles
65-
[`FileCapture`]: xref:Bonsai.Vision.FileCapture
66-
[`CreateObservable`]: xref:Bonsai.Reactive.CreateObservable
66+
[`FileCapture`]: xref:Bonsai.Vision.FileCapture

articles/observables.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ In reactive programming, we compose operations on sequences (generation, filteri
2626

2727
Arrows entering the box indicate that the operator is receiving notifications from the observable sequence that it is subscribed to. Arrows leaving the box show items that are emitted by the operator itself. If no `subscribe` arrow is explicitly indicated in the diagram, it is assumed to be placed at the start of the source sequence.
2828

29-
In this case we can see from the diagram that the [`Condition`](xref:Bonsai.Reactive.Condition) operator is filtering the input notifications from the source sequence: only notifications with a specific shape are sent out in the result sequence.
29+
In this case we can see from the diagram that the [`Condition`] operator is filtering the input notifications from the source sequence: only notifications with a specific shape are sent out in the result sequence.
3030

3131
## Bonsai Workflows
3232

@@ -67,7 +67,7 @@ A video file also generates a sequence of images, but in contrast to the camera,
6767

6868
Understanding the *temperature* of an observable sequence is particularly important when that sequence is shared between multiple operators. It can help to understand whether those operators will see the same data items, and what the effect of subscribing to the shared sequence at different times is going to be.
6969

70-
It is also possible to change the temperature of observable sequences using reactive operators. The [`Replay`](xref:Bonsai.Reactive.Replay) operator can be used to subscribe to the camera and start recording all incoming images. Every time a downstream observer subscribes to the result sequence, it will then replay all images on-demand, even if they subscribe late. The originally *hot* sequence has been turned into a *cold* observable by the replay behaviour.
70+
It is also possible to change the temperature of observable sequences using reactive operators. The [`Replay`] operator can be used to subscribe to the camera and start recording all incoming images. Every time a downstream observer subscribes to the result sequence, it will then replay all images on-demand, even if they subscribe late. The originally *hot* sequence has been turned into a *cold* observable by the replay behaviour.
7171

7272
<img alt="Replay operator" src="~/images/reactive-replay.svg" style="max-height:250px;padding:1em 0" />
7373

@@ -78,6 +78,8 @@ Conversely, the [`Publish`](xref:Bonsai.Reactive.Publish) operator can be used t
7878
In the Bonsai visual language, whenever two operators receive data from the same source, i.e. whenever there are branches in the workflow, subscriptions use the `Publish` behaviour. This means that the default sharing behaviour of Bonsai sequences is *hot*. It is possible to change this by using specialized sharing operators, called [Subjects](xref:subjects).
7979

8080
<!-- Reference-style links -->
81-
[`Sample`]: xref:Bonsai.Reactive.Sample
81+
[`Condition`]: xref:Bonsai.Reactive.Condition
8282
[`Grayscale`]: xref:Bonsai.Vision.Grayscale
83-
[`KeyDown`]: xref:Bonsai.Windows.Input.KeyDown
83+
[`KeyDown`]: xref:Bonsai.Windows.Input.KeyDown
84+
[`Replay`]: xref:Bonsai.Reactive.Replay
85+
[`Sample`]: xref:Bonsai.Reactive.Sample

articles/property-mapping.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ Property mapping operators allow you to do exactly this. They are operators that
3434

3535
## Externalized properties
3636

37-
The [`ExternalizedMapping`](xref:Bonsai.Expressions.ExternalizedMappingBuilder) operator allows you to create externalized properties. The easiest way to initialize the mapping is from the right-click context menu when a single node is selected. Selecting a property from this menu will create or update the externalized mapping node. Multiple properties can be externalized from the same node.
37+
The [`ExternalizedMapping`] operator allows you to create externalized properties. The easiest way to initialize the mapping is from the right-click context menu when a single node is selected. Selecting a property from this menu will create or update the externalized mapping node. Multiple properties can be externalized from the same node.
3838

3939
![Externalized property](~/images/language-externalizedproperty.png)
4040

4141
[!include[ExternalizedMapping](~/articles/expressions-externalizedmapping.md)]
4242

4343
## Mapping a sequence to a property
4444

45-
After an operator property has been externalized, you can connect any sequence which is compatible with the data type of the property to the mapping node. When a connection to a source sequence is established, the externalized property will be promoted to a [`PropertyMapping`](xref:Bonsai.Expressions.PropertyMappingBuilder) operator.
45+
After an operator property has been externalized, you can connect any sequence which is compatible with the data type of the property to the mapping node. When a connection to a source sequence is established, the externalized property will be promoted to a [`PropertyMapping`] operator.
4646

4747
Now every time the source sequence emits a new notification, the mapping operator will react by changing the target property to the incoming value.
4848

@@ -60,9 +60,12 @@ Now every time the source sequence emits a new notification, the mapping operato
6060

6161
Sometimes you need to synchronize property updates with the data flow, i.e. you do not want the property mapping operator to change the property values outside of notifications emitted by the source sequence.
6262

63-
For example, imagine a transform operator which is converting a source sequence from one format to another, where the format specification is given by a set of operator properties. You may need the target format to change dynamically from time to time, but you may also need to guarantee that parts of the format specification do not change while the operator was converting some other input. The [`InputMapping`](xref:Bonsai.Expressions.InputMappingBuilder) operator allows you to do this by synchronizing property updates with input notifications.
63+
For example, imagine a transform operator which is converting a source sequence from one format to another, where the format specification is given by a set of operator properties. You may need the target format to change dynamically from time to time, but you may also need to guarantee that parts of the format specification do not change while the operator was converting some other input. The [`InputMapping`] operator allows you to do this by synchronizing property updates with input notifications.
6464

6565
[!include[InputMapping](~/articles/expressions-inputmapping.md)]
6666

6767
<!-- Reference-style links -->
68-
[`ConvertScale`]: xref:Bonsai.Dsp.ConvertScale
68+
[`ConvertScale`]: xref:Bonsai.Dsp.ConvertScale
69+
[`ExternalizedMapping`]: xref:Bonsai.Expressions.ExternalizedMappingBuilder
70+
[`InputMapping`]: xref:Bonsai.Expressions.InputMappingBuilder
71+
[`PropertyMapping`]: xref:Bonsai.Expressions.PropertyMappingBuilder

articles/subject-async.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ title: "AsyncSubject"
88
[`AsyncSubject`] stores and passes the last value (and only the last value) emitted by the source sequence to each subscribed observer. The value is also only sent out after the source sequence terminates. If the source sequence does not emit any value, [`AsyncSubject`] will also terminate without emitting any values.
99

1010
> [!Tip]
11-
> You can use the [`Take`](xref:Bonsai.Reactive.Take) operator before [`AsyncSubject`] to store the first value from an infinite sequence.
11+
> You can use the [`Take`] operator before [`AsyncSubject`] to store the first value from an infinite sequence.
1212
1313
Any observers which subscribe after the source sequence terminates will immediately receive the stored value. If the source sequence terminates with an error, [`AsyncSubject`] will not emit any values but will pass along the error notification to all observers.
1414

1515
<!-- Reference-style links -->
16-
[`AsyncSubject`]: xref:Bonsai.Reactive.AsyncSubject
16+
[`AsyncSubject`]: xref:Bonsai.Reactive.AsyncSubject
17+
[`Take`]: xref:Bonsai.Reactive.Take

articles/subject-publish.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ title: "PublishSubject"
77

88
[`PublishSubject`] passes to each subscribed observer only the values from the source sequence which were emitted after the time of subscription.
99

10-
This fire-and-forget behavior means that any observers which subscribe late might lose one or more items emitted between the time that [`PublishSubject`] was created and the time that the observer subscribed to it. If you require guaranteed delivery of all values from the source sequence, you need to ensure that all observers subscribe immediately upon workflow initialization. If this is not possible, you should consider switching to an [`AsyncSubject`](xref:Bonsai.Reactive.AsyncSubject) if the sequence contains a single value, or a [`ReplaySubject`](xref:Bonsai.Reactive.ReplaySubject) if the sequence contains multiple values.
10+
This fire-and-forget behavior means that any observers which subscribe late might lose one or more items emitted between the time that [`PublishSubject`] was created and the time that the observer subscribed to it. If you require guaranteed delivery of all values from the source sequence, you need to ensure that all observers subscribe immediately upon workflow initialization. If this is not possible, you should consider switching to an [`AsyncSubject`] if the sequence contains a single value, or a [`ReplaySubject`] if the sequence contains multiple values.
1111

1212
If the source sequence terminates with an error, [`PublishSubject`] will not emit any items to subsequent observers, but will pass along the terminating error.
1313

1414
<!-- Reference-style links -->
15-
[`PublishSubject`]: xref:Bonsai.Reactive.PublishSubject
15+
[`AsyncSubject`]: xref:Bonsai.Reactive.AsyncSubject
16+
[`PublishSubject`]: xref:Bonsai.Reactive.PublishSubject
17+
[`ReplaySubject`]: xref:Bonsai.Reactive.ReplaySubject

articles/workflow-guidelines.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This section offers guidelines and design patterns to consider when developing w
99
## Workflow Organization
1010

1111
:::do
12-
use [`GroupWorkflow`](xref:Bonsai.Expressions.GroupWorkflowBuilder) nodes to separate independent functionality (e.g. acquisition, visualization and processing).
12+
use [`GroupWorkflow`] nodes to separate independent functionality (e.g. acquisition, visualization and processing).
1313
:::
1414

1515
:::avoid
@@ -29,7 +29,7 @@ use a [`BehaviorSubject`] to share global state which can be accessed by multipl
2929
:::
3030

3131
:::avoid
32-
using [`MulticastSubject`](xref:Bonsai.Expressions.MulticastSubject) on variables which are not declared as [`BehaviorSubject`]. This will prevent accidental termination of the subject sequence if a producer terminates prematurely.
32+
using [`MulticastSubject`] on variables which are not declared as [`BehaviorSubject`]. This will prevent accidental termination of the subject sequence if a producer terminates prematurely.
3333
:::
3434

3535
:::consider
@@ -42,10 +42,10 @@ moving all subject declarations to the top of the workflow. This will make sure
4242

4343
## Nested Operators
4444

45-
Several reactive operators require specification of a nested workflow, e.g. [`SelectMany`](xref:Bonsai.Reactive.SelectMany) or [`CreateObservable`](xref:Bonsai.Reactive.CreateObservable). The operator itself will control when the nested workflow is initialized and subscribed to. If it is possible for a nested workflow to be executed multiple times, potentially in parallel, we call the operator *reentrant*. Some care is necessary to understand how to manage shared state and properties inside a reentrant nested operator.
45+
Several reactive operators require specification of a nested workflow, e.g. [`SelectMany`] or [`CreateObservable`]. The operator itself will control when the nested workflow is initialized and subscribed to. If it is possible for a nested workflow to be executed multiple times, potentially in parallel, we call the operator *reentrant*. Some care is necessary to understand how to manage shared state and properties inside a reentrant nested operator.
4646

4747
:::do
48-
use an [`AsyncSubject`](xref:Bonsai.Reactive.AsyncSubject) to share workflow input data inside a nested operator.
48+
use an [`AsyncSubject`] to share workflow input data inside a nested operator.
4949
:::
5050

5151
:::avoid
@@ -61,5 +61,10 @@ branch a source sequence to share the same value across different [`PropertyMapp
6161
Alternatively, you can either share the value using a subject, or branch after the [`PropertyMapping`] node (if both the value to share and the name of the property in each node are identical).
6262

6363
<!-- Reference-style links -->
64+
[`AsyncSubject`]: xref:Bonsai.Reactive.AsyncSubject
6465
[`BehaviorSubject`]: xref:Bonsai.Reactive.BehaviorSubject
65-
[`PropertyMapping`]: xref:Bonsai.Expressions.PropertyMappingBuilder
66+
[`CreateObservable`]: xref:Bonsai.Reactive.CreateObservable
67+
[`GroupWorkflow`]: xref:Bonsai.Expressions.GroupWorkflowBuilder
68+
[`MulticastSubject`]: xref:Bonsai.Expressions.MulticastSubject
69+
[`PropertyMapping`]: xref:Bonsai.Expressions.PropertyMappingBuilder
70+
[`SelectMany`]: xref:Bonsai.Reactive.SelectMany

tutorials/vision-psychophysics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ To implement the `TestGrating` state, we want to reuse our previous `RandomOrien
109109
![BonVision render test grating](~/workflows/bonvision-render-testgrating.bonsai)
110110
:::
111111

112-
- Insert a new `RandomOrientationGrating` operator from the toolbox and combine it with the input by using the `Zip` combinator. This will generate a pair where the first value is the random angle from the first reference grating, and the second value is the random angle for this test grating.
112+
- Insert a new `RandomOrientationGrating` operator from the toolbox and combine it with the input by using the [`Zip`] combinator. This will generate a pair where the first value is the random angle from the first reference grating, and the second value is the random angle for this test grating.
113113

114114
_Run the workflow and validate the random angle pairs are distinct and valid from trial to trial._
115115

0 commit comments

Comments
 (0)