C code generator

C code generator features

IdentifierSettings feature

The IdentifierSettings feature allows the configuration of module names and identifier character length:

  • moduleName (String, optional): Name for header and implementation. By default, the name of the statechart is used.
  • statemachinePrefix (String, optional): Prefix that is prepended to function, state, and type names. By default, the name of the statechart is used.
  • maxIdentifierLength (Integer, optional): DEPRECATED. Maximum number of characters of an identifier. Default: 31 characters, which is complying with the ANSI C99 standard.
  • separator (String, optional): Character to replace whitespace and otherwise illegal characters in names.

Please note that the maxIdentifierLength option, which existed in older versions of YAKINDU Statechart Tools, has been removed in favor of a statechart annotation that is only available in the C/C++ domain bundled with YAKINDU Statechart Tools Professional Edition, see @ShortIdentifiers.

Example:

feature IdentifierSettings {
    moduleName = "MyStatechart"
    statemachinePrefix = "myStatechart"
    maxIdentifierLength = 31
    separator = "_"
}

Tracing feature

The Tracing feature enables the generation of tracing callback functions:

  • enterState (boolean, optional): Specifies whether to generate a callback function that is used to notify about state-entering events.
  • exitState (boolean, optional): Specifies whether to generate a callback that is used to notify about state-exiting events.

Example:

feature Tracing {
    enterState = true
    exitState  = true
}

Includes feature

The Includes feature allows to change how include statements are generated:

  • useRelativePaths (Boolean, optional): If this parameter is set to true, relative paths are calculated for include statements, otherwise simple includes are used. Default: true.

Example:

feature Includes {
    useRelativePaths = false
}

Specification of C code

In order to describe the API specifications of the code generated by the YAKINDU C generator, the explanations below are using the Traffic Light sample state machine, see figure "The Traffic Light sample statechart model" . It models a pedestrian crossing with push-button operated traffic lights („pelican crossing”).


The _Traffic Light_ sample statechart model

The Traffic Light sample statechart model

Generated code files

You will find the generated code in the src-gen folder of the traffic light example.

The C code generator generates two or three header files, depending on the statechart.

  • sc_types.h: Contains type definitions used by the statechart. Since the contents of this file is always the same for all statecharts, it will be generated only if it does not yet exist. And since it will never be overwritten, you can change or amend the definitions made there. For example, you might wish to adapt the types to better match your target platform.
  • Statechart.h: Contains the basic declarations for everything needed in the underlying statechart’s code. The file is named after the statechart, i.e., if the statechart’s name is TrafficLight, this file’s name will be TrafficLight.h. It is always generated.
  • StatechartRequired.h: Contains declarations of functions the developer has to implement. The file is named after the statechart, i.e., if the statechart’s name is TrafficLight, this file’s name will be TrafficLightRequired.h. It is generated only if one or more of the following conditions are fulfilled:
    • The statechart declares operations.
    • The statechart uses timing features.
    • The code generator model activates the Tracing feature.
The first one is sc_types.h:

#ifndef SC_TYPES_H_
#define SC_TYPES_H_

#ifdef __cplusplus
extern "C"
{
#endif 

#include <stdint.h>
#include <stdbool.h>

#define sc_string		char*
 
typedef bool			sc_boolean;
typedef int_fast16_t	sc_short;
typedef uint_fast16_t	sc_ushort;
typedef int32_t			sc_integer;
typedef uint32_t		sc_uinteger;

typedef double			sc_real;

typedef void*			sc_eventid;

typedef intptr_t		sc_intptr_t;

#ifdef __cplusplus
}
#endif

#ifndef null
	#ifdef __cplusplus
		#define null 0
	#else
		#define null ((void *)0)
	#endif
#endif

#define bool_true true
#define bool_false false

#endif /* SC_TYPES_H_ */

The header file contains some basic definitions for C++ compiler compatibility and some typedefs to map the YAKINDU statechart types to C types.

The next header file is named after the statechart. In case of the traffic light example it is called TrafficLight.h:



#ifndef TRAFFICLIGHTWAITING_H_
#define TRAFFICLIGHTWAITING_H_

#include "../src/sc_types.h"
		
