Skip to content

Commit

Permalink
Merge pull request #97 from banchan86/workflow-container-update
Browse files Browse the repository at this point in the history
Workflow container update
  • Loading branch information
glopesdev authored Nov 8, 2024
2 parents 9407e55 + 3cf90b1 commit ebe5faa
Show file tree
Hide file tree
Showing 134 changed files with 5,588 additions and 834 deletions.
4 changes: 3 additions & 1 deletion articles/higher-order.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ When building simple reactive programs, it is usually enough to place a source f

However, sometimes you may need to build systems that deal with an unknown number of sources. For example, imagine you wanted to create a workflow to merge together several video files. If you knew beforehand how many files you will need to combine and where they are exactly located, you might use the [`Concat`](xref:Bonsai.Reactive.Concat) operator to design a workflow like the following:

![Concatenate video files using first order operators](~/images/concatfile-firstorder.svg)
:::workflow
![Concatenate video files using first order operators](~/workflows/concatfile-firstorder.bonsai)
:::

But what if you did not know beforehand how many video files you will need to combine, and you wanted to merge all these videos without having to manually place a source node for every file?

Expand Down
4 changes: 3 additions & 1 deletion articles/observables.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ In this case we can see from the diagram that the [`Condition`](xref:Bonsai.Reac

The Bonsai language uses a graphical representation called a *workflow* to describe complex combinations of operations on observable sequences.

![Example workflow](~/images/language-sampleframe.svg)
:::workflow
![Example workflow](~/workflows/language-sampleframe.bonsai)
:::

In a workflow, each node represents an operator defining an observable sequence. Nodes can be connected to other nodes, from left to right. Each connection indicates that the downstream operator on the right subscribes, or "listens", to the notifications of the upstream operator on the left.

Expand Down
12 changes: 9 additions & 3 deletions articles/property-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ Each Bonsai operator exposes a set of configuration properties that allow you to

As an example, imagine you wanted to continuously playback a sound WAV file to the speakers at a specified volume level. You might design a workflow that looks like the following:

![WAV file playback](~/images/language-wavplayback.svg)
:::workflow
![WAV file playback](~/workflows/language-wavplayback.bonsai)
:::

Using the [`ConvertScale`](xref:Bonsai.Dsp.ConvertScale) operator you could set the volume manually by changing its [`Scale`](xref:Bonsai.Dsp.ConvertScale.Scale) parameter.

Now consider a variation of this workflow where the playback volume needs to be modulated continuously depending on some other variable, for example the horizontal position of the mouse cursor as it moves across the screen.

A simple way to compute the desired scale value would be to rescale the X coordinate of mouse movements to a range between zero and one:

![Rescaled mouse position](~/images/language-mouserescale.svg)
:::workflow
![Rescaled mouse position](~/workflows/language-mouserescale.bonsai)
:::

However, how would you now connect the sequence of scale values computed from the mouse position to changes in the [`Scale`](xref:Bonsai.Dsp.ConvertScale.Scale) property of the [`ConvertScale`](xref:Bonsai.Dsp.ConvertScale) node?

Expand All @@ -43,7 +47,9 @@ After an operator property has been externalized, you can connect any sequence w

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

![Rescale WAV playback with mouse position](~/images/language-wavplayback-mapping.svg)
:::workflow
![Rescale WAV playback with mouse position](~/workflows/language-wavplayback-mapping.bonsai)
:::

[!include[PropertyMapping](~/articles/expressions-propertymapping.md)]

Expand Down
4 changes: 3 additions & 1 deletion articles/subject-multicast.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ title: "MulticastSubject"

The `MulticastSubject` operator works like a sink which accesses the subject with the specified name, at the same scope level or above, and forwards any values emitted by the source sequence to the shared subject. Depending on the behavior of the subject, these values will then be passed to any operators subscribed to the subject, including any termination and error notifications.

![Example workflow](~/images/language-subject-multicast.svg)
:::workflow
![MulticastSubject workflow](~/workflows/language-subject-multicast.bonsai)
:::
4 changes: 3 additions & 1 deletion articles/subject-subscribe.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ title: "SubscribeSubject"

The `SubscribeSubject` operator is essentially a source which accesses a subject with the specified name, at the same scope level or above, and subscribes to it. The behavior of `SubscribeSubject` is defined by the type of the subject which is accessed, and values from the shared underlying sequence will then be passed to any operators downstream from `SubscribeSubject`, as if these operators were connected to the subject directly.

![Example workflow](~/images/language-subject-subscribe.svg)
:::workflow
![SubscribeSubject workflow](~/workflows/language-subject-subscribe.bonsai)
:::

> [!Note]
> If the definition of the underlying subject changes, there is no need to change the `SubscribeSubject` as long as the name remains the same.
16 changes: 12 additions & 4 deletions articles/subjects.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Subjects are a special type of operator that allows reusing and sharing of obser

Most subjects will be given a name. You can subscribe to a named subject from anywhere in the workflow using the [`SubscribeSubject`](#subscribesubject) operator, making subjects very useful to organize complex workflows into modular components that can be easily replaced. The following example demonstrates how to separate logging of a sequence of images using a [`PublishSubject`](#publishsubject).

![Example of using subjects to share observable sequences](~/images/language-subjects.svg)
:::workflow
![Example of using subjects to share observable sequences](~/workflows/language-subjects.bonsai)
:::

Finally, subjects also allow you to control the [temperature](xref:observables#temperature) of the shared sequence. You can convert a sequence from *cold* to *hot* using [`PublishSubject`](#publishsubject) or from *hot* to *cold* using [`ReplaySubject`](#replaysubject).

Expand All @@ -25,7 +27,9 @@ Similarly, if node groups are used to define [higher-order observable sequences]

Anonymous branch points in the workflow implicitly define a [`PublishSubject`](#publishsubject) with no name. All branches are first subscribed to the subject prior to subscribing to the common source sequence, so there is a guarantee that every value will be delivered to all branches, assuming immediate subscription.

![Example of using branching to share observable sequences](~/images/language-subjects-branching.svg)
:::workflow
![Example of using branching to share observable sequences](~/workflows/language-subjects-branching.bonsai)
:::

> [!Warning]
> Dangling branches operate independently from each other, and from the subscription to the source sequence. If one branch terminates and resubscribes to the source (e.g. using the [`Repeat`](xref:Bonsai.Reactive.Repeat) operator) while other branches keep going, this will not reinitialize the shared subscription to the source. If such behavior is of interest, you will need to merge all branches together and implement the cancellation and resubscription logic downstream of the merge point.
Expand All @@ -34,7 +38,9 @@ Anonymous branch points in the workflow implicitly define a [`PublishSubject`](#

Subjects can be declared either as a sink from an existing observable sequence, or as a source. Source subjects do not have a pre-existing input sequence from which values are generated, but rather they are setup to redirect inputs from multiple writers into one reader, for example for logging or control purposes.

![Example of declaring a subject as a sink or a source](~/images/language-subject-declaration.svg)
:::workflow
![Example of declaring a subject as a sink or a source](~/workflows/language-subject-declaration.bonsai)
:::

If subjects are created as a source, the type of the subject needs to be declared explicitly on creation. This is done by selecting the source sequence in the workflow whose type we would like to share, and using the right-click context menu.

Expand All @@ -46,7 +52,9 @@ If subjects are created as a source, the type of the subject needs to be declare

Below are listed all different subject types, each represented visually by a unique icon.

![Visual indication of subject types](~/images/language-subject-types.svg)
:::workflow
![Visual indication of subject types](~/workflows/language-subject-types.bonsai)
:::

The last two operators, [`SubscribeSubject`](#subscribesubject) and [`MulticastSubject`](#multicastsubject), are used to access existing declared subjects for reading and writing, respectively. This is visually indicated by the `*` in the operator icon. Their behavior will be determined by the type of subject they are accessing.

Expand Down
3 changes: 0 additions & 3 deletions images/bonvision-orientation-discrimination-feedback.svg

This file was deleted.

Loading

0 comments on commit ebe5faa

Please sign in to comment.