3.5.4. 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.4.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
eprosima::fastrtps::xmlparser::XMLProfileManager::loadXMLFile("example_type.xml");

// Retrieve the an instance of the desired type and register it
eprosima::fastrtps::types::DynamicType_ptr dyn_type =
        eprosima::fastrtps::xmlparser::XMLProfileManager::getDynamicTypeByName("DynamicType")->build();
TypeSupport dyn_type_support(new eprosima::fastrtps::types::DynamicPubSubType(dyn_type));
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 Dynamic Topic Types section.

3.5.4.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 Dynamic Topic Types.

  • Manually implementing the getKey() member function on the TopicDataType and setting the m_isGetKeyDefined data member value to true.

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.