[programmer/prog-setup.tex]
\label{prog_setup}
\section{Parameter class}
\label{prog_setup_parameter}
Configuration and status information of objects can be represented by the \class{Parameter} class.
Any object derived from \class{Worker} class
(e.~g.~ \class{Application}, \class{Device}, \class{Module}, and \class{Port})
can have a list of parameters assigned to it.
There are a number of \class{Worker} methods to create parameter objects of different kinds and access their values.
These are shown in the following table:
\begin{tabular}{|l|l|lll|}
\hline
Type & Class & Create & Getter & Setter \\
\hline
string & StrParameter & CreateParStr() & GetParStr() & SetParStr () \\
double & DoubleParameter & CreateParDouble() & GetParDouble() & SetParDouble() \\
int & IntParameter & CreateParInt() & GetParInt() & SetParInt() \\
bool & StrParameter & CreateParBool() & GetParBool() & SetParBool() \\
\hline
\end{tabular}
The \func{CreatePar...()} methods will internally create a new
\class{Parameter} of the specified name if it does not exist before.
For any type of parameter the \func{GetParStr()} and \func{SetParStr()} methods can be used
which will deliver the parameter value as text string expression.
As one can see, to represent a boolean value a string parameter is used.
If text of string is "true" (in lower case),
the boolean value is recognized as \keyw{true},
otherwise as \keyw{false}.
It is recommended to use these \class{Worker} methods to create parameters and access their values;
but one can also use \func{Par()} method to find any parameter object
and use its methods directly.
\section{Use parameter for control}
\label{prog_setup_parametercontrol}
One advantage of the \dabc~ parameter objects is that parameter values can be
observed and changed by a control system.
When a parameter value is changed in the program by a \func{SetPar...} method,
the control system is informed and represents such change in an appropriate GUI element.
On the other hand, if the user modifies a parameter value in the GUI,
the value of the parameter object will be changed and the corresponding parent object
(\class{Module}, \class{Device}) gets a callback via
virtual method \func{ParameterChanged() [obsolete] }.
By implementing a suitable reaction in this call,
one could reconfigure or adjust the running program on the fly.
A parameter object may be "fixed" via \func{Parameter::SetFixed()} method.
This disables possibility to change the parameter value, both
from the program and the control/configuration system side.
Only when the "fixed" flag is reset to \keyw{false},
the parameter can be modified again.
Not all parameters objects should be visible to the control system.
Each parameter has a \strong{visibility flag}
which is assigned to the parameter instance when it is created.
Only when \func{Parameter::IsVisible()} returns \keyw{true}, parameter will be
known (visible) to the control system. Even if parameter is seen
from control system, it only can be changed \strong{from} control system
when flag \func{Parameter::IsChangable()} returns \keyw{true}.
\section{Example of parameters usage}
\label{prog_setup_parameterexample}
Let's consider an example of a module which uses parameters:
\begin{verbatim}
class UserModule : public dabc::ModuleAsync {
public:
UserModule(const char* name, dabc::Command* cmd = 0) :
dabc::ModuleAsync(name, cmd)
{
CreatePar("Output").DfltBool(true);
CreatePar("Counter").DfltInt(0);
CreateTimer("Timer", 1.0, false);
}
virtual void ProcessTimerEvent(unsigned timer)
{
Par("Counter").SetInt(Par("Counter").AsInt()+1);
if (Par("Output").AsBool())
DOUT1("Counter = %d", Par("Counter").AsInt());
}
};
\end{verbatim}
In the module constructor two parameters are created - boolean and integer,
and a timer with $1\mbox{~s}$ period.
When the module is started, the value of integer parameter "Counter"
will be changed every second.
If boolean parameter "Output" is set to \keyw{true},
the counter value will be displayed on debug output.
Using a control system, the value of the boolean parameter can be changed.
To detect and react on such change,
one should implement following method:
\begin{verbatim}
virtual void ParameterChanged(dabc::Parameter* par)
{
if (par->IsName("Output"))
DOUT1("Output flag changed to %s", DBOOL(GetParBool("Output");
}
\end{verbatim}
For performance reasons one should avoid to use parameter getter/setter methods
(like \func{GetParBool()} or \func{SetParInt()}) inside a loop
being executed many times. The main purpose of a parameter
object is to provide a connection to the control and configuration system.
In other situations simple class members should be used.
\section{Configuration parameters}
\label{prog_setup_configurationparameter}
Another use case of parameters consists in the object configuration.
When one creates an object, like a module or a device,
it is often necessary to deliver one or several configuration values
to the constructor, e.~g.~ the required
number of input ports, or a server socket port number.
For such situation configuration parameter are defined.
These parameters should be created and set
in the object constructor with following methods only:
\bdes
\item[GetCfgStr] string
\item[GetCfgDouble] double
\item[GetCfgInt] integer
\item[GetCfgBool] boolean
\edes
All these methods have following arguments: the parameter name,
a default value [optional], and a pointer to a \class{Command} object [optional].
Let's add one configuration parameter to our module constructor:
\begin{small}
\begin{verbatim}
UserModule(const char* name, dabc::Command* cmd = 0) :
dabc::ModuleAsync(name, cmd)
{
CreatePar("Output").DfltBool(true);
CreatePar("Counter").DfltInt(0);
double period = Cfg("Period", cmd).AsDouble(1.);
CreateTimer("Timer", period, false);
}
\end{verbatim}
\end{small}
Here the period of the timer is set via configuration parameter "Period".
How will its value be defined?
First of all, it will be checked if a parameter of that name exists in command
\func{cmd}. If not, the appropriate entry will be searched in the \dabc\ setup file,
as discussed in Section \paref{user-setup} of the \dabc\ user manual.
If the configuration file also does not contain such parameter,
the specified default value $1.0$ will be used.
% \section{Configuration file example}
% \label{prog_setup_configfile}
% The configuration file is an XML file in a \dabc-specific format,
% which contains values for some or all configuration parameters of the system.
%
% Let's consider this simple but functional configuration file:
%
% \begin{small}
% \begin{verbatim}
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
% \end{verbatim}
% \end{small}
%
% This is an example XML file for an MBS generator, which produces
% MBS events and provides them to an {\em MBS transport} server.
% To run that example, just "run.sh test.xml" should be executed in a shell.
% Other applications
% (\dabc~ or {\em Go4}) can connect to that server and read generated mbs events.
%
%
% \section{Basic syntax}
% \label{prog_setup_configfile_syntax}
% A \dabc~ configuration file should always contain as root node.
% Inside the node one or several nodes should exists.
% Each node represents the {\em application context} which runs as
% independent executable.
% Optionally the node can have and nodes,
% which are described further in the following sections \ref{prog_setup_configfile_variables}
% and \ref{prog_setup_configfile_defaults}
%
%
% \section{Context}
% \label{prog_setup_configfile_context}
% A node can have two optional attributes:
% \bdes
% \item["host"] host name, where executable should run, default is "localhost"
% \item["name"] application (manager), default is the host name.
% \edes
%
% Inside a node configuration parameters for modules, devices, memory pools are
% contained.
% In the example file one sees several parameters for the output port of
% the generator module.
%
%
% \section{Run arguments}
% \label{prog_setup_configfile_run}
% Usually a node has a subnode, where the user may define different parameters, relevant for running the \dabc~ executable:
%
% \bdes
% \item[lib] name of a library which should be loaded. Several libraries can be specified.
% \item[func] name of a function which should be called to create modules.
% This is an alternative to instantiating a subclass of \class{dabc::Application}
% (compare section \ref{prog_plugin_applicaton})
% \item[runfunc] function name to run some sequence of operations (start, stop, reconfigure) over application. Useful
% for batch mode
% \item[port] ssh port number of remote host
% \item[user] account name to be used for ssh (login without password should be possible)
% \item[init] init script, which should be called before dabc application starts
% \item[test] test script, which is called when test sequence is run by run.sh script
% \item[timeout] ssh timeout
% \item[debugger] argument to run with a debugger. Value should be like "gdb -x run.txt --args", where file run.txt should contain commands "r bt q". Special value "true" starts gdb with prepared commands list, "false" disables debugger.
% \item[workdir] directory where \dabc~ executable should start
% \item[debuglevel] level of debug output on console, default 1
% \item[logfile] filename for log output, default none
% \item[loglevel] level of log output to file, default 2
% \item[DIM\_DNS\_NODE] node name of DIM dns server, used by DIM controls implementation
% \item[DIM\_DNS\_PORT] port number of DIM dns server, used by DIM controls implementation
% \item[cpuinfo] instantiate \class{dabc::CpuInfoModule} to show CPU and memory usage information.
% Value must be >= 0. If 0, only two parameters are created, if 15 - several ratemeters will be created.
% \edes
%
%
% \section{Variables}
% \label{prog_setup_configfile_variables}
% In the root node one can insert a node which may contain
% definitions of one or several variables. Once defined,
% such variables can be used in any place of the configuration file to set parameter values.
% In this case the syntax to set a parameter is:
%
% \begin{small}
% \begin{verbatim}
%
% \end{verbatim}
% \end{small}
%
% It is allowed to define a variable as a combination of text with another variable,
% but neither arithmetic nor string operations are supported.
%
% Using variables, one can modify the example in the following way:
%
% \begin{small}
% \begin{verbatim}
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
% \end{verbatim}
% \end{small}
%
% Here context name and module name are set via {\tt myname} variable,
% and mbs server socket port is set via {\tt myport} variable.
%
% There are several variables which are predefined by the configuration system:
%
% \bbul
% \item DABCSYS - top directory of \dabc~ installation
% \item DABCUSERDIR - user-specified directory
% \item DABCWORKDIR - current working directory
% \item DABCNUMNODES - number of nodes in configuration files
% \item DABCNODEID - sequence number of current node in configuration file
% \ebul
%
% Any shell environment variable
% is also available as variable in the configuration file to set parameter values.
%
%
% \section{Default values}
% \label{prog_setup_configfile_defaults}
% There are situations when one needs to set the same value to several similar parameters,
% for instance the same queue length for all output ports in the module.
% One possible way is to use syntax as described above.
% The disadvantage of such approach is that one must expand the XML file
% to set each queue length explicitely from the appropriate variable;
% so in case of a big number of ports the file will be very long and
% confusing to the user.
%
% Another possibility to set several parameters at once
% consists in \strong{wildcard rules} using "*" or "?" symbols.
% These can be defined in a node:
%
% \begin{small}
% \begin{verbatim}
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
% \end{verbatim}
% \end{small}
%
% In this example for all ports which names begin with the string "Output",
% and which belong to any module, the output queue length will be 5.
% A wildcard rule of this form will be applied for
% all contexts of the configuration file,
% i.~e.~ by such rule we set the output queue length for all modules on all nodes.
% This allows to configure a big multi-node cluster with
% a compact XML file.
%
% Another possibility to set default value for some parameters - create
% parameter with the same name in parent object. Here word \strong{create}
% is crutial - one should use \func{CreateParInt()} method in module constructor -
% it is not enough just put additional tag in xml file. For instance, one can
% create parameter "MbsServerPort" in generator module and than
% MBS server transport, created for output port, will use that value for
% as default server port number.
\section{Usage of commands for configuration}
\label{prog_setup_configuration_commands}
Let's consider the possibility to configure a module by means of the \class{Command} class.
Here the use case is that
an object (like a module) should be created with fixed parameters,
ignoring the values specified in the configuration file.
In our example one can modify \func{InitMbsGenerator()} function in the following way:
\begin{small}
\begin{verbatim}
extern "C" void InitMbsGenerator()
{
dabc::Command* cmd = new dabc::CmdCreateModule("mbs::GeneratorModule",
"Generator");
cmd.SetInt("SubeventSize", 128);
if (!dabc::mgr.Execute(cmd)) {
EOUT("Cannot create generator module");
exit(1);
}
...
}
\end{verbatim}
\end{small}
Here one adds an additional parameter of name "SubeventSize" to
the \class{CmdCreateModule} object,
which will set the MBS subevent size to 128.
The generator module constructor will get the parameter value via method
\func{GetCfgInt()}, as described in section \ref{prog_setup_configurationparameter}.
Since the parameters of the passed \func{cmd} object will override all other settings here,
the value of the corresponding entry in the configuration file has no effect.