#ifdef __cplusplus
extern "C" { 
#endif 

/*! \file Header of the state machine 'TrafficLightWaiting'.
*/


/*! Enumeration of all states */ 
typedef enum
{
	TrafficLightWaiting_last_state,
	TrafficLightWaiting_main_region_on,
	TrafficLightWaiting_main_region_on_r1_StreetGreen,
	TrafficLightWaiting_main_region_on_r1_PedWaiting,
	TrafficLightWaiting_main_region_on_r1_PedWaiting_r1_waitOn,
	TrafficLightWaiting_main_region_on_r1_PedWaiting_r1_waitOff,
	TrafficLightWaiting_main_region_on_r1_StreetAttention,
	TrafficLightWaiting_main_region_on_r1_StreetRed,
	TrafficLightWaiting_main_region_on_r1_PedestrianGreen,
	TrafficLightWaiting_main_region_on_r1_PedestrianRed,
	TrafficLightWaiting_main_region_on_r1_StreetPrepare,
	TrafficLightWaiting_main_region_off,
	TrafficLightWaiting_main_region_off_r1_YellowOn,
	TrafficLightWaiting_main_region_off_r1_YellowOff
} TrafficLightWaitingStates;

/*! Type definition of the data structure for the TrafficLightWaitingIfaceTrafficLight interface scope. */
typedef struct
{
	sc_boolean red;
	sc_boolean yellow;
	sc_boolean green;
} TrafficLightWaitingIfaceTrafficLight;

/*! Type definition of the data structure for the TrafficLightWaitingIfacePedestrian interface scope. */
typedef struct
{
	sc_boolean request;
	sc_boolean red;
	sc_boolean green;
} TrafficLightWaitingIfacePedestrian;

/*! Type definition of the data structure for the TrafficLightWaitingIface interface scope. */
typedef struct
{
	sc_boolean pedestrianRequest_raised;
	sc_boolean onOff_raised;
} TrafficLightWaitingIface;

/*! Type definition of the data structure for the TrafficLightWaitingTimeEvents interface scope. */
typedef struct
{
	sc_boolean trafficLightWaiting_main_region_on_r1_PedWaiting_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_PedWaiting_r1_waitOn_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_PedWaiting_r1_waitOff_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_StreetAttention_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_StreetRed_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_PedestrianGreen_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_PedestrianRed_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_on_r1_StreetPrepare_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_off_r1_YellowOn_tev0_raised;
	sc_boolean trafficLightWaiting_main_region_off_r1_YellowOff_tev0_raised;
} TrafficLightWaitingTimeEvents;


/*! Define dimension of the state configuration vector for orthogonal states. */
#define TRAFFICLIGHTWAITING_MAX_ORTHOGONAL_STATES 1

/*! Define maximum number of time events that can be active at once */
#define TRAFFICLIGHTWAITING_MAX_ACTIVE_TIME_EVENTS 2

/*! Define indices of states in the StateConfVector */
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_STREETGREEN 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_PEDWAITING 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_PEDWAITING_R1_WAITON 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_PEDWAITING_R1_WAITOFF 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_STREETATTENTION 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_STREETRED 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_PEDESTRIANGREEN 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_PEDESTRIANRED 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON_R1_STREETPREPARE 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_OFF 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_OFF_R1_YELLOWON 0
#define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_OFF_R1_YELLOWOFF 0

/*! 
 * Type definition of the data structure for the TrafficLightWaiting state machine.
 * This data structure has to be allocated by the client code. 
 */
typedef struct
{
	TrafficLightWaitingStates stateConfVector[TRAFFICLIGHTWAITING_MAX_ORTHOGONAL_STATES];
	sc_ushort stateConfVectorPosition; 
	
	TrafficLightWaitingIfaceTrafficLight ifaceTrafficLight;
	TrafficLightWaitingIfacePedestrian ifacePedestrian;
	TrafficLightWaitingIface iface;
	TrafficLightWaitingTimeEvents timeEvents;
} TrafficLightWaiting;


/*! Initializes the TrafficLightWaiting state machine data structures. Must be called before first usage.*/
extern void trafficLightWaiting_init(TrafficLightWaiting* handle);

/*! Activates the state machine */
extern void trafficLightWaiting_enter(TrafficLightWaiting* handle);

/*! Deactivates the state machine */
extern void trafficLightWaiting_exit(TrafficLightWaiting* handle);

/*! Performs a 'run to completion' step. */
extern void trafficLightWaiting_runCycle(TrafficLightWaiting* handle);

/*! Raises a time event. */
extern void trafficLightWaiting_raiseTimeEvent(const TrafficLightWaiting* handle, sc_eventid evid);

/*! Gets the value of the variable 'red' that is defined in the interface scope 'TrafficLight'. */ 
extern sc_boolean trafficLightWaitingIfaceTrafficLight_get_red(const TrafficLightWaiting* handle);
/*! Sets the value of the variable 'red' that is defined in the interface scope 'TrafficLight'. */ 
extern void trafficLightWaitingIfaceTrafficLight_set_red(TrafficLightWaiting* handle, sc_boolean value);
/*! Gets the value of the variable 'yellow' that is defined in the interface scope 'TrafficLight'. */ 
extern sc_boolean trafficLightWaitingIfaceTrafficLight_get_yellow(const TrafficLightWaiting* handle);
/*! Sets the value of the variable 'yellow' that is defined in the interface scope 'TrafficLight'. */ 
extern void trafficLightWaitingIfaceTrafficLight_set_yellow(TrafficLightWaiting* handle, sc_boolean value);
/*! Gets the value of the variable 'green' that is defined in the interface scope 'TrafficLight'. */ 
extern sc_boolean trafficLightWaitingIfaceTrafficLight_get_green(const TrafficLightWaiting* handle);
/*! Sets the value of the variable 'green' that is defined in the interface scope 'TrafficLight'. */ 
extern void trafficLightWaitingIfaceTrafficLight_set_green(TrafficLightWaiting* handle, sc_boolean value);
/*! Gets the value of the variable 'request' that is defined in the interface scope 'Pedestrian'. */ 
extern sc_boolean trafficLightWaitingIfacePedestrian_get_request(const TrafficLightWaiting* handle);
/*! Sets the value of the variable 'request' that is defined in the interface scope 'Pedestrian'. */ 
extern void trafficLightWaitingIfacePedestrian_set_request(TrafficLightWaiting* handle, sc_boolean value);
/*! Gets the value of the variable 'red' that is defined in the interface scope 'Pedestrian'. */ 
extern sc_boolean trafficLightWaitingIfacePedestrian_get_red(const TrafficLightWaiting* handle);
/*! Sets the value of the variable 'red' that is defined in the interface scope 'Pedestrian'. */ 
extern void trafficLightWaitingIfacePedestrian_set_red(TrafficLightWaiting* handle, sc_boolean value);
/*! Gets the value of the variable 'green' that is defined in the interface scope 'Pedestrian'. */ 
extern sc_boolean trafficLightWaitingIfacePedestrian_get_green(const TrafficLightWaiting* handle);
/*! Sets the value of the variable 'green' that is defined in the interface scope 'Pedestrian'. */ 
extern void trafficLightWaitingIfacePedestrian_set_green(TrafficLightWaiting* handle, sc_boolean value);
/*! Raises the in event 'pedestrianRequest' that is defined in the default interface scope. */ 
extern void trafficLightWaitingIface_raise_pedestrianRequest(TrafficLightWaiting* handle);

/*! Raises the in event 'onOff' that is defined in the default interface scope. */ 
extern void trafficLightWaitingIface_raise_onOff(TrafficLightWaiting* handle);


/*!
 * Checks whether the state machine is active (until 2.4.1 this method was used for states).
 * A state machine is active if it was entered. It is inactive if it has not been entered at all or if it has been exited.
 */
extern sc_boolean trafficLightWaiting_isActive(const TrafficLightWaiting* handle);

/*!
 * Checks if all active states are final. 
 * If there are no active states then the state machine is considered being inactive. In this case this method returns false.
 */
extern sc_boolean trafficLightWaiting_isFinal(const TrafficLightWaiting* handle);

/*! Checks if the specified state is active (until 2.4.1 the used method for states was called isActive()). */
extern sc_boolean trafficLightWaiting_isStateActive(const TrafficLightWaiting* handle, TrafficLightWaitingStates state);



#ifdef __cplusplus
}
#endif 

