CoreDX DDS Modern C++ API
Dynamic Type and Dynamic Data Use Cases

DynamicType Use Cases

Set up:

#include <dds/dds.hpp>
#include <dds/core/xtypes/xtypes.hpp>

Define an enumerated (enum) type:

dds::core::xtypes::EnumType enumType("EnumType");
enumType.bit_bound(16);
enumType.add_member( dds::core::xtypes::EnumMember( "ONE", 1 ) );
enumType.add_member( dds::core::xtypes::EnumMember( "TWO", 2 ) );
enumType.add_member( dds::core::xtypes::EnumMember( "THREE", 3 ) );

Define a structure type:

dds::core::xtypes::Member member1("long1", dds::core::xtypes::primitive_type<int32_t>() );
member1.id( 101 ); // set the id (if left at default 'INVALID' then it will be auto assigned when added to a structure)
member1.key( true ); // mark the member as 'key' (default is false = not key)
member1.must_understand(true); // mark the member as 'must_understand' (default is false = not must_understand)
// these calls can be cascaded, for example:
dds::core::xtypes::Member member2 = dds::core::xtypes::Member("long2", dds::core::xtypes::primitive_type<int32_t>()).id( 101 ).optional(true);
// we don't add 'member1' or 'member2' to the struct below, but we could...
// construct a 'struct' named 'structType' with several members
dds::core::xtypes::StructType structType("StructType");
structType.add_member( dds::core::xtypes::Member("a_long", dds::core::xtypes::primitive_type<int32_t>()) );
structType.add_member( dds::core::xtypes::Member("a_string", dds::core::xtypes::StringType()) ); // unbounded
structType.add_member( dds::core::xtypes::Member("a_enum", enumType ) );
structType.add_member( dds::core::xtypes::Member("a_fixed_string", dds::core::xtypes::StringType(16)) );
structType.add_member( dds::core::xtypes::Member("a_opt_string", dds::core::xtypes::StringType(16)).optional(true) );
structType.add_member( dds::core::xtypes::Member("a_array", dds::core::xtypes::ArrayType(dds::core::xtypes::primitive_type<int32_t>(), 5)) );
structType.add_member( dds::core::xtypes::Member("a_sequence", dds::core::xtypes::SequenceType(dds::core::xtypes::primitive_type<int32_t>(), 10)) );
structType.add_member( dds::core::xtypes::Member("a_map", dds::core::xtypes::MapType(dds::core::xtypes::primitive_type<int32_t>(),
// define and add an embedded struct member
fooType.add_member( dds::core::xtypes::Member("x", dds::core::xtypes::primitive_type<int32_t>()).key(true) );
structType.add_member( dds::core::xtypes::Member("a_foo", fooType));

This is equivalent to the IDL:

@bit_bound(16) enum EnumType { ONE=1, TWO=2, THREE=3 };
struct Foo {
@key long x;
};
struct StructType {
long a_long;
string a_string;
EnumType a_enum;
string<16> a_fixed_string;
@optional string<16> a_opt_string;
long a_array[5];
sequence<long,10> a_sequence;
map<long,string,10> a_map;
Foo a_foo;
};

Define a union type:

dds::core::xtypes::UnionType unionType("UnionType", dds::core::xtypes::primitive_type<int32_t>());
unionType.add_member( dds::core::xtypes::UnionMember("a_long", dds::core::xtypes::primitive_type<int32_t>(), 1 ) );
unionType.add_member( dds::core::xtypes::UnionMember("a_other_long", dds::core::xtypes::primitive_type<int32_t>(), 2 ).is_default_case(true).id( 101) );
unionType.add_member( dds::core::xtypes::UnionMember("a_foo", fooType, 3 ).id( 102 ) );
unionType.add_member( dds::core::xtypes::UnionMember("a_array", dds::core::xtypes::ArrayType(dds::core::xtypes::primitive_type<int32_t>(), 5), 4) );

This is equivalent to the IDL:

struct Foo {
@key long x;
};
union UnionType switch( long ) {
case 1: long a_long;
default:
case 2: @id(101) long a_other_long;
case 3: @id(102) Foo a_foo;
case 4: long a_array[4];
};

The API also supports constructing struct and union types with the member[s] specified as an initializer list:

"Struct2", {
dds::core::xtypes::Member("a", dds::core::xtypes::primitive_type<int32_t>()).key(true),
dds::core::xtypes::Member("b", dds::core::xtypes::primitive_type<int32_t>()),
}
);
"Union2",
dds::core::xtypes::primitive_type<int32_t>(),
{
dds::core::xtypes::UnionMember("a", dds::core::xtypes::primitive_type<int32_t>(), 1 ),
dds::core::xtypes::UnionMember("b", dds::core::xtypes::primitive_type<int32_t>(), 2 ),
} );

Using Dynamic Types with DataReaders and DataWriters

Construct a Topic that refers to a constructed Dynamic Type (struct or union), then refer to that Topic when constructing the DataReader and/or DataWriter.

// construct the type
foo.add_member( dds::core::xtypes::Member("x", dds::core::xtypes::primitive_type<int32_t>()).key(true) );
foo.add_member( dds::core::xtypes::Member("y", dds::core::xtypes::primitive_type<bool>()) );
foo.add_member( dds::core::xtypes::Member("z", dds::core::xtypes::primitive_type<float>()) );
// refer to that type and DynamicData in the Topic
dds::topic::Topic< dds::core::xtypes::DynamicData > test_topic( dp, "TestTopic", foo );
// use that Topic for DataWriter
// use that Topic for DataReader

DynamicData Use Cases

Publishing a DynamicData sample

// prepare the DynamicData sample
sample.value( "x", 3 );
sample.value( "y", true );
sample.value<float>( "z", 3.1415 );
// write it!
test_dw.write( sample );

Receiving DynamicData samples

// read it
test_dr >> dds::sub::read >> samples;
for ( auto sample : samples )
{
if ( sample.info().valid() )
{
cout << "x : " << sample.data().value<int32_t>("x") << endl;;
cout << "y : " << sample.data().value<bool>("y") << endl;
cout << "z : " << sample.data().value<float>("z") << endl;
}
}

© 2009-2020 Twin Oaks Computing, Inc
Castle Rock, CO 80104
All rights reserved.