Autogenerator usage

This page is about the usage of the QtIVI auto-generator.

Introduction

The Generator is a Python script that can be run manually or using the QMake Integration. This script uses QFace as the autogenerator framework which parses the IDL file, generates the domain-model (similar to AST) and then feeds it to the actual generator. Depending on the type of the generated project, different formats are specified.

Command line parameters

The generation is run using the following command:

$$[QT_HOST_BINS]/ivigenerator/generate.py --format=backend_simulator interface.qface out_dir

The options and parameters are:

--reload / --no-reload [optional]specifies whether the generator should keep track of the changes in the IDL file and update output on the fly (--no-reload by default)
-f, --format [frontend|backend_simulator|control_panel|<folder>]see below
--helpShow options and exit.
sourcePath or paths to the IDL source files. In case of multiple entries present, each one will be handled. In case a directory path is provided, it will be scanned for all the IDL files.
outputdirGeneration destination folder

At the moment the generator is able to generate 2 kinds of projects given an interface IDL file based on the --format option value. These are:

frontend Generates a developer facing API using base classes from qtivicore and the Dynamic Backend System
backend_simulator Generates a simulation backend for the API generated by the "frontend" option. This backend serves as a mock implementation.
control_panel Generates a controller application, consisting of an UI and a C++ plugin, which communicates to the simulation backend generated from the same qface file using QtSimulator.
folder pathUses templates inside the folder. A YAML file with the same name as the folder (and .yaml extension) should provide a list of template files in the folder (see YAML format specification below).

YAML configuration

The Python script is responsible for parsing the input files and for the creation of a domain model. This domain model is passed as a context to the Jinja template engine. To control which files are generated, the "Generation YAML" can be used. In addition, an "Annotations YAML" can be used to add more information to the IDL file, which are generator specific.

Generation YAML

After the domain model tree has been created, this tree is traversed and each leaf of the domain model object tree (module, interface, structure, etc) is passed to a specific Jinja template defined by the configuration file. This file must be in YAML format and for every particular generation format its name is defined in the script. This file must have the following structure:

generate_rules:
    module_rules:
        -   dest_file:  "{{module.module_name|lower}}plugin.h"
          template_file:  "plugin.h.tpl"
    interface_rules:
        -   dest_file: '{{interface|lower}}backend.h'
          template_file: 'backend.h.tpl'
    struct_rules:

For every entity there is a list of templates needed to be called when traversing this entity in the domain model tree. Here, dest_file is a name of the file need to be created specified in the Jinja template language format: the value of the object property used in the name template will be processed and substituted into the template, thus forming the final name of the file to create. dest_file is a name of the template to be used. For the IVI generator, rules for three kinds of entities need to be specified: modules, interfaces and structures.

Annotations YAML

At the moment not all aspects of the interface description cannot be expressed using the IDL itself. For instance there is no language construct to define default value for the property or values the property can take on. Still this can be achieved via a mechanism called Annotations. Annotations allow great freedom and flexibility of expressing any concepts and constructs.

Below is an example of using annotations in the IDL. Here it's defined that interface is zoned and its identifier is specified.

@config: {zoned: true, id: "org.qt-project.qtivi.ClimateControl/1.2" }

Not all of the annotations make sense to be put in the main IDL file either. For instance, one may need to define some aspects of generation of the auto-testing code. Such annotations can be put in the YAML file accompanying the main IDL file and named after it. During the parse phase QFace picks this file up automatically and merges annotation specified in this YAML file with those defined in the IDL file.

For QtIvi there are following annotations used for the IDL definition:

TagWhereObject typePurpose
@config(interfaceBuilder: "FunctionName")Main IDL fileModuleDeclares a function which will be called in the plugin to generate the instances for every interface. The function takes a pointer to the plugin instance and returns a QVector<QIviFeatureInterface *>. Interfaces should be generated in the same order as defined by Plugin::interfaces().

This can be used to instanciate classes derived from the generated plugin interfaces classes.

