Skip to content

ParameterGenerator

Alexander Pimenov edited this page Jan 7, 2019 · 6 revisions

ParameterGenerator

-> Motivation

Parameter generator is a code generation tool that simplifies the manipulation with code. In many places plain data objects are used.

Let's have a look how parameters are transfered from ui to execution:

  1. First Ui notifies ui thread about changes in parameters with a signal
  2. Ui thread gets data from ui and packs it into data structure
  3. Several data structures are then repacked to form the data block for calculation thread
  4. This data structure is transfered to Calculation Thread and accepted ans used there.
  5. Most probably Calculation Thread will call some Сore code with the same parameters.

If one wants to change or add one parameter he will have to change a lot of places. To aviod this we will have to generate either Ui form parameter class of vica versa.

Similar tools to look at (Could happen it will be enough)

  1. Autogen - http://www.gnu.org/software/autogen/

-> Plain objects generator

This generator is able to generate complicated classes for plain objects (POCO as analog - http://en.wikipedia.org/wiki/Plain_Old_Java_Object). It allows the following features:

  1. Getters and setters
  2. Trivial Constructors
  3. Visitor pattern
  4. Reflection
  5. Stream and console printing
  6. Aggregation

-> Generator work flow

  1. Generator reads config file and searches for a variety of descriptions of the poco objects
  2. Reads the POCO structures descriptions constructed from fields, see below.
  3. Checks structure integrity, for all referenced classes to be defined.
  4. Consults config to see what outputs should be generated
  5. Generates the output

--> Fields

We want to support so far 3 types of fields:

  1. Simple data fields that have Qt Ui directly corresponding to them
    • Boolean field (QCheckBox and QRadioButton)
    • Integer field (QSpinBox)
    • Double field (QDoubleSpinBox)
    • Integer (enum) field (QComboBox)
    • String field (QLineEdit)
    • Collections (!)
  2. Common Data types from core 1.1. Vector2dd 1.1. Vector3dd
  3. Other POCO object fields

Let's for example have a look at integer field. This type of field is predefined. This type of field has predefined a corresponding ui - QSpinBox It also has some properties.

  1. Name
  2. Minimum value
  3. Maximum value
  4. Default value
  5. Comment (corresponds to tooltip in Widget)

Same for double field.

For boolean or string field:

  1. Name
  2. Default value
  3. Widget type (QCheckBox or QRadioButton). If omitted, QCheckBox is used.
  4. Comment (corresponds to tooltip in Widget)

Enum field has also list of specific names and comments for the enum elements

--> Parameters generator sources

There are several sources of the plain object data information

---> *.ui Input

The plain object can be generated form the qt .ui file (not implemented yet)

---> Plain text Input

Some simple form for very simple primitive classes (not implemented yet)

---> *.xml Input

We can generate this class form the simple xml description All we need is a name of class and the list of the fields, for each of them we need its type and its default value. For example the following XML can be used




  
  

  
    
    
    
    
  

  
    
    
  


  
    
    
    
    
    

    
    
  
    
    

    
    

    
    
   

   
    
    
    
   

---> Mapping formats

As you can see sometimes it is possible to include one class fields into the other, also it is possible to rename the fields and exclude some of them




 
    
    
 

 
    
      
    

    
      
    


    
    
      
    

    
    
      
      
    

  

--> Possible outputs

---> Simple C class

POCO objects can appear as a result of config file processing as in current implementation of paramGenerator

Class can optionally switch on and off

  1. Default constructor
  2. getters/setters vs. public fields

    Example()
    {
       DefaultSetter setter;
       accept(setter);
    }

---> OpenGL style accessors

This type accessors are for easy interfacing other languages without overloading functions and exposing all parameters in runtime.


    enum ParameterId {
       PARAMETER_INT_FIELD, 
       PARAMETER_DOUBLE_FIELD, 
       PARAMETER_BOOL_FIELD, 
    };

    bool setParameteri(ParameterId parameterName, int value);

    bool setParameterd(ParameterId parameterName, double value);

    int getParameteri(ParameterId parameterName);

    double getParameterd(ParameterId parameterName);

---> Сlass with reflection

Each class stores a static list of the fields with corresponding properties ParameterGenerator#--Fields and some properties dependent on the generated class such as the offset to the field. Reflection allows to have better visitor classes giving them the ability to serialize into the binary formats

/tools/generatorConcept/reflection.h

---> Qt Ui

This example is in template format ParameterGenerator#- Patterns



$forall fields {



 
    
    20
    ${number}
    70
    17
    
 
  
    ${name}
  




  
    
    140
    ${number}
    58
    23
    
  
 
    ${comment}
  


}

-> Patterns

Generator will change it's way of code generation. Before that it used сout to generate code. It was an ugly way, because the generated code structure was obscure. Now we propose the way that is similar to the HTML is generated - (http://en.wikipedia.org/wiki/Template_engine_%28web%29) It's not necessary to make templates as separate strings, it's just about simplifying the understanding of what is currently generated

See example below:

${variable}@uc - variable in uppercase

${variable}@cc - variable in camelCase

"|" symbol meens align the position in cycle

class Example
{
public:
    /* Section with default values */
    $forall fields {const static ${type} |${name}@uc_DEFAULT = |${defaultValue}; }

    /* Section with fields names */
    $forall fields {const static char * |${name}@uc_NAME; }

    /* Section with variables */
    $forall fields {
        // ${comment}
        ${type} m${name}@cc;
    }

    /* Section with getters */
    $forall fields {
       ${type} get${name}@cc() const 
       {
           return m${name}@cc;
       }
    }

    /* Section with setters */
    $forall fields {
       void get${name}@cc( const ${type} &value) 
       {
           m${name}@cc = value;
       }
    }

    /* visitor pattern */
template
    void accept(VisitorType &visitor)
    {
      $forall fields {
        visitor.visit(m${name}@cc,    ${name}@uc_DEFAULT    , ${name}@uc_NAME);
      }
    }
};

-> Visitors

As you can see above we have several default visitors.

  1. Default setter
  2. Stream printer
  3. QSettings getter and setter
  4. XML getter and setter

class DefaultSetter
{
public:
    void visit(int &intField, int defaultValue, const char */*fieldName*/)
    {
        intField = defaultValue;
    };

    void visit(double &doubleField, double defaultValue, const char */*fieldName*/)
    {
        doubleField = defaultValue;
    };

    void visit(bool &boolField, bool defaultValue, const char * /*fieldName*/)
    {
        boolField = defaultValue;
    };
};

class PrinterVisitor
{
public:
    ostream &out;
    PrinterVisitor(ostream &_out) : out(_out) {}

    void visit(int &intField, int /* defaultValue */, const char *fieldName)
    {
        out << fieldName << " = " << intField << endl;
    };

    void visit(double &doubleField, double /* defaultValue */, const char *fieldName)
    {
        out << fieldName << " = " << doubleField << endl;
    };

    void visit(bool &boolField, bool /* defaultValue */, const char *fieldName)
    {
        out << fieldName << " = " << boolField << endl;
    };

};

-> Unsolved problems

  1. Visitors design is overcomplicated, writer visitor don't need default field.
  2. Signals and slots so far are not clear

Clone this wiki locally