11.7. Dynamic Types profiles¶
Fast DDS supports the implementation of DynamicType by defining them through XML files. Thus the Dynamic Types can be modified without the need to modify the source code of the DDS application.
11.7.1. XML Structure¶
The definition of type profiles in the XML file is done with the <types>
tag.
Each <types>
element can contain one or more Type definitions.
Defining several types within a <types>
element or a single type for each <types>
element has the same
result.
Below, an example of a stand-alone types definition via XML is shown.
<types>
<type>
<!-- Type definition -->
</type>
<type>
<!-- Type definition -->
<!-- Type definition -->
</type>
</types>
Note
For more information on the difference between stand-alone and rooted definitions please refer to section Rooted vs Standalone profiles definition.
11.7.2. Type definition¶
Below, the types supported by Fast DDS are presented . For further information about the supported DynamicType, please, refer to Supported Types. For each of the types detailed below, an example of how to build the type’s XML profile is provided.
11.7.2.1. Enum¶
The <enum>
type is defined by its attribute name
and a set of <enumerator>
child elements.
Each <enumerator>
is defined by two attributes: a name
and an optional value
.
Please, refer to Enumeration for more information on the <enum>
type.
<enum name="MyEnum">
<enumerator name="A" value="0"/>
<enumerator name="B" value="1"/>
<enumerator name="C" value="2"/>
</enum>
11.7.2.2. Typedef¶
The <typedef>
XML element is defined by a name
and a type
mandatory attributes, and various optional
attributes for complex types definition.
These optional attributes are: key_type
, arrayDimensions
, nonBasicTypeName
, sequenceMaxLength
, and
mapMaxLength
.
See Complex types attributes for more information on these attributes.
The <typedef>
element corresponds to Alias in Supported Types
section.
<typedef name="MyAliasEnum" type="nonBasic" nonBasicTypeName="MyEnum"/>
<typedef name="MyAliasArray" type="int32" arrayDimension="2,2"/>
11.7.2.3. Struct¶
The <struct>
element is defined by its name
attribute and its <member>
child elements.
Please, refer to Structure for more information on the <struct>
type.
<struct name="MyStruct">
<member name="first" type="int32"/>
<member name="second" type="int64"/>
</struct>
Structs can inherit from another structs.
This is implemented by defining the value of the baseType
attribute, on the child <struct>
element to be the
value of the name
attribute of the parent <struct>
element.
This is exemplified by the code snippet below.
<struct name="ParentStruct">
<member name="first" type="int32"/>
<member name="second" type="int64"/>
</struct>
<struct name="ChildStruct" baseType="ParentStruct">
<member name="third" type="int32"/>
<member name="fourth" type="int64"/>
</struct>
11.7.2.4. Union¶
The <union>
type is defined by a name
attribute, a <discriminator>
child element and a set of <case>
child elements.
Each <case>
element has one or more <caseDiscriminator>
and a <member>
child elements.
Please, refer to Union for more information on the <union>
type.
<union name="MyUnion">
<discriminator type="byte"/>
<case>
<caseDiscriminator value="0"/>
<caseDiscriminator value="1"/>
<member name="first" type="int32"/>
</case>
<case>
<caseDiscriminator value="2"/>
<member name="second" type="nonBasic" nonBasicTypeName="MyStruct"/>
</case>
<case>
<caseDiscriminator value="default"/>
<member name="third" type="nonBasic" nonBasicTypeName="int64"/>
</case>
</union>
11.7.2.5. Bitset¶
The <bitset>
element defines the Bitset type.
It is comprised by a name
attribute and a set of <bitfield>
child elements.
In turn, the <bitfield>
element has the mandatory bit_bound
attribute, which can not be higher than 64, and
two optional attributes:
name
and type
.
A <bitfield>
with a blank name
attribute is an inaccessible set of bits.
Its management type
can ease the <bitfield>
modification and access.
Please, refer to Bitset for more information about the <bitset>
type.
<bitset name="MyBitSet">
<bitfield name="a" bit_bound="3"/>
<bitfield name="b" bit_bound="1"/>
<bitfield bit_bound="4"/>
<bitfield name="c" bit_bound="10"/>
<bitfield name="d" bit_bound="12" type="int16"/>
</bitset>
Moreover, bitsets can inherit from another bitsets:
<bitset name="ParentBitSet">
<bitfield name="a" bit_bound="10"/>
<bitfield name="b" bit_bound="15"/>
</bitset>
<bitset name="ChildBitSet" baseType="ParentBitSet">
<bitfield bit_bound="1"/>
<bitfield bit_bound="5" type="uint16"/>
</bitset>
11.7.2.6. Bitmask¶
The <bitmask>
element, which corresponds to the Bitmask type, is defined by
a mandatory name
attribute, an optional bit_bound
attribute, and several <bit_value>
child elements.
The bit_bound
attribute specifies the number of bits that the type will manage.
The maximum value allowed for the bit_bound
is 64.
The <bit_value>
element can define its position in the bitmask setting the positition
attribute.
Please, refer to Bitmask for more information on the <bitmask>
type.
<bitmask name="MyBitMask" bit_bound="8">
<bit_value name="flag0" position="0"/>
<bit_value name="flag1"/>
<bit_value name="flag2" position="2"/>
<bit_value name="flag5" position="5"/>
</bitmask>
11.7.2.7. Member types¶
Member types are defined as any type that can belong to a <struct>
or a <union>
, or be aliased by a
<typedef>
.
These can be defined by the <member>
XML tag.
11.7.2.7.1. Primitive types¶
The identifiers of the available basic types are listed in the table below. Please, refer to Primitive Types for more information on the primitive types.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All of them are defined as follows:
<struct name="primitive_types_example">
<!-- Primitive type definitions inside a struct -->
<member name="my_long" type="int64"/>
<member name="my_bool" type="boolean"/>
<member name="my_string" type="string"/>
</struct>
11.7.2.7.2. Arrays¶
Arrays are defined in the same way as any other member type but they add the attribute arrayDimensions
.
The format of the arrayDimensions
attribute value is the size of each dimension separated by commas.
Please, refer to Array explanation for more information on array type.
<struct name="arrays_example">
<member name="long_array" type="int32" arrayDimensions="2,3,4"/>
</struct>
11.7.2.7.3. Sequences¶
The sequence type is implemented by setting three attributes: name
, the type
, and the
sequenceMaxLength
.
The type of its content should be defined by the type
attribute.
The following example shows the implementation of a sequence of maximum length equal to 3.
In turn, this is a sequence of sequences of maximum length of 2 and contents of type int32
.
Please, refer to Sequence section for more information on sequence type.
<typedef name="my_sequence_inner" type="int32" sequenceMaxLength="2"/>
<struct name="SeqSeqStruct">
<member name="my_sequence_sequence" type="nonBasic" nonBasicTypeName="my_sequence_inner" sequenceMaxLength="3"/>
</struct>
11.7.2.7.4. Maps¶
Maps are similar to sequences, but they need to define two content types.
The key_type
defines the type of the map key, while the type
defines the map value type.
Again, both types can be defined as attributes of a <typedef>
element, or as a <member>
child element of a
<struct>
or <union>
elements.
See section Map for more information on map type.
<typedef name="my_map_inner" type="int32" key_type="int32" mapMaxLength="2"/>
<struct name="MapMapStruct">
<member name="my_map_map" type="nonBasic" nonBasicTypeName="my_map_inner" key_type="int32" mapMaxLength="2"/>
</struct>
11.7.2.8. Complex types¶
The complex types are a combination of the aforementioned types.
Complex types can be defined using the <member>
element in the same way a basic or an array type would be.
Please, refer to Complex Types section for more information on complex types.
<struct name="OtherStruct">
<member name="my_enum" type="nonBasic" nonBasicTypeName="MyEnum"/>
<member name="my_struct" type="nonBasic" nonBasicTypeName="MyStruct" arrayDimensions="5"/>
</struct>
11.7.2.8.1. Complex types attributes¶
The attributes of a complex type element can be highly varied depending on the type being defined. Since the attributes that can be defined for each of the types have already been listed, these attributes are then defined in the following table.
Name |
Description |
---|---|
|
Data type.
This can be a Primitive types or a |
|
Name of the complex type. Only applies if the |
|
Dimensions of an array. |
|
Maximum length of a Sequences. |
|
Maximum length of a Maps. |
|
Data type of a map key. |
11.7.3. Loading dynamic types in a Fast DDS application¶
In the Fast DDS application that will make use of the XML Types, the XML files that define the types must be loaded before trying to instantiate DynamicPubSubType objects of these types.
// Create a DomainParticipant
DomainParticipant* participant =
DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
// Error
return;
}
// Load the XML File
if (ReturnCode_t::RETCODE_OK ==
DomainParticipantFactory::get_instance()->load_XML_profiles_file("my_profiles.xml"))
{
// Retrieve the an instance of MyStruct type
eprosima::fastrtps::types::DynamicType_ptr my_struct_type =
eprosima::fastrtps::xmlparser::XMLProfileManager::getDynamicTypeByName("MyStruct")->build();
// Register MyStruct type
TypeSupport my_struct_type_support(new eprosima::fastrtps::types::DynamicPubSubType(my_struct_type));
my_struct_type_support.register_type(participant, nullptr);
}
else
{
std::cout << "Cannot open XML file \"types.xml\". "
<< "Please, set the correct path to the XML file"
<< std::endl;
}