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:
myobject.h:
class MyObject: public VimmsObject {
...
//object variables
TOutputString* outString;
TInputFloat* inFloat;
//variables controlled by properties
double maxVal,minVal;
int continueOnError;
...
public:
...
}
myobject.cpp:
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:
- TInputInteger
- TInputFloat
- TInputString
- TInputIntegerArray
- TInputFloatArray
For output
variables the corresponding classes exist:
- TOutputInteger
- TOutputFloat
- TOutputString
- TOutputIntegerArray
- TOutputFloatArray
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
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.
Back