#endif /* TRAFFICLIGHTWAITING_H_ */


Within this header file an enum containing the state names is defined as well as data structures for each of the statechart’s interfaces. Additionally a structure for the statechart’s time events is defined. The interfaces' and time events' data structures are nested into the parent structure TrafficLight. The client has to allocate memory for this structure. It is a common parameter of most functions the generated state machine code defines. In the subsequent text, this structure is called the statechart data structure.

Defines and constants in the statechart header file

The header file Statechart.h contains several #define statements for constants that are explained below, based on the TrafficLight example and the header file shown above.

  • #define TRAFFICLIGHTWAITING_MAX_ORTHOGONAL_STATES 1: The orthogonality of this statechart, that is, the maximum number of states that will be active at the same time. The state configuration vector manages the active states. It has this many entries.
  • #define TRAFFICLIGHTWAITING_MAX_ACTIVE_TIME_EVENTS 2: The maximum number of time events this statechart will have to wait for simultaneously. When writing a timer service, you can use this constant to plan for the amount of memory you will have to allocate for timers. (Take a look at the traffic light statechart. Can you find the state in which two time events will be active at the same time?)
  • #define SCVI_TRAFFICLIGHTWAITING_MAIN_REGION_ON 0 (and so on): The index of the state in the state configuration vector. Since this example does not have any orthogonal regions, all indices are 0. If states are orthogonal to each other, their index will be different.
