Using Input / Output Variables and Properties

This pages gives an overview of the object variable interface defined in the header file vimmsvar.h. We start with a small example which shows how to define and use variables and properties:


class MyObject: public VimmsObject { ... //object variables TOutputString* outString; TInputFloat* inFloat; //variables controlled by properties double maxVal,minVal; int continueOnError; ... public: ... }


QString choices[2] = {"Continue","Don't continue"}; void MyObject::CreateVars(int /*version*/) { (inFloat = new TInputFloat("Input"))->InsertInto(InputVars); (outString = new TOutputString("Text"))->InsertInto(OutputVars); (new TFloatProperty("Max. value",this,maxVal))->InsertInto(Properties); (new TFloatProperty("Min. value",this,minVal))->InsertInto(Properties); (new TChoiceProperty("Cont. on error",this,continueOnError,choices,2))->InsertInto(Properties); } bool MyObject::WantData() { if (inFloat->HasData()) { double value = inFloat->GetData(); if (value <= maxVal && value >= minVal) { char s[25]; sprintf(s,"%f",value); outString->SetData(s,strlen(s)); return true; } } outString->ClearData(); return (continueOnError == 0); } Here we see the definition example of one input and one output variable as well as three properties. Input and output variables should be defined in the header file as pointers TOutput... and TInput... classes. The properties are defined like normal C variables. Their contents is edited via the property dialogs and stored within the Vimms project files. For most properties an input variable is created automatically. For choice properties no input variable is created, so that their value can only be changed via the property dialogs.

The version parameter of the function CreateVars() normally contains the version number that is returned by the function GetCurrentVersion() which is defined in the highest base class TPersistObject. It can be used to detect whether reading an old project file with an older version of the object is read in.

In the function WantData() accessing the variables is demonstrated: First it is checked whether the input variable has data. If it has and it is between a minimum and maximum value, it is converted into a string which is passed to the output variable outString. If the value was not converted, depending on the property continueOnError is zero or not, which means the user has choosen "Continue" or "Don't continue" in the property dialog, execution is continued or stopped at this object.

Defining Input / Output Variables

There exist 5 different data types for input and output variables. The classes for input variables are: For output variables the corresponding classes exist: They all are created in the same way like shown in the example: The constructors take one single argument, the name of the variable as it appears in the property dialogs. Each variable must be inserted into the corresponding VimmsList: InputVars for input variables and OutputVars for output variables.

Accessing data from input variables

Input variables should only be used from within the function WantData() which performs the object's standard action or other user defined actions. All input variable classes are derived from the class TInputVarBase which provides the following functions for checking variable status:
bool HasData()
This function returns true if the input variable is connected to another object's output variable and the output variable has been assigned some data. It returns false if the input variable is not connected or there is no data in the connected output variable.
bool Connected()
Returns true if the input variable is connected to the output variable of another object. The output variable needs not to have data.
TVarType GetType()
Returns the type of the variable, as defined in vflcalc.h
Getting the data of input variables is different for array-like variables like TInputString, TInputIntegerArray, TInputFloatArray and scalar-like variables TInputInteger and TInputFloat.

For scalar-like variables use the member function GetData() which returns a double or an integer depending on the variable type.

For array-like variables use GetData(int& len) which returns a pointer to an array corresponding to the variable type and passes the length of the returned array in the len parameter. The TInputString variable returns a char array, TInputIntegerArray returns an int array and TInputFloatArray returns a double array. For TInputFloatArray for example the GetData() function is defined in the following way:

double* TInputFloatArray::GetData(int& len) The returned arrays must be deleted after use, using delete[]. Otherwise memory resource leaks would occur. The returned arrays may be changed by the object as they are only copies of the real return values.

If data is accessed from variables whose HasData() function returns false, scalar variables return the data type's default value (normally 0) and array variables return a zero pointer, the length parameter is undefined.

Setting data of output variables

Like input variables, output variable should also only be used from within WantData() or other user defined actions. They are derived from the base class TOutputVariableBase. Here are functions common to all output variables:
TVarType GetType()
Returns the type of the output variable, as defined in vflcalc.h
void ClearData()
Clears the data which has been set to the output variable. If you want to ensure that an output variable contains no data you should clear it using this function. All output variables are automatically initialized and cleared at program start.
Like with input variables, setting data of output variables is different for array-like and scalar-like variables. For TOutputInteger and TOutputFloat use the functions SetData(int value) and SetData(double value) respectively.

For setting data of array-like output variables TOutputString, TOutputIntegerArray and TOutputFloatArray use the functions void SetData(const char* data,int len), void SetData(const int* data,int len) and void SetData(const double* data,int len). The data arrays are copied internally.

Unlike with normal char array strings in C which are zero terminated, the TOutputString and TInputString variables can handle binary data which also can contain zeros.


Properties differ from normal input variables: They can automatically create input variables and set internal C variables defined in the object's class and automatically create a line in the object's default property dialog. Normally properties are only defined and the rest is done automatically. As shown in the example above the property pointer itself needs not to be stored in a separate variable. All properties are derived from the base class TObjectProperty, they are defined in properties.h. All property constructors require a name as the first parameter, a pointer to the current VimmsObject (normally this), and a reference to the class variable that should contain propertie's data. This variable must be a member of the VimmsObject's class. Variables that are passed to a propertie's constructor are automatically stored within the vimms project file and restored when the object is recreated from the file. Most properties also have parameters repaint, createVar and refill The parameter repaint should normally be set to false; if it is set to true, the layout screen is repainted if the variable is changed within the property dialog. This is only useful if the contents of the variable is used for painting the object icon or drawing the object's title. If createVar is set to false, no input variable is created for the property. This is useful if the variable contents shouldn't be changed during runtime. An example for this is the object's title. The parameter refill should always be false. The following predifined property constructors exist:
TStringProperty(const QString& name, VimmsObject* parent, QString& s, bool repaint = false, bool createVar = true, bool refill = false)
This creates a string property for the class variable s.
TIntegerProperty(const QString& name,VimmsObject* parent,int& i, int amin = INT_MIN,int amax = INT_MAX,bool repaint = false, bool createVar = true, bool refill = false)
This creates an integer property for the class variable i. Maximal and minimal value of this variable can be specified with amin and amax parameters. These are checked for if the properties value is changed within the property dialog. These are not checked during runtime.
TFloatProperty(const QString& name,VimmsObject* parent,double& d, double amin = -DBL_MAX,double amax = DBL_MAX,int decimals=5,bool repaint = false, bool createVar = true, bool refill = false)
This creates a float property for the class variable d. Maximal and minimal value of this variable can be specified with amin and amax parameters. These are checked for if the properties value is changed within the property dialog. These are not checked during runtime. The number of decimals shown in the property dialog can be specified with decimals.
TChoiceProperty(const QString& name,VimmsObject* parent,int& i,const QString* chs,int ccount,bool repaint = false,bool refill = false)
This creates a property for the integer class variable i. In the property dialog a drop down listbox is displayed allowing the user to choose between predefined values. The number of predifined values is specified via ccount and the text for each value is passed as an QString-Array chs with as many elements as specified by ccount. The index of the choosen value (starting with zero) is stored in the class variable i. This property never creates an input variable.
TFontProperty(const QString& name, VimmsObject* parent, QFont& afont, bool repaint = false)
This property allows the user to choose a font from withing the property dialog, which is stored in the class variable QFont.
There is one application where one wants to access the property also after creation: To determine whether the property has been changed via the associated input variable. For this to work, the properties TStringProperty, TIntegerProperty and TFloatProperty all have an element function getInputVar() which returns the input variable that has been automatically created by the property. Using the input variable's element function HasData() it can be found out whether a new value has been stored in the corresponding class variable.


The Vimms User Manual