-
-
Notifications
You must be signed in to change notification settings - Fork 33
Description
Imagine the following scenario.
We have a struct called AnimalId that contains a single field, id, which serves as the unique key/identifier.
Animal is the base “class” and is uniquely identified by an id field of type AnimalId.
In addition to the identifier, it contains other non-key fields.
Then we have Cat and Dog, which are structs that inherit from Animal (in Rust this would be modeled via composition, parent field, but the IDL supports inheritance).
Conceptually, both Cat and Dog are specialized forms of Animal (an is-a relationship).
#[derive(DdsType)]
struct AnimalId {
#[dust_dds(key)]
id: u8,
}
#[derive(DdsType)]
struct Animal {
#[dust_dds(key)]
id: AnimalId;
name: String,
weight: f32,
}
#[derive(DdsType)]
struct Cat {
#[dust_dds(key)]
parent: Animal,
// Fields...
}
#[derive(DdsType)]
struct Dog {
#[dust_dds(key)]
parent: Animal,
// Fields...
}Now, a new Cat with id = 1 is created and written to DDS.
After some time passes, it needs to be disposed.
To do this, we create a Cat instance where all fields are set to their default values except for the identifier (Cat.parent.id), which is 1. Unfortunately, this does not work because we currently skip clearing field values when is_key is set to true.
This behavior works correctly for simple or primitive key types, but it fails for more complex keys, such as structs that contain nested fields, some of which may not be keys.
To fix this, we should modify function clear_nonkey_values as follows:
pub fn clear_nonkey_values(&mut self) -> XTypesResult<()> {
for index in 0..self.type_ref.get_member_count() {
let member = self.type_ref.get_member_by_index(index)?;
let member_id = member.get_id();
if !member.get_descriptor()?.is_key {
self.abstract_data.remove(&member_id);
} else if let Some(data_storage) = self.abstract_data.get_mut(&member_id) {
if let DataStorage::ComplexValue(complex_value) = data_storage { // Only for ComplexValue or expand?
complex_value.clear_nonkey_values()?
}
}
}
Ok(())
}Note that this is a building block for supporting inheritance in IDL (see CycloneDDS | Struct inheritance in idl C generator).
PS: The value field of BuiltInTopicKey must have #[dust_dds(key)] (and all tests are green 🫠):
pub struct BuiltInTopicKey {
#[dust_dds(key)] // Required
pub value: [u8; 16],
}