RTI Connext C# API  6.1.2
DynamicData examples

How to publish and subscribe to topics for dynamically-defined types.

How to publish and subscribe to topics for dynamically-defined types.

In addition to IDL and code generation, data types can be defined dynamically in code and in XML using Rti.Types.Dynamic.DynamicType. Data for those types can be published and subscribed to using Rti.Types.Dynamic.DynamicData.

Example 1: define a type and publish a data sample

// Define the Shape type dynamically:
StructType shapeType = typeFactory.BuildStruct()
.WithName("Shape")
.AddMember(new StructMember("color", typeFactory.CreateString(bounds: 128), isKey: true))
.AddMember(new StructMember("x", typeFactory.GetPrimitiveType<int>()))
.AddMember(new StructMember("y", typeFactory.GetPrimitiveType<int>()))
.AddMember(new StructMember("shapesize", typeFactory.GetPrimitiveType<int>()))
.Create();
// Create a topic for the type we have defined. The generic type argument
// for Topic is DynamicData when we call CreateTopic with a DynamicType.
Topic<DynamicData> topic = participant.CreateTopic(
name: "Square",
type: shapeType);
// Create a DataWriter
DataWriter<DynamicData> writer = participant.ImplicitPublisher
.CreateDataWriter(topic);
// Create a sample
DynamicData sample = new DynamicData(shapeType);
// writer.CreateData() has the same effect:
DynamicData sample2 = writer.CreateData();
// Set the fields by name
sample.SetValue(memberName: "color", value: "GREEN");
sample.SetValue(memberName: "shapesize", value: 40);
// Or by member index (which is more efficient)
sample.SetValue(memberId: 2, value: 100); // sample.x = 100
sample.SetValue(memberId: 3, value: 100); // sample.y = 100
// The type of the argument value must match exactly the declared field
// type. For convenience, SetAnyValue will attempt to transform the
// intput value to the declared type. In this example it will convert
// the string "17" to an the int 17.
sample.SetAnyValue(memberName: "x", value: "17");
A factory for creating DynamicTypes.
Definition: DynamicTypeFactory.cs:21
StructBuilder BuildStruct()
Returns a StructBuilder that allows creating an StructType.
static DynamicTypeFactory Instance
A singleton for the factory.
Definition: DynamicTypeFactory.cs:25
StructType Create()
Creates a new StructType object using the current properties of the StructBuilder instance.
Definition: StructBuilder.cs:131
StructBuilder AddMember(StructMember member)
Returns the same StructBuilder instance with a new StructMember added to Members.
Definition: StructBuilder.cs:99
StructBuilder WithName(string name)
Returns the same StructBuilder instance with a modified Name.
Definition: StructBuilder.cs:66
Contains support for the dynamic definition and manipulation of topic-types.
Definition: Namespaces.cs:102
Support for topic-types.
Definition: Namespaces.cs:96
Contains the RTI Connext C# API.
Definition: Logger.cs:20

Example 2: load a type definition from XML and subscribe to it

static void ProcessData(AnyDataReader anyReader)
{
var reader = (DataReader<DynamicData>)anyReader;
using var samples = reader.Take();
foreach (var sample in samples)
{
if (sample.Info.ValidData)
{
DynamicData data = sample.Data;
// Get the fields using member name or member index
string color = data.GetValue<string>(memberName: "color");
int shapesize = data.GetValue<int>(memberName: "shapesize");
var coordinates = (
data.GetValue<int>(memberId: 2), // data.x
data.GetValue<int>(memberId: 3) // data.y
);
// The type argument for GetValue must exactly match the declared
// field type. You can use GetAnyValue to return an object instead
object colorAsObject = data.GetAnyValue("color");
// You can also convert the data to string
Console.WriteLine(data);
}
}
}
// Load the ShapeType from an XML file
var provider = new QosProvider("Shape.xml");
DynamicType shapeType = provider.GetType("Shape");
// Create a topic for the type we have defined. The generic type argument
// for Topic is DynamicData when we call CreateTopic with a DynamicType.
Topic<DynamicData> topic = participant.CreateTopic(
name: "Square",
type: shapeType);
// Create a DataReader with an event handler for DataAvailable
DataReader<DynamicData> reader =
participant.ImplicitSubscriber.CreateDataReader(
topic,
preEnableAction: reader => reader.DataAvailable += ProcessData);
// ...

The XML definition of the Shape type is:

<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://community.rti.com/schema/current/rti_dds_profiles.xsd">
<types>
<module name="Example">
<struct name= "Shape">
<member name="color" stringMaxLength="128" type="string" key="true"/>
<member name="x" type="int32"/>
<member name="y" type="int32"/>
<member name="shapesize" type="int32"/>
</struct>
</module>
</types>
</dds>

The rticonnextdds-examples GitHub repository provides additional DynamicData examples