/**************************************************************************** ** ** Copyright (C) 2018 Pelagicore AG ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the QtIvi module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL-QTAS$ ** Commercial License Usage ** Licensees holding valid commercial Qt Automotive Suite licenses may use ** this file in accordance with the commercial license agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and The Qt Company. For ** licensing terms and conditions see https://www.qt.io/terms-conditions. ** For further information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free ** Documentation License version 1.3 as published by the Free Software ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \page generator-usage.html \title Autogenerator usage \previouspage Jinja template syntax \nextpage Filter Reference This page is about the usage of the QtIVI auto-generator. \section1 Introduction The Generator is a Python script that can be run manually or using the \l {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 \e{formats} are specified. \section1 Command line parameters The generation is run using the following command: \code $$[QT_HOST_BINS]/ivigenerator/generate.py --format=backend_simulator interface.qface out_dir \endcode The options and parameters are: \table \row \li --reload / --no-reload [optional] \li specifies whether the generator should keep track of the changes in the IDL file and update output on the fly (--no-reload by default) \row \li -f, --format [frontend|backend_simulator|control_panel|backend_qtro|server_qtro|] \li see below \row \li --help \li Show options and exit. \row \li source \li Path 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. \row \li outputdir \li Generation destination folder \endtable At the moment the generator is able to generate 5 kinds of projects given an interface IDL file based on the \e {--format} option value. These are: \table \row \li \l {frontend} \target frontend-template \li Generates a developer facing API using base classes from qtivicore and the \l {Dynamic Backend System} \row \li \l {Backend Simulator} {backend_simulator} \target backend-simulator-template \li Generates a simulation backend for the API generated by the "frontend" option. This backend serves as a mock implementation. \row \li \l {Control Panel} {control_panel} \target control-panel-template \li 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. \row \li \l {QtRemoteObjects Backend} {backend_qtro} \target backend-qtro-template \li Generates a QtRemoteObjects based backend client for the API generated by the "frontend" option. This backend connects to a backend server. \row \li \l {QtRemoteObjects Server} {server_qtro} \target server-qtro-template \li Generates a QtRemoteObjects based backend server stub for the API generated by the "frontend" option. \row \li folder path \li Uses 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). \endtable \section1 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. \section2 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: \code 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: \endcode For every entity there is a list of templates needed to be called when traversing this entity in the domain model tree. Here, \e{dest_file} is a name of the file need to be created specified in the \l {Jinja template syntax}{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. \e{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. \section2 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 \l {annotations_reference} {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. \code @config: {zoned: true, id: "org.qt-project.qtivi.ClimateControl/1.2" } \endcode 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: \table \header \li Tag \li Where \li Object type \li Purpose \row \li @config(interfaceBuilder: "FunctionName") \li Main IDL file \li Module \li Declares 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 \c {QVector}. Interfaces should be generated in the same order as defined by \c {Plugin::interfaces()}. This can be used to instanciate classes derived from the generated plugin interfaces classes. \row \li @config(zoned) \li Main IDL file \li Interface \li tells 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 \row \li @config(id=org.qt.project.qtivi.ClimateControl.1.0) \li Main IDL file \li Interface \li defines the interface id. The id is a string used by the QtIvi service manager to glue frontend interface and backend implementation together. See \l {Dynamic Backend System} for more details. \row \li @config(getter_name) \li Main IDL file \li Property \li Overrides the default getter method name. Useful for boolean properties (for example, getter for property 'enabled', should be 'isEnabled' rather than the default). \row \li @config(setter_name) \li Main IDL file \li Property \li Overrides the default setter method name. \row \li @config(qml_name) \li Main IDL file \li Module, Interface \li Defines 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. \endtable 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: \table \header \li Tag \li Where \li Object type \li Purpose \row \li \code config_simulator: zones: { left : FrontLeft, right : FrontRight, rear: Rear } \endcode \li Accompanying YAML file \li Interface \li For the backend simulator defines a list of zones supported by the simulation code with their names \row \li \code config_simulator: default: AirflowDirection.Floor | AirflowDirection.Dashboard \endcode \li Accompanying YAML file \li Property \li Defines 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 "=". \code config_simulator: default: { left: 21.0, right: 22.5, =: 0.0 } \endcode \row \li \code config_simulator: minimum: 10 \endcode \li Accompanying YAML file \li Property \li Defines the minimum value for integer and real properties, generated code in the simulator backend will check for validity. \row \li \code config_simulator: maximum: 10 \endcode \li Accompanying YAML file \li Property \li Defines the maximum value for integer and real properties, generated code in the simulator backend will check for validity. \row \li \code config_simulator: range: [10, 20] \endcode \li Accompanying YAML file \li Property \li Defines the range value for integer and real properties, generated code in the simulator backend will check for validity. \row \li \code config_simulator: domain: {10, 20, 30} \endcode \li Accompanying YAML file \li Property \li Defines the possible values for the property, generated code in the simulator backend will check for validity. \endtable \section1 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: \section2 Frontend \table \header \li File name \li Purpose \row \li "{{module.module_name|lower}}global.h" \li Standard file with global EXPORT defines \row \li "{{module.module_name|lower}}module.h/cpp" \li Files defining a module class used for module global variables and types. \row \li "{{module|lower|replace('.', '-')}}.pri" \li Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project. \row \li "{{interface|lower}}backendinterface.h/cpp" \li Files defining the interface need to be implemented by the backend implementation of the feature \row \li "{{interface|lower}}.h/cpp" \li Front end implementation of the feature, ready to be used from QML. \row \li "{{interface|lower}}_p.h" \li Private part of the frontend implementation \endtable \section2 Backend simulator \table \header \li File name \li Purpose \row \li "{{module.module_name|lower}}plugin.h/cpp" \li Files defining implementation of QtIvi backend plugin implementing QIviServiceInterface \row \li "{{module.module_name|lower}}.json" \li File containing identifiers of the exposed feature interfaces needed by the Qt plugin system. \row \li "{{module|lower|replace('.', '-')}}.pri" \li Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project. \row \li "{{interface|lower}}backend.h/cpp" \li Files containing the implementation of the simulation backend. \endtable \section2 Control Panel The control_panel template is only available if the QtSimulator module was found. Please see the \l{feature-qtsimulator}{Configuration Page} for more information. \table \header \li File name \li Purpose \row \li "main.cpp" \li Launcher code loading the QML code and exporting the C++ interface. \row \li "main.qml" \li Main QML file containing the code to load the Control UIs for every interface. \row \li "qml.qrc" \li QRC file for all QML code. \row \li "FlagControl.qml" \li UI Element to control a flag inside a interface. \row \li "EnumControl.qml" \li UI Element to control a enum inside a interface. \row \li "{{module|lower|replace('.', '-')}}.pri" \li Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project. \row \li "{{module.module_name|lower}}global.h" \li Standard file with global EXPORT defines \row \li "{{module.module_name|lower}}module.h/cpp" \li Files defining a module class used for module global variables and types. \row \li "{{interface|lower}}.h/cpp" \li C++ code retrieving and forwarding the state using QtSimulator. \row \li "{{module.module_name|lower}}ControlUi.qml" \li Control UI for this interface. Contains a interface to control every property and method and log calls to signals. \endtable \section2 QtRemoteObjects Backend The backend_qtro template is only available if the QtRemoteObjects module was found. Despite the name, the remote object backend is not the location for the implementation of the actual backend logic, but just a client for connecting to the remote backend server. \table \header \li File name \li Purpose \row \li "{{module.module_name|lower}}plugin.h/cpp" \li Files defining implementation of QtIvi backend plugin implementing QIviServiceInterface \row \li "{{module.module_name|lower}}.json" \li File containing identifiers of the exposed feature interfaces needed by the Qt plugin system. \row \li "{{module|lower|replace('.', '-')}}.pri" \li Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project. Also adds the .rep file to the project and calls the remote object compiler. \row \li "{{interface|lower}}backend.h/cpp" \li Files containing the implementation of the remote object backend. Establishes the connection and initializes the remote object replica. \row \li "{{interface|lower}}.rep" \li The input file for Qt’s \l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} for producing the replica class code. \endtable \section2 QtRemoteObjects server The server_qtro template is only available if the QtRemoteObjects module was found. The produced code contains merely the source classes to inherit and code for establishing the connection. It is up to the developer to implement the actual backend logic. \table \header \li File name \li Purpose \row \li "core.h/cpp" \li Code for establishing the connection and starting the remoting for the source objects. \row \li "{{srcBase|lower}}.pri" \li Standard Qt .pri file, containing all the generated files that can be used for including the autogenerated files into a qmake project. Also includes the .rep file to the project and calls the remote object compiler. \row \li "{{interface|lower}}.rep" \li The input file for the Qt’s \l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} for producing the source class code. \endtable */