Since version 0.6, you can add "attributes" to your objects. Wallaroo attributes are similar to standard C++ class attributes, except their value can be assigned in the configuration file or by using a DSL similar to the one used for wiring.
Wallaroo attributes are the solution to the limit in the numbers of ctor parameters in classes managed by wallaroo. (see CtorParameters).
This is an example of attribute declaration:
// triangle.h class Triangle : public wallaroo::Part { ... private: const Attribute< unsigned int > base; const Attribute< unsigned int > height; };
In the constructor, you must give a name to your attributes, so that you can name them in the configuration file or in the DSL:
// triangle.cpp Triangle::Triangle() : base( "base", RegistrationToken() ), height( "height", RegistrationToken() ), ... { }
After you create an object, you can assign a value to its attributes by using this Domain Specific Language:
set_attribute( "base" ).of( shape_catalog[ "triangle1" ] ).to( 10 ); set_attribute( "height" ).of( shape_catalog[ "triangle1" ] ).to( 20 );
To save some typing, if you are referring to the same catalog, you can write:
wallaroo_within( shape_catalog ) { set_attribute( "base" ).of( "triangle1" ).to( 10 ); set_attribute( "height" ).of( "triangle1" ).to( 20 ); }
Wallaroo can throw these exceptions:
ElementNotFound
if the attributes doesn't exist in the object specified WrongType
if the value is not of the type of the attribute Setting attributes, as well as wiring, can be performed in the configuration file.
This is a sample of an XML file example:
<part> <name>triangle1</name> <class>Triangle</class> <attribute> <name>base</name> <value>10</value> </attribute> <attribute> <name>height</name> <value>20</value> </attribute> </part>
This is a sample of a JSON file example:
"parts": [ { "name": "triangle1", "class": "Triangle", "attribute": { "name": "base", "value": 10 }, "attribute": { "name": "height", "value": 20 } },
With wallaroo attributes you can work around the limit on contructor parameters. However, using attributes instead of constructor parameters requires some care.
The constructor is the place where you perform initialization tasks for your objects, possibly using the constructor parameters.
However, the attribute assignment is performed after the objects are created, i.e. after the constructor calls. This means that inside the constructors your attributes have undefined value, so you cannot use attributes inside the constructors.
To solve this issue, wallaroo provides the methods Catalog::Init()
and Part::Init()
.
If you need the attributes value to perform the initialization of an object, you can override the virtual method Part::Init()
. Inside this method you can put the initialization of your object (the code put in the ctor) safely assuming the attributes value are correct.
The method Catalog::Init()
calls Part::Init()
for each object contained in the Catalog
. During the application initialization, you should call Catalog::Init()
after the wiring and attribute initialization.
This snippet of code shows how to perform the initialization:
// triangle.h class Triangle : public wallaroo::Part { public: virtual void Init() { // use attributes: here they've been already valorized } ... private: const Attribute< unsigned int > base; const Attribute< unsigned int > height; }; ... // main.cpp int main() { ... wallaroo_within( shape_catalog ) { set_attribute( "base" ).of( "triangle1" ).to( 10 ); set_attribute( "height" ).of( "triangle1" ).to( 20 ); } // this calls Init() for every object in the catalog shape_catalog.Init(); ...