xentara-plugin v1.2.1
The Xentara Plugin Framework
Loading...
Searching...
No Matches
Loading Element Configs
See also
The Xentara Model File in the Xentara user manual

The Loading Sequence

Loading and an element is done in three steps:

  1. First, the virtual function loadConfig() is called, passing it the JSON object that contains the element's configuration. This function must go through all the members of the JSON object and initialize the configuration accordingly. After reading all the parameters, the configuration must be checked for completeness and consistency.
  2. Then, the virtual function realize() is called to allow the element to perform any initialization that can only be done once the entire model has been loaded.
  3. Finally, the virtual function prepare() is called, to allow the element to perform additional initialization that can only be done once all the objects in the model have been realized realized.

Publishing Config Parameters as Xentara Attributes

An element can publish some or all of its configuration parameters as Xentara attributes, which can then be read by other entities, or by client applications. Xentara itself automatically publishes the name, the primary key, and the UUID of each element.

If you which to publish addition configuration parameters, you must append them to the configuration array returned by config() in the constructor of the element class using appendObject() or one of the related functions. Xentara will use the this array to allocate the storage for the entities' configuration attributes before calling loadConfig().

Here is how you could add a custom configuration struct called CustomConfig to an element class:

class MyComponent::Class : public xentara::io::ComponentClass
{
public:
auto customConfig() const -> const auto &
{
return _customConfig;
}
private:
xentara::memory::Array::ObjectHandle<CustomConfig> _customConfig { config().appendObject<CustomConfig>() };
};
A class of I/O component that a driver supports.
Definition ComponentClass.hpp:29
auto config() -> memory::Array &
Gets the array object used for the configuration attributes.
Definition ComponentClass.hpp:135
A handle to an array element containing an object or an array of objects.
Definition Array_ObjectHandle.hpp:11

You do not need to add the entire configuration to this array, only the configuration parameters you intend to publish as Xentara attributes.

To access the custom parameters in your load function, use the array handle stored in your class object on the initializer parameter of loadConfig():

auto &attributes = initializer[Class::instance().customConfig()];

To obtain a read handle to the attribute, use the array handle stored in your class object on the config block returned by configBlock():

auto customConfigHandle = configBlock().handle(Class::instance().customConfig());
Examples
PublishingConfigAttributes.cpp

Resolving Cross References

Xentara elements can reference other entities, or attributes, events, or tasks of other entities. During the loading process, however, the referenced entities might not be available yet, since they might only appear later in the configuration file. For this reason, references to Xentara elements and their members must be resolved lazily, onca the entire configuration has been loaded. To simplify this, the framework passes an object of type xentara::config::Resolver to loadConfig(). This object has a number of member functions submit(), that allow you to submit requests for resolving cross references. Xentara will store these requests in the resolver object, and resolve them once all the entities and their primary keys are known.

You can use the resolver to resolve the following types of objects:

The objects will be available from the realize() loading step onwards.

There are three main strategies for handling the reference once it is resolved:

Handling Standard Properties

Each Xentara element type has a number of standard properties that are maintained by the plugin framework for you. These include the name, the primary key, and the UUID of the object. Since these properties reside in the same JSON object as the custom properties, you must pass any object members you do not recongize back to the framework. To enable you to do this, the framework passes an object of type FallbackConfigHandler to loadConfig(). You can pass individual JSON object members to this object, or pass the entire JSON object to it, if you do not have any custom properties:

auto MySimpleObject::loadConfig(const ConfigIntializer &initializer,
const FallbackConfigHandler &fallbackHandler) -> void
{
fallbackHandler(jsonObject);
}
auto MyComplexObject::loadConfig(const ConfigIntializer &initializer,
const FallbackConfigHandler &fallbackHandler) -> void
{
for (auto && [key, value] : jsonObject)
{
if (key == "thisIsTheOnlyKeyIKnow")
{
_thisIsTheOnlyKeyIKnow = value.toNumber<int>();
}
else
{
fallbackHandler(key, value);
}
}
}
An object used to resolve cross references in a configuration.
Definition Resolver.hpp:76

Handling Errors

You should check each configuration parameter for errors. After you have loaded all configuration parameters, you should check the configuration for completeness and consistency. If you encounter any errors, you should throw an exception of type std::runtime_error. Use the function xentara::utils::json::decoder::throwWithLocation() to throw the error, so that the error message will contain the line number in within the JSON file:

if (size <= 0)
{
xentara::utils::json::decoder::throwWithLocation(value, "size must be greater than 0");
}
auto throwWithLocation(const Location &location, StdException &&exception)

On error, this will print something like:

FATAL ERROR: /home/xentara/.config/xentara/model.json (line 1415): size must be greater than 0

Examples

Example for a class that loads an I/O component:

LoadingElementConfig.cpp

Example for a class that publishes some config attributes of an I/O component:

PublishingConfigAttributes.cpp