@config(zoned)Main IDL fileInterfacetells the generator whether the interface is zoned or not. This allows to define whether the backend feature interface is derived from QIviZonedFeatureInterface or from QIviFeatureInterface
@config(id=org.qt.project.qtivi.ClimateControl.1.0)Main IDL fileInterfacedefines the interface id. The id is a string used by the QtIvi service manager to glue frontend interface and backend implementation together. See Dynamic Backend System for more details.
@config(getter_name)Main IDL filePropertyOverrides the default getter method name. Useful for boolean properties (for example, getter for property 'enabled', should be 'isEnabled' rather than the default).
@config(setter_name)Main IDL filePropertyOverrides the default setter method name.
@config(qml_name)Main IDL fileModule, InterfaceDefines the name this interface/module should be using in QML. For interfaces, it is the name which is used to export the interface to QML. For modules it defines the uri of the complete module.

The annotations that are not logically part of the interface description but rather the ones used for specifying additional information are put in the accompanying YAML file. Here is the list of annotations used for defining various aspects of the generation of the backend-simulator:

TagWhereObject typePurpose
config_simulator:
     zones: { left : FrontLeft, right : FrontRight, rear: Rear }
Accompanying YAML fileInterfaceFor the backend simulator defines a list of zones supported by the simulation code with their names
config_simulator:
default: AirflowDirection.Floor | AirflowDirection.Dashboard
Accompanying YAML filePropertyDefines the initial values for the property returned by the simulator backend.

For zoned properties a mapping from a zone to a default value can be used. The default key of the map is "=".

config_simulator:
default: { left: 21.0, right: 22.5, =: 0.0 }
config_simulator:
minimum: 10
Accompanying YAML filePropertyDefines the minimum value for integer and real properties, generated code in the simulator backend will check for validity.
config_simulator:
maximum: 10
Accompanying YAML filePropertyDefines the maximum value for integer and real properties, generated code in the simulator backend will check for validity.
config_simulator:
range: [10, 20]
Accompanying YAML filePropertyDefines the range value for integer and real properties, generated code in the simulator backend will check for validity.
config_simulator:
domain: {10, 20, 30}
Accompanying YAML filePropertyDefines the possible values for the property, generated code in the simulator backend will check for validity.

Generated projects structure

In the generator output directory first a new subfolder with the name of the module id will be created. All the generated files will be put in this folder. The following files will be generated:

Frontend

File namePurpose
"{{module.module_name|lower}}global.h"Standard file with global EXPORT defines
"{{module.module_name|lower}}module.h/cpp"Files defining a module class used for module global variables and types.
"{{module|lower|replace('.', '-')}}.pri"Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project.
"{{interface|lower}}backendinterface.h/cpp"Files defining the interface need to be implemented by the backend implementation of the feature
"{{interface|lower}}.h/cpp"Front end implementation of the feature, ready to be used from QML.
"{{interface|lower}}_p.h"Private part of the frontend implementation

Backend simulator

File namePurpose
"{{module.module_name|lower}}plugin.h/cpp"Files defining implementation of QtIvi backend plugin implementing QIviServiceInterface
"{{module.module_name|lower}}.json"File containing identifiers of the exposed feature interfaces needed by the Qt plugin system.
"{{module|lower|replace('.', '-')}}.pri"Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project.
"{{interface|lower}}backend.h/cpp"Files containing the implementation of the simulation backend.

Control Panel

The control_panel template is only available if the QtSimulator module was found. Please see the Configuration Page for more information.

File namePurpose
"main.cpp"Launcher code loading the QML code and exporting the C++ interface.
"main.qml"Main QML file containing the code to load the Control UIs for every interface.
"qml.qrc"QRC file for all QML code.
"FlagControl.qml"UI Element to control a flag inside a interface.
"EnumControl.qml"UI Element to control a enum inside a interface.
"{{module|lower|replace('.', '-')}}.pri"Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project.
"{{module.module_name|lower}}global.h"Standard file with global EXPORT defines
"{{module.module_name|lower}}module.h/cpp"Files defining a module class used for module global variables and types.
"{{interface|lower}}.h/cpp"C++ code retrieving and forwarding the state using QtSimulator.
"{{module.module_name|lower}}ControlUi.qml"Control UI for this interface. Contains a interface to control every property and method and log calls to signals.

© 2018 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.