Fundamental statechart functions

The generated code contains fundamental functions to initialize, enter, and exit a state machine, as well as a function to execute a run-to-completion step.

In the header file, the function names are made up of the state machine name followed by the name of the respective functionality. For the traffic light example, these functions are generated as follows:

/*! Initializes the TrafficLight state machine data structures. Must be called before first usage.*/
extern void trafficLight_init(TrafficLight* handle);

/*! Activates the state machine */
extern void trafficLight_enter(TrafficLight* handle);

/*! Deactivates the state machine */
extern void trafficLight_exit(TrafficLight* handle);

/*! Performs a 'run to completion' step. */
extern void trafficLight_runCycle(TrafficLight* handle);

  • The init() function is used to initialize the internal objects of the state machine right after its instantiation. Variables are initialized to their respective default values. If the statechart defines any initialized variables, these initializations are also done in the init() function.

  • The enter() function must be called to enter the state machine. It brings the state machine to a well-defined state.

  • The exit() function is used to leave a state machine statefully. If for example a history state is used in one of the top regions, the last active state is stored and the state machine is left via exit(). Re-entering it via enter() continues to work with the saved state.

  • The runCycle() function is used to trigger a run-to-completion step in which the state machine evaluates arising events and computes possible state changes. Somewhat simplified, a run-to-completion cycle consists of the following steps:

    1. Clear the list of outgoing events.

    2. Check whether any events have occurred which are leading to a state change.

    3. If a state change has to be done:

      1. Make the present state inactive.

      2. Execute exit actions of the present state.

      3. Save history state, if necessary.

      4. Execute transition actions, if any.

      5. Execute entry actions of the new state.

      6. Make the new state active.

    4. Clear the list of incoming events.

Accessing variables and events

The client code can read and write state machine variables and raise state machine events. The getters and setters for each variable and event are also contained in the header file. The function names are matching the following pattern:

statechart_name Iface interface_name _ [ set | get | raise ] _ [ variable_name|_event_name_]

For example, the getter of the red variable of the Pedestrian interface is named trafficLightIfacePedestrian_get_red(TrafficLight* handle)

Time-controlled state machines

If a statechart uses timing functionality or external operations, or tracing is activated in the generator model, an additional header file is generated. Its name matches the following pattern:

statechart_name Required.h

This header file declares functions the client code has to implement externally.

Example

The traffic light example uses timing functionality, namely after clauses. To support time-controlled behavior, the additional header file TrafficLightRequired.h is generated. Note the two functions trafficLight_setTimer and trafficLight_unsetTimer..



#ifndef TRAFFICLIGHTWAITINGREQUIRED_H_
#define TRAFFICLIGHTWAITINGREQUIRED_H_

