Revision control

Copy as Markdown

// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example tasktree/trafficlight
\meta tags {widgets}
\examplecategory {Data Processing & I/O}
\title TaskTree Traffic Light
\ingroup tasktree_examples
\brief Demonstrates how to implement state machine behavior using TaskTree
through a traffic light simulation.
The \e {TaskTree Traffic Light} is an alternative implementation
for the Traffic Light examples in
\l {SCXML Traffic Light (Static, Widgets)} {Qt SCXML} and
\l {Traffic Light} {Qt State Machine}.
\image tasktree-trafficlight-example.png
{Traffic light with green light illuminated and pause button}
The application consists of three main components:
\list
\li A \c TrafficLight widget that displays the current state.
\li A \c TaskTree recipe that controls state transitions.
\li A \c GlueInterface that synchronizes the UI with the state machine.
\endlist
The following sections describe more details of the example's code.
\section1 Helper Glue Class
The \c GlueInterface class provides a clean separation between the UI and
operational logic.
\snippet tasktree/trafficlight/glueinterface.h 0
The \c GlueInterface class provides the following interface methods:
\table
\header
\li Method
\li Purpose
\row
\li \c setLights()
\li Updates traffic light state from TaskTree recipe
\row
\li \c lightsChanged()
\li Notifies UI when light states change
\row
\li \c smash()/ \c repair()
\li Handles fault simulation and recovery actions
\endtable
When users interact with the UI:
\list
\li Clicking pause triggers \c smash(), simulating a fault.
\li Clicking play triggers \c repair(), restoring normal operation.
\endlist
\section1 Implementing the state machine
The state machine logic is implemented through a TaskTree recipe.
The \c recipe() method creates this logic using a reference to \c GlueInterface:
\snippet tasktree/trafficlight/recipe.cpp 0
\section2 Root state management
The top level \l {QtTaskTree::}{Forever} item executes its
children in an infinite loop. It contains two subgroups representing
\e working and \e broken states.
State transition rules:
\list
\li States execute in sequence, because the default
\l {Execution Mode}{execution mode} is
\l {QtTaskTree::}{sequential}.
\li When one state completes, the other begins.
\li Transitions are triggered when a user clicks the pause or play
button in the UI, emitting the corresponding signal.
\endlist
\section2 The "working" operation state
The \e working \l {QtTaskTree::}{Group} consists of two
tasks running in \l {QtTaskTree::}{parallel}:
\list
\li The \l {QtTaskTree::}{signalAwaiterTask}
connects to the \c GlueInterface::smashed signal. If the signal is
triggered, the task immediately finishes with
\l {QtTaskTree::}{DoneResult::Success}. This
causes the \e working \l {QtTaskTree::}{Group} to stop
executing, and the recipe transitions to the \e broken state.
\li The nested \l {QtTaskTree::}{Forever} task consist of
four \c switchLightsTask tasks ("red", "redGoingGreen", "green", and
"greenGoingRed") executed \l {QtTaskTree::sequential}{sequentially}
in an infinite loop.
\endlist
The \l {QtTaskTree::}{stopOnSuccess} item of each group
instructs it to stop executing when any of its child tasks finishes with
\l {QtTaskTree::}{DoneResult::Success}.
The \c switchLightsTask implementation:
\list
\li Updates light states through \c GlueInterface::setLights().
\li Creates a timed delay using \l {QtTaskTree::}{timeoutTask}.
\li Maintains state for the specified duration \c timeout.
\endlist
\snippet tasktree/trafficlight/recipe.cpp 1
\section2 The "broken" operation state
The \e broken \l {QtTaskTree::}{Group} is similar to the
\e working \l {QtTaskTree::}{Group}. The only difference is that it
connects to the \c GlueInterface::repaired signal, and the lights cycle only
between 2 states toggling the \e yellow light on and off.
\section1 Application setup
The main application setup creates and connects all components:
\snippet tasktree/trafficlight/main.cpp 0
The \c main() function instantiates QApplication, \c GlueInterface,
QTaskTree and \c TrafficLight objects.
To construct the \c taskTree object, we pass a \c recipe() constructed with
the \c iface object. The \c widget also uses the passed \c iface object.
Before executing the application, the \c main() function shows the
\c TrafficLight widget and starts the task tree.
\include examples-run.qdocinc
*/