Configuration
Met.3D requires several components to be configured during startup, including:
Available actor types
Datasets to load before the initial session is created
Batch mode
Development aids
Per-user application settings
This page documents the classes responsible for loading, organizing, and applying this configuration.
Application configuration
MApplicationConfigurationManager is the central entry point for
system-startup configuration. One instance is created in MMainWindow, and
Met.3D is configured from the MMainWindow constructor by calling
loadConfiguration().
Rather than implementing all startup configuration itself, MApplicationConfigurationManager delegates
individual configuration tasks to a collection of MAbstractApplicationConfiguration instances.
Each implementation provides a single configure() method that is invoked during loadConfiguration().
This keeps each configuration concern isolated instead of accumulating all startup logic in one large routine.
The following configuration classes are currently registered:
MPipelineConfiguration– Initializes the pipeline schedulers and loads the datasets specified via the--datasetscommand-line argument. It also creates the required data pipelines for newly loaded datasets, both during startup and when datasets are loaded later from the GUI.MBatchModeConfiguration– Reads the batch mode configuration (see Batch mode for the batch mode configuration format).MDevelopmentAidsConfiguration– Initializes modules that support development and debugging independently of the application’s normal runtime configuration. It currently contains tests formetroutines.h
In addition, registerActorFactories() registers all actor factories known to Met.3D.
Unlike the classes above, this is not implemented as an MAbstractApplicationConfiguration and is called directly from loadConfiguration().
Actor type registry
MActorTypeRegistry maintains the set of actor types available in Met.3D.
It is responsible for creating actor instances at runtime—for example, when a user creates a new actor through the UI.
New actor types are registered via MActorTypeRegistry::registerActorType<ActorType>(group).
This function wraps the actor type in an MGenericActorFactory<ActorType> and registers it both
in a global registry keyed by
ActorType::staticActorType(), andin the named
groupused to organize actor types in the user interface.
The registry therefore supports looking up actor factories either directly by name (getActorFactory() and hasActorFactory())
or by UI group (getActorGroups() and getActorTypesByGroup()).
Per-user configuration
Per-user configuration is handled independently of MApplicationConfigurationManager by two singleton classes:
MUserConfigurationstores user-facing application settings in Qt’s standard per-platform configuration location (for example,$HOME/.configon Linux). The configuration is loaded automatically the first time it is accessed, creating default values if necessary.A convenience typedef,
MConfig, provides concise static accessors for all configuration options.MUserCachestores application state that should persist across sessions but is not considered user-facing configuration. Examples include dock widget layouts and file browser bookmarks.MUserCacheprovides templatedsetValue()andvalue()convenience functions for any type supported byQVariant, while also exposing the underlyingQSettingsobject for more advanced use cases. LikeMUserConfiguration, it is loaded on first access.
Extending the user configuration
When adding a new user configuration option, follow the structure of the existing options and place it into the appropriate configuration group.
In muserconfiguration.h, add
a
static inlineaccessor that exposes the value, anda property member that stores and edits the value.
1class MUserConfiguration : public QObject
2{
3 ...
4public: // Static interface
5 ...
6 static int exampleOption()
7 { return getInstance()->exampleOptionProp; }
8 ...
9private:
10 ...
11 MIntProperty exampleOptionProp;
12 ...
13}
The property should be to be non-undoable, have a config key for persistence, and an appropriate value callback.
The available callbacks are:
configurationChanged– Emitted whenever the setting changes, so dependent classes can update immediately.restartRequiredConfigurationChanged– Emitted when the change only takes effect after restarting the application.
Initialize the property in muserconfiguration.cpp and add it to the appropriate property group.
1...
2
3exampleOptionProp = MIntProperty("Example Option", 0);
4exampleOptionProp.setConfigKey("example_option");
5exampleOptionProp.toggleUndoable(false); // All user settings are not undoable.
6exampleOptionProp.registerValueCallback(this, &MUserConfiguration::configurationChanged);
7generalSettingsProp.addSubProperty(exampleOptionsProp);
8...
This new option can now be read everywhere in Met.3D via MConfig::exampleOption().
Using the user cache
The user cache stores information that should persist across application runs without being part of the user’s application settings. Each cache entry belongs to a namespace, allowing independent parts of the application to use identical keys without conflict.
To store a single value, use MUserCache::setValue(const QString &ns, const QString &key, const T &value).
The value type must be supported by QVariant.
Lists can be stored using MUserCache::writeList(const QString &ns, const QString &key, const QList<T> &list).
For example:
1int value = 10;
2MUserCache::setValue("ExampleNamespace", "example_key", value);
3
4QList<int> values = ...;
5MUserCache::writeList("ExampleNamespace", "example_list_key", value);
Read individual values using MUserCache::value(const QString &ns, const QString &key, T defaultValue = {}).
If no value exists, the supplied default value is returned.
Lists can be read using MUserCache::readList(const QString &ns, const QString &key).
If the key does not exist, an empty list is returned.
1int value = MUserCache::value<int>("ExampleNamespace", "example_key");
2
3QList<int> values = MUserCache::readList("ExampleNamespace", "example_list_key");