Hi all,
I'm wondering if there is a way to write only a member subset of a complex type so that, for instance, I could send those members whose value has changed.
Thanks
Antonio
Hi all,
I'm wondering if there is a way to write only a member subset of a complex type so that, for instance, I could send those members whose value has changed.
Thanks
Antonio
Hi Antonio,
There is one way to do it. You can find all information I'll give you here in the Users Manual "3.8.3 Sending Only a Few Fields":
Using the Dynamic Data API you can define "sparse value types". A sample of such a type only contains the field values that were explicitly set by the sender. So fields that have not been set by the sender can't be read by the recipient (returning an error).
Consider that sparse value types affects discovery because end-points only communicate each other only if they both use sparse value types.
The code to create sparse value types is the following:
DDS_ExceptionCode_t ex = DDS_NO_EXCEPTION_CODE;
DDS_TypeCodeFactory* factory = DDS_TypeCodeFactory::get_instance();
DDS_TypeCode* sparseTc = factory->create_sparse_tc( "MySparseType", DDS_VM_NONE, NULL, ex);
sparseTc->add_member("my_integer", ID_MY_INTEGER, factory->get_primitive_tc(DDS_TK_LONG), DDS_TYPECODE_NONKEY_MEMBER, ex);
Note that you have to define a member ID. The ID is a two-bytes code that identifies uniquely the field within its parent type. So you are adding two bytes to your data. If you want to consume less bandwidth, using sparse value types can be a good way to do it, but just when the percentage of fields that a sample contains is low enough to save more bytes than added with ID's. Usually, sparse value types are useful if that percentage is lower or equal than 50%.
I hope my answer is useful for you.
Juanjo.
Thanks a lot Juanjo. I've been taking a look into the user's manual but I haven't seen any useful example showing how to select which members to send and which not. Could you point me to documentation that shows that or provide a simple example?
Antonio
Hi Antonio,
the code to set data members to send them is the following:
DDSDynamicDataTypeSupport* support = ...;
DDS_DynamicData* sample = support->create_data();
DDS_ReturnCode_t success = sample->set_long("myInteger", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED, 5);
DDS_Long theInteger = 0;
success = sample->get_long(&theInteger, "myInteger", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED);
And to clear data members, use the clear_member function:
DDS_ReturnCode_t DDS_DynamicData::clear_member (const char* member_name, DDS_DynamicDataMemberId member_id)
For example:
DDS_ReturnCode_t success = sample->clear_member("myInteger", DDS_DYNAMIC_DATA_MEMBER_ID_UNSPECIFIED);
Regards, Juanjo.
That's the operation that I was missing. I think it should be pointed out in the user's manual.
Thanks
Antonio