Configuration API

Configuration options are settings that are exposed via a network interface from DV runtime. The way configuration options are implemented, the user can change the options dynamically at runtime, either via the DV gui, or with the command line utility.

Definition of configuration options

Static vs Runtime definition

Configuration options should be added in the static function static void initConfigOptions(dv::RuntimeConfig &config) in your module. This static function gets executed upon adding the module to the project, but before it has started. The function is used to populate the configuration before starting the module.

One can add configuration options at runtime, by accessing the modules config.add function at runtime. This makes sense, for example, in the constructor.

Selection of config option types

The following configuration option types are available

Name

Value type

Description

GUI representation

int

32bit integer

Accepts a range

numeric option

long

64bit integer

Accepts a range

numeric option

float

32bit float

Accepts a range

numeric option

double

64bit float

Accepts a range

numeric option

bool

boolean

Displays a checkbok

checkbox option

string

string

Displays an edit field

string option

button

boolean

Displays a button

button option

fileSave

string

Shows a file save dialog

file option

fileOpen

string

Shows a file open dialog

file option

directory

string

Shows a directory chooser dialog

file option

list

string

Shows a dropdown menu

list option

Adding a numerical option (int, long, float, double)

A numerical option can be added as follows

config.add(<name>, dv::ConfigOption::intOption(<description>, <defaultValue>, <minValue>, <maxValue>))
config.add(<name>, dv::ConfigOption::longOption(<description>, <defaultValue>, <minValue>, <maxValue>))
config.add(<name>, dv::ConfigOption::floatOption(<description>, <defaultValue>, <minValue>, <maxValue>))
config.add(<name>, dv::ConfigOption::doubleOption(<description>, <defaultValue>, <minValue>, <maxValue>))
  • name The name of the configuration option. Should be a camel cased variable compliant name

  • description A description of the purpose of the config option

  • defaultValue The value this config option should get initialized with

  • minValue The minimum allowed value for this config option. This is optional. If not set, the range defaults to the order of magnitude of the defaultValue

  • maxValue The maximum allowed value for this config option. This is optional. If not set, the range defaults to the order of magnitude of the defaultValue

Adding a string option

config.add(<name>, dv::ConfigOption::stringOption(<description>, <defaultValue>))
  • name The name of the configuration option. Should be a camel cased variable compliant name

  • defaultValue The default string to be used in this option

Adding a file option

A file option without a default value can be added as follows:

config.add(<name>, dv::ConfigOption::fileOpenOption(<description>, <allowedExtensions>))
config.add(<name>, dv::ConfigOption::fileSaveOption(<description>, <allowedExtensions>))

A file option with a default value can be added as follows:

config.add(<name>, dv::ConfigOption::fileOpenOption(<description>, <defaultValue>, <allowedExtensions>))
config.add(<name>, dv::ConfigOption::fileSaveOption(<description>, <defaultValue>, <allowedExtensions>))

A directory option can be added with:

config.add(<name>, dv::ConfigOption::directoryOption(<description>, <defaultValue>))
  • name The name of the configuration option. Should be a camel cased variable compliant name

  • defaultValue The default file path for the option. This is optional. If not set, the default is an empty string.

  • description A description of the purpose of the config option

  • allowedExtensions A comma separated list of the allowed extensions. Extensions should just be the ending, without dot. E.g. jpg,jpeg,png

Adding a button option

config.add(<name>, dv::ConfigOption::buttonOption(<description>, <buttonLabel>))
  • name The name of the configuration option. Should be a camel cased variable compliant name

  • description A description of the purpose of the config option

  • buttonLabel The string that should be displayed on the button

A button option has a boolean value type. By default, the value is false. As soon as a user clicks the button, the button gets disabled and the value set to true to indicate the request. To re-arm the button, reset the value back to false.

Adding a list option

config.add(<name>, dv::ConfigOption::listOption(<description>, <defaultChoice>, {<choice1>, <choice2>, ...}, <allowMultipleSelection>))
  • name The name of the configuration option. Should be a camel cased variable compliant name

  • description A description of the purpose of the config option

  • defaultChoice The default choice for this option. This can either be a string or the index of the choice in the list of choices. In case of a string, the string has to be present in the list of choices as well.

  • {<choice1>, <choice2>, ...} A vector of strings, denoting all possible selections for this option

Reading config options

Config values can be read easily with

bool value = config.getBool(<name>)
int value = config.getInt(<name>)
long value = config.getLong(<name>)
float value = config.getFloat(<name>)
double value = config.getDouble(<name>)
std::string value = config.getString(<name>)

The get functions are not compile time type checked. Make sure to use the correct getter function for your data type to prevent a runtime error. The correct value type for the config options can be obtained from the table above.

Validity of read values

Config option values can be read safely everywhere in the code. Outside changes to the option values are applied in between calls to the run and configUpdate functions. During the function calls, the value of config options can be seen as constant. (Unless explicitly changed in your code).

Performance considerations

Looking up a config value requies a string key lookup in a hash map. This is a very efficient operation, however, when used in a hot loop in the code, it can add overhead.

To mitigate this problem, the module api provides the opportunity to override a void configUpdate() function. This function, compared to the run function, only runs when a config value actually has changed. You can then copy the value of the config variable to an instance member. E.g.

void configUpdate() override {
    this->myConfigOption = config.getInt("myConfigOption");
}

During the run function call, one can then just use the instance member integer, rather than querying the value of the config option over and over again.

Setting config options

Config options can be set everywhere in the code. The option assumes the new value immediately after setting it. To set a config option, use the correct corresponding function

config.setBool(<name>, <value>)
config.setInt(<name>, <value>)
config.setLong(<name>, <value>)
config.setFloat(<name>, <value>)
config.setDouble(<name>, <value>)
config.setString(<name>, <value>)

Again, it is important to use the correct function for the options value type. Note that by setting config options from code, you are overwriting changes the user has made to the options.

Re-enabling buttons

Buttons have a boolean value type. As long as their config option value is false, the button appears armed and can be clicked. Clicking the button sets the value to true, to indicate a click request. After performing the required action, set the value back to false to re-enable the button.

Example:

void configUpdate() override {
    // check if user has clicked the button
    if(config.getBool("myButton") {

        // do complicated action..

        // re-enable button
        config.setBool("myButton", false);
    }
}