#include "../src/sc_types.h"
#include "TrafficLightWaiting.h"

#ifdef __cplusplus
extern "C"
{
#endif 

/*! \file This header defines prototypes for all functions that are required by the state machine implementation.

This is a state machine uses time events which require access to a timing service. Thus the function prototypes:
	- trafficLightWaiting_setTimer and
	- trafficLightWaiting_unsetTimer
are defined.

These functions will be called during a 'run to completion step' (runCycle) of the statechart. 
There are some constraints that have to be considered for the implementation of these functions:
	- never call the statechart API functions from within these functions.
	- make sure that the execution time is as short as possible.
 
*/




/*!
 * This is a timed state machine that requires timer services
 */ 

/*! This function has to set up timers for the time events that are required by the state machine. */
/*! 
	This function will be called for each time event that is relevant for a state when a state will be entered.
	\param evid An unique identifier of the event.
	\time_ms The time in milli seconds
	\periodic Indicates the the time event must be raised periodically until the timer is unset 
*/
extern void trafficLightWaiting_setTimer(TrafficLightWaiting* handle, const sc_eventid evid, const sc_integer time_ms, const sc_boolean periodic);

/*! This function has to unset timers for the time events that are required by the state machine. */
/*! 
	This function will be called for each time event taht is relevant for a state when a state will be left.
	\param evid An unique identifier of the event.
*/
extern void trafficLightWaiting_unsetTimer(TrafficLightWaiting* handle, const sc_eventid evid);



#ifdef __cplusplus
}
#endif 

#endif /* TRAFFICLIGHTWAITINGREQUIRED_H_ */
/

Basically the proper time handling has to be implemented by the developer, because timer functions generally depend on the hardware target used. So for each hardware target the client code must provide a function to set a timer and another function to unset it. These functions have to be implemented externally and have to be linked to the generated code.

The following functions are dealing with timing functionality:

Function setTimer

A state machine calls the setTimer() function – short for the function’s full name like, e.g., void trafficLight_setTimer(TrafficLight* handle, const sc_eventid evid, const sc_integer time_ms, const sc_boolean periodic) – to tell the timer service that it has to start a timer for the given time event identifier and raise it after the period of time specified by the time_ms parameter has expired. It is important to only start a timer thread or a hardware timer interrupt within the setTimer() function and avoid any time-consuming operations like extensive computations, sleeping or waiting. Never call the statechart API functions from within these functions! Otherwise the state machine execution might hang within the timer service or might not show the expected runtime behavior.

In order to have the timer service raise the time event periodically, the parameter periodic must be true.

Function unsetTimer

The state machine calls the function trafficLight_unsetTimer(TrafficLight* handle, const sc_eventid evid) to notify the timer service to unset the timer for the given event ID.

Function raiseTimeEvent

In order to notify the state machine about the occurence of a time event after a period of time has expired, the raiseTimeEvent() function – defined in the header file of the state machine – needs to be called on the state machine. In the case of the traffic light example it is named trafficLight_raiseTimeEvent(const TrafficLight* handle, sc_eventid evid) (in file TrafficLight.h).

The time event is recognized by the state machine and will be processed during the next run cycle.

You can conclude that in order to process the time events raised by the timing service without too much latency, the runtime environment has to call the state machine’s runCycle() function as frequently as needed. Consider for example a time event which is raised by the timer service after 500 ms. However, if the runtime environment calls the state machine’s runCycle() function only once per 1000 ms, the event will quite likely not be processed at the correct points in time.

Operation callbacks

YAKINDU Statechart Tools support client code operations that can be called by a state machine and that are executed as actions. These operations have to be implemented in order to make a statechart executable. The figure below shows a sample statechart using an operation:

Specifying an operation callback in the model

Specifying an operation callback in the model

Let’s have a look at the generated code in DefaultSMRequired.h:


#ifndef DEFAULTSMREQUIRED_H_
#define DEFAULTSMREQUIRED_H_

#include "sc_types.h"
#include "DefaultSM.h"

