xentara-plugin v1.1
The Xentara Plugin Framework
|
Loading and an element is done in three steps:
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:
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():
To obtain a read handle to the attribute, use the array handle stored in your class object on the config block returned by configBlock():
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:
You can just store it in an std::weak_ptr, std::reference_wrapper, or xentara::model::SubReference. To accoplish this, simply pass a reference to the variable that will store the object reference to xentara::config::Resolver::submit. if you have a member variable *_ioBatch* of type std::weak_ptr<MyIoBatch>, for example, you can write:
You can call a member function of the referring object. To accomplish this, use a lambda:
You can call a member function of the referred-to object. To accomplish this, you can also use a lambda:
sharedFromThis() is enabled by deriving from xentara::plugin::EnableSharedFromThis. if MyIoBatch::addIoPoint() takes a reference instead of an std::shared_ptr, you can of course just write ioBatch.addIoPoint(*this);
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:
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:
On error, this will print something like:
FATAL ERROR: /home/xentara/.config/xentara/model.json (line 1415): size must be greater than 0
Example for a class that loads an I/O component:
Example for a class that publishes some config attributes of an I/O component: