3.5.6. Definition of data types
The definition of the data type exchanged in a Topic is divided in
two classes: the TypeSupport
and the TopicDataType
.
TopicDataType describes the data type exchanged between a publication and a subscription, i.e., the data corresponding to a Topic. The user has to create a specialized class for each specific type that will be used by the application.
Any specialization of TopicDataType must be registered in the DomainParticipant
before it can be used to create Topic objects.
A TypeSupport object encapsulates an instance of TopicDataType, providing the functions needed to
register the type and interact with the publication and subscription.
To register the data type, create a new TypeSupport with a TopicDataType instance
and use the register_type()
member function on the TypeSupport.
Then the Topic can be created with the registered type name.
Note
Registering two different data types on the same DomainParticipant with identical names is not allowed and will issue an error. However, it is allowed to register the same data type within the same DomainParticipant, with the same or different names. If the same data type is registered twice on the same DomainParticipant with the same name, the second registering will have no effect, but will not issue any error.
// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
// Error
return;
}
// Register the data type in the DomainParticipant.
// If nullptr is used as name argument, the one returned by the type itself is used
TypeSupport custom_type_support(new CustomDataType());
custom_type_support.register_type(participant, nullptr);
// The previous instruction is equivalent to the following one
// Even if we are registering the same data type with the same name twice, no error will be issued
custom_type_support.register_type(participant, custom_type_support.get_type_name());
// Create a Topic with the registered type.
Topic* topic =
participant->create_topic("topic_name", custom_type_support.get_type_name(), TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
// Error
return;
}
// Create an alias for the same data type using a different name.
custom_type_support.register_type(participant, "data_type_name");
// We can now use the aliased name to If no name is given, it uses the name returned by the type itself
Topic* another_topic =
participant->create_topic("other_topic_name", "data_type_name", TOPIC_QOS_DEFAULT);
if (nullptr == another_topic)
{
// Error
return;
}
3.5.6.1. Dynamic data types
Instead of directly writing the specialized TopicDataType
class, it is possible to dynamically define
data types following the OMG Extensible and Dynamic Topic Types for DDS interface.
Data types can also be described on an XML file that is dynamically loaded.
// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
// Error
return;
}
// Load the XML file with the type description
DomainParticipantFactory::get_instance()->load_XML_profiles_file("example_type.xml");
// Retrieve the an instance of the desired type
DynamicTypeBuilder::_ref_type dyn_type_builder;
DomainParticipantFactory::get_instance()->get_dynamic_type_builder_from_xml_by_name("DynamicType",
dyn_type_builder);
// Register dynamic type
TypeSupport dyn_type_support(new DynamicPubSubType(dyn_type_builder->build()));
dyn_type_support.register_type(participant, nullptr);
// Create a Topic with the registered type.
Topic* topic =
participant->create_topic("topic_name", dyn_type_support.get_type_name(), TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
// Error
return;
}
A complete description of the dynamic definition of types can be found on the XTypes section.
3.5.6.2. Data types with a key
Data types that define a set of fields to form a unique key can distinguish different data sets within the same data type.
To define a keyed Topic, the getKey()
member function on the TopicDataType
has to be overridden to return the appropriate key value according to the data fields.
Additionally, the m_isGetKeyDefined
data member needs to be set to true
to let the entities
know that this is a keyed Topic and that getKey()
should be used.
Types that do not define a key will have m_isGetKeyDefined
set to false.
There are three ways to implement keys on the TopicDataType:
Adding a
@Key
annotation to the members that form the key in the IDL file when using Fast DDS-Gen.Adding the attribute
Key
to the member and its parents when using XTypes.Manually implementing the
getKey()
member function on the TopicDataType and setting them_isGetKeyDefined
data member value totrue
.
Data types with key are used to define data sub flows on a single Topic. Data values with the same key on the same Topic represent data from the same sub-flow, while data values with different keys on the same Topic represent data from different sub-flows. The middleware keeps these sub-flows separated, but all will be restricted to the same QoS values of the Topic. If no key is provided, the data set associated with the Topic is restricted to a single flow.