#ifdef __cplusplus
extern "C"
{
#endif 

/*! \file This header defines prototypes for all functions that are required by the state machine implementation.

This state machine makes use of operations declared in the state machines interface or internal scopes. Thus the function prototypes:
	- defaultSMIfaceSample_myOperation
are defined.

These functions will be called during a 'run to completion step' (runCycle) of the statechart. 
There are some constraints that have to be considered for the implementation of these functions:
	- never call the statechart API functions from within these functions.
	- make sure that the execution time is as short as possible.
 
*/
extern sc_integer defaultSMIfaceSample_myOperation(DefaultSM* handle, const sc_integer p1, const sc_boolean p2);




#ifdef __cplusplus
}
#endif 

#endif /* DEFAULTSMREQUIRED_H_ */

An additional external function declaration sc_integer defaultSMIfaceSample_myOperation(DefaultSM* handle, const sc_integer p1, const sc_boolean p2) has been generated. This function has to be implemented and linked with the generated code, so that the state machine can use it.

Integrating generated code

To get a clue how to integrate a generated C state machine with your project, have a look at this main.c file and its main() function. Please note that the trafficLight_setTimer and trafficLight_unsetTimer functions are implemented here as well:

#include "org_yakindu_sct_examples_c_trafficlight.h"

#include "src-gen/sc_types.h"
#include "src-gen/TrafficLight.h"
#include "statemachine/TrafficLightTimer.h"
#include "statemachine/TrafficLightRunner.h"

TrafficLightTimer *timer;

int main(int argc, char *argv[]) {
    TrafficLight handle;
    trafficLight_init(&handle);
    timer = new TrafficLightTimer(&handle);
    trafficLight_enter(&handle);
    QApplication a(argc, argv);
    TrafficLightRunner *runner = new TrafficLightRunner(&handle, 100);
    org_yakindu_sct_examples_c_trafficlight w(0, runner);
    w.show();
    int ret = a.exec();
    return ret;
}

void trafficLight_setTimer(const sc_eventid evid,
        const sc_integer time_ms, const sc_boolean periodic) {
    timer->setTimer(evid, time_ms, periodic);
}

void trafficLight_unsetTimer(const sc_eventid evid) {
    timer->unsetTimer(evid);
}

First an instance of the statechart data structure is created and initialized by the trafficLight_init(&handle) function. The next step instantiates the timer. The class TrafficLightTimer represents an implementation of a timer service and uses the timer functionality of the Qt framework. The TrafficLightRunner is a runtime service that executes a run-to-completion step of the state machine every 100 ms. The runner class and the GUI are wired in the C++ class org_yakindu_sct_examples_c_trafficlight:

#include "org_yakindu_sct_examples_c_trafficlight.h"

org_yakindu_sct_examples_c_trafficlight::org_yakindu_sct_examples_c_trafficlight(
        QWidget *parent, TrafficLightRunner *runner) :
        QMainWindow(parent) {

    ui.setupUi(this);
    crossing = new CrossingWidget(this);

    trafficLight = new TrafficLightWidget(crossing);
    trafficLight->setGeometry(275, 75, 30, 90);

    pedestrianLight = new PedestrianLightWidget(crossing);
    pedestrianLight->setGeometry(50, 10, 70, 20);

    connect(runner, SIGNAL(cycleDone(TrafficLight*)), this, SLOT(update(TrafficLight*)));

    pedestrianReq = new QPushButton("pedestrian request", this);
    pedestrianReq->setGeometry(1, 365, 150, 30);
    connect(pedestrianReq, SIGNAL(released()), runner, SLOT(raisePedestrianRequest()));


    off = new QPushButton("off / on", this);
    off->setGeometry(249, 365, 150, 30);
    connect(off, SIGNAL(released()), runner, SLOT(raiseOnOff()));
}

void org_yakindu_sct_examples_c_trafficlight::update(
        TrafficLight *handle) {
    trafficLight->setSignals(handle-&gt;ifaceTrafficLight.red,
            handle->ifaceTrafficLight.yellow, handle->ifaceTrafficLight.green);
    pedestrianLight->setSignals(handle->ifacePedestrian.request,
            handle->ifacePedestrian.red, handle->ifacePedestrian.green);
    QMainWindow::update();
}

org_yakindu_sct_examples_c_trafficlight::~org_yakindu_sct_examples_c_trafficlight() {

}