Skip to content

Commit

Permalink
docs: extend timer example with buttons (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
domire8 authored Jan 10, 2025
1 parent 1f9f36d commit 9f87c98
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 83 deletions.
2 changes: 2 additions & 0 deletions docs/docs/concepts/05-building-blocks/03-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ using [transition events](./02-events.md#transitions). Associating the `on_load`
`lifecycle: configure` event enables the component to automatically configure itself. Equivalently, the `on_configure`
transition can be used to trigger a `lifecycle: activate` event.

<!-- TODO: explain that this only works if everything happens on load, not after deactivating it reactivates again -->

## Services

Components can provide service endpoints to trigger specific behaviors on demand. For compatibility with the application
Expand Down
58 changes: 30 additions & 28 deletions docs/docs/getting-started/04-examples/01-timer-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ application.

## Launcher configuration requirements

This example uses AICA Core v4.0.1 in the Launcher configuration.
This example uses AICA Core v4.2.0 in the Launcher configuration.

## Setting up the application

Expand All @@ -19,7 +19,7 @@ Copy the following application code into the text box under the Editor tab, repl
```yaml
schema: 2-0-2
dependencies:
core: v4.0.1
core: v4.2.0
on_start:
load:
component: timer
Expand All @@ -41,6 +41,7 @@ components:
is_timed_out:
transition: timer_2
parameters:
rate: !!float 5.0
timeout: !!float 2.0
timer_2:
component: aica_core_components::utility::Timer
Expand All @@ -59,8 +60,9 @@ components:
is_timed_out:
transition: timer
parameters:
rate: !!float 5.0
timeout: !!float 4.0
hardware: { }
hardware: {}
graph:
positions:
stop:
Expand Down Expand Up @@ -103,30 +105,6 @@ The display name field is used just for rendering the component on the graph.
In this case, `aica_core_components::utility::Timer` is the registration of a built-in AICA component. It is a lifecycle
component that starts a timer when the component is activated.

Thereafter, the initial component parameters are defined.

```yaml
parameters:
rate: !!float 5.0
timeout: !!float 2.0
```

All components have a `rate` parameter which defines the frequency of periodic execution steps. The default rate for
components is 10 Hertz, so 10 times per second. The component rate can be increased or decreased to make a component run
faster or slower, respectively.

The timer component has a special parameter called `timeout`, which is the duration in seconds that the timer should
be active. At the end of the timeout period, it will be in the "timed out" state.

:::info

The `!!float` tag is used to distinguish floating-point parameters from integer parameters in the YAML. Some YAML
document parsers, formatters or emitters would round a value such as `5.0` to the "equivalent" integer value `5`.
AICA Studio automatically adds the `!!float` tag to ensure that the Event Engine always parses the parameter as a
floating-point value.

:::

The `events` field of a component associates component state transitions and predicates with events.

```yaml
Expand All @@ -153,7 +131,7 @@ When a lifecycle component configures or activates itself automatically, this is

![auto lifecycle timer](./assets/auto-lifecycle-events-timer.png)

Finally, the timer component has a special predicate `is_timed_out`, which is internally associated with the `timeout`
Thereafter, the timer component has a special predicate `is_timed_out`, which is internally associated with the `timeout`
parameter.

```yaml
Expand All @@ -166,6 +144,30 @@ In this case, after the timer component has been active for 2 seconds, it trigge
The `transition` event from `timer` to `timer_2` is a shorthand for unloading the first component and loading the
second.

Finally, the initial component parameters are defined.

```yaml
parameters:
rate: !!float 5.0
timeout: !!float 2.0
```

All components have a `rate` parameter which defines the frequency of periodic execution steps. The default rate for
components is 10 Hertz, so 10 times per second. The component rate can be increased or decreased to make a component run
faster or slower, respectively.

The timer component has a special parameter called `timeout`, which is the duration in seconds that the timer should
be active. At the end of the timeout period, it will be in the "timed out" state.

:::info

The `!!float` tag is used to distinguish floating-point parameters from integer parameters in the YAML. Some YAML
document parsers, formatters or emitters would round a value such as `5.0` to the "equivalent" integer value `5`.
AICA Studio automatically adds the `!!float` tag to ensure that the Event Engine always parses the parameter as a
floating-point value.

:::

The second block describing `timer_2` is nearly identical (apart from a different value for the `timeout` parameter), as
the two timers are intended to have symmetrical behavior.

Expand Down
160 changes: 105 additions & 55 deletions docs/docs/getting-started/04-examples/02-editor-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
sidebar_position: 2
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# The application graph editor

In the previous steps, an example application graph was generated from YAML. The graph can also be edited interactively
Expand All @@ -15,88 +18,135 @@ on the page to expand either the code editor or graph view to full screen.
You can also use the graph control buttons on the bottom left to zoom and fit the view. The mini-map on the bottom right
can also be used to navigate around the graph.

<!-- TODO: parameters and auto-lifecycle events are no longer dropdowns, but part of the Parameter editor view -->

## Setting component parameters

![timer example](./assets/component-parameters.png)
## Editing component settings

Component parameters can be edited directly in the graph view.
Click on the Parameter dropdown of one of the timer components in the graph and look for the Timeout parameter field.
Try changing the number to a different value in seconds, and look for the corresponding change in the code editor.
Then press play on the application and observe that the timer now has a different duration before triggering the
"Is timed out" predicate.
Component parameters and settings can be edited directly from the graph view. Click on the gear icon of the first Timer
component to open its settings panel. The settings panel can be closed with the X or by clicking anywhere in the graph.

## Auto-lifecycle events
![timer settings](./assets/timer-settings.png)

![timer example](./assets/auto-lifecycle-events.png)
### Auto-lifecycle events

Because the timer components are lifecycle components, they only count down the time when they are active. By default,
the "Load" or "Transition" events start the lifecycle component in an unconfigured state. The "auto-configure" and
"auto-activate" toggle switches on the component can be used to enable or disable
[auto lifecycle events](../../concepts/05-building-blocks/03-components.md#auto-lifecycle-events).
"auto-activate" toggle switches can be used to enable or disable
[auto-lifecycle events](../../concepts/05-building-blocks/03-components.md#auto-lifecycle-events).

When both toggle switches are enabled, the YAML code will show the corresponding events for the componnts:

```yaml
events:
is_unconfigured:
lifecycle: configure
is_inactive:
lifecycle: activate
transitions:
on_load:
lifecycle:
component: timer
transition: configure
on_configure:
lifecycle:
component: timer
transition: activate
```
Disabling one or both auto event switches will also remove the corresponding events from the YAML, while enabling the
switch will regenerate the event in the YAML.
Disabling one or both auto-lifecycle event switches will also remove the corresponding events from the YAML, while
enabling the switch will regenerate the event in the YAML.
## Setting component parameters
Component parameters can be edited directly in the settings panel. Change the value of the Timeout parameter and look
for the corresponding change in the code editor. Then press play on the application and observe that the timer now has a
different duration before triggering the "Is timed out" predicate.
<!-- TODO: explain behavior with "default" once it's working as intended -->
## Adding and deleting elements
Elements can be added to the graph using the sidebar menu; press the (+) button in the top right corner of the graph to
open the sidebar and see a list of available application elements. At the top of the list are the "Hardware Interface",
"Trigger Events Button", "Sequence" and "Condition" nodes. These are followed by a list of all available components from
AICA Core and any additionally installed packages, grouped by package. Clicking on any element in the sidebar will
automatically add it to the graph.
<!-- TODO: link the examples once they exist -->
<Tabs groupId="os">
<TabItem value="linux" label="Linux">
To delete an element from the graph, press the small menu icon in its top right corner, then click Remove. Elements can
also be deleted by selecting them with a click and pressing the Backspace key on your keyboard.
<!-- TODO: Replace the following sections with adding interactive buttons
</TabItem>
<TabItem value="mac" label="macOS">
Show how we can:
- go to the sidebar
- click on add trigger button
- drag to reposition
- create an event edge to the timer
- choose the event type (e.g. deactivate)
- rename the button
To delete an element from the graph, press the small menu icon in its top right corner, then click Remove. Elements can
also be deleted by selecting them with a click and pressing the Delete key on your keyboard.
Repeat for a second button to show manual deactivation / activation
</TabItem>
</Tabs>
Then say: now that we learned to add buttons and create event edges, try to do the same for components. As an exercise,
search for and add timer components, set thea auto-lifecycle events, and connect the transition edges to recreate the
example from scratch.
-->
To delete an element from the graph, press the small menu icon in its top right corner, then click Remove. Elements can
also be deleted by selecting them with a click and pressing the Delete keyboard shortcut.
For this example, let's add a "Trigger Events Button" to the timer application by clicking on it in the sidebar. A new
button should appear on the graph and in the code. This is an interactive elements that can be used to trigger events
through mouse clicks and interact with the flow of the application.
The sidebar menu can be closed with the X icon or by clicking anywhere in the graph.
Drag the button to change its position in the graph. This will also update the corresponding Trigger Events Button
position in the YAML code editor.
## Creating and deleting event edges
The timers are connected with a Transition event edge. To change the event type on an edge, click on the label. This
will open a selection menu showing other available event types (for example, Load, Unload, Configure...). Choosing
a different event type will close the selection menu and update the YAML code accordingly.
To create a new edge, move the mouse over an event source handle until the cursor changes to a targeting reticule. Then,
click and drag to create a draft edge. Pull it towards a target handle (on the top left of a component) until the cursor
changes again and the draft edge snaps in place, at which point you can let go of the mouse button. If the connection is
valid, it will create a new event edge with the default event (Load). Event source handles are found under transitions
and predicates of a component and look like that:
![timer example](./assets/event-edge.png)
![event handle](./assets/event-source-handle.png)
Clicking on an edge also selects it, which is indicated by the increased line thickness. Clicking away from the edge
will deselect it. While the edge is selected, press the delete key to delete the edge. This will also remove the
event from the YAML representation.
:::note
All components also have a similar source handle icon on the top right. This handle is not an event source and cannot be
connected to target components or hardware with event edges. Instead, it is a condition source used to connect condition
edges to condition and sequence inputs.
Invalid edge connections will automatically be rejected.
To create a new edge, move the mouse over the event source handle next to a component predicate until the cursor changes
to a targeting reticule. Then, click and drag to create a draft edge. Pull it towards a target handle (on the top left
of a component) until the cursor changes again and the draft edge snaps in place, then let go of the mouse button.
<!-- TODO: link example with conditions -->
If the connection is valid, it will create a new event edge with the default event (Load).
:::
Create an event edge between the new trigger button and the Timer 2 component. The default event type for newly created
edge is always "Load". To change the type of event that should be triggered, click on the event label on the edge to
open a selection menu showing other available event types (for example, Load, Unload, Configure...) and click on the
desired event. This will close the selection menu and update the YAML code accordingly.
For this example, choose the Deactivate event in order to pause the timer on click of the button.
![event edge](./assets/event-edge.png)
Clicking on an edge also selects it, which is indicated by the increased line thickness. Clicking away from the edge
will deselect it. While the edge is selected, press the Delete key to delete the edge. This will also remove the
event from the YAML representation.
## Adding and deleting components
Now add a second trigger button, create a new event edge to Timer 2 and choose the Activate event type.
Components can be added to the graph using the component sidebar menu; press the (+) button in the corner of the graph
to open the sidebar. At the top, you will see two special entries "Event Trigger" and "Hardware Interface", which will
be explained in a later example. These are followed by a list of components with a name and brief description.
![trigger buttons](./assets/trigger-buttons.gif)
Try to add a third timer component to the application using the graph editor. Search for "timer" in the search field and
then click on the Timer component. A new component should appear on the graph and in the code.
## Renaming elements in the graph
The sidebar menu can be closed by clicking anywhere in the graph. Click and drag on the component to change its position
in the graph. This will also update the associated position in the code editor.
Both buttons now still have the default "Trigger Events Button" name, which may become confusing in larger applications.
To rename an element in the graph, click on the small menu icon in its top right corner, then click Rename. Give the two
buttons a new name: "Pause Timer" for the button with the Deactivate event, and "Play Timer" for the button with the
Activate event.
To delete a component, press the small menu icon in the top right corner of the component, then click Remove.
Now, try to run the application again and use the Pause Timer and Play Timer trigger buttons to deactivate and activate
Timer 2 while it is active. Verify that once deactivated, the elapsed time does not count towards the component timing
out and it only times out once it has been in the active state for a total of 4 seconds. That is, deactivating the
component will freeze the timer until reactivation.
As an exercise, delete all the components and try to recreate the timer application example from scratch using only the
graph editor. Remember to set a timeout value in the component parameters.
Now that we learned to add buttons and create event edges, try to do the same for components. As an exercise, delete
all elements from the graph and try to recreate this example from scratch using only the graph editor. Search for and
add the timer components from the sidebar, set the auto-lifecycle events, and connect the transition edges. Remember to
set a timeout value in the component parameters.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/docs/getting-started/04-examples/assets/timer-example.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/docs/getting-started/04-examples/assets/timer-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9f87c98

Please sign in to comment.