@@ -577,7 +577,7 @@ bool DDSManager::addPartition(const std::string& topicName,
577
577
// ------------------------------------------------------------------------------
578
578
bool DDSManager::createSubscriber (const std::string& topicName,
579
579
const std::string& readerName,
580
- const std::string& filter)
580
+ const std::string& filter, const DDS::StringSeq &filterParams )
581
581
{
582
582
// Make sure the data reader name is valid
583
583
if (readerName.empty ())
@@ -641,14 +641,14 @@ bool DDSManager::createSubscriber(const std::string& topicName,
641
641
// Create a new filtered topic if requested
642
642
if (!filter.empty ())
643
643
{
644
- const DDS::StringSeq noParams;
645
- const std::string filterName = topicName + " _" + readerName;
644
+ const std::string filterName = topicName + " _" + readerName + " _0" ;
646
645
DDS::ContentFilteredTopic_var filteredTopic =
647
646
m_domainParticipant->create_contentfilteredtopic (
648
647
filterName.c_str (),
649
648
topicGroup->topic ,
650
649
filter.c_str (),
651
- noParams);
650
+ filterParams);
651
+
652
652
653
653
if (!filteredTopic)
654
654
{
@@ -784,7 +784,8 @@ bool DDSManager::createPublisher(const std::string& topicName)
784
784
// ------------------------------------------------------------------------------
785
785
bool DDSManager::createPublisherSubscriber (const std::string& topicName,
786
786
const std::string& readerName,
787
- const std::string& filter)
787
+ const std::string& filter,
788
+ const DDS::StringSeq &filterParams)
788
789
{
789
790
// TODO: Remove this function (No longer used).
790
791
bool pass = false ;
@@ -795,7 +796,7 @@ bool DDSManager::createPublisherSubscriber(const std::string& topicName,
795
796
return false ;
796
797
}
797
798
798
- pass = createSubscriber (topicName, readerName, filter);
799
+ pass = createSubscriber (topicName, readerName, filter, filterParams );
799
800
if (!pass)
800
801
{
801
802
return false ;
@@ -929,33 +930,57 @@ bool DDSManager::replaceFilter(const std::string& topicName,
929
930
decltype (m_sharedLock) lock (m_topicMutex);
930
931
std::shared_ptr<TopicGroup> topicGroup = m_topics[topicName];
931
932
932
- if (topicGroup->m_readerListeners .find (readerName) ! = topicGroup->m_readerListeners .end ()) {
933
+ if (topicGroup->m_readerListeners .find (readerName) = = topicGroup->m_readerListeners .end ()) {
933
934
std::cerr << " Error in replaceFilter: Reader listener '" << readerName
934
- << " ' already registered for topic '"
935
+ << " ' not registered for topic '"
935
936
<< topicName
936
937
<< " '." << std::endl;
937
938
return false ;
938
939
}
939
940
940
- // Stop the emitter if it exists
941
+ // Stop the emitter if it exists (exists for callbacks)
941
942
EmitterBase* emitter = nullptr ;
942
943
if (topicGroup->emitters .find (readerName) != topicGroup->emitters .end ())
943
944
{
945
+ std::cerr << " found emitter when trying to stop" << std::endl;
944
946
emitter = topicGroup->emitters [readerName].get ();
945
947
if (emitter->isRunning ())
946
948
{
949
+ std::cerr << " emitter told to stop" << std::endl;
947
950
emitter->stop ();
948
951
}
949
952
}
950
953
951
954
952
- DDS::ContentFilteredTopic* topicDesc =
953
- dynamic_cast <DDS::ContentFilteredTopic*>
954
- (dataReader->get_topicdescription ());
955
+ DDS::TopicDescription_var topic = dataReader->get_topicdescription ();
956
+ DDS::ContentFilteredTopic_var topicDesc = DDS::ContentFilteredTopic::_narrow (topic);
957
+
958
+ // We have to destroy the current data reader before building a new one
959
+ // The first step is to delete the contained entities (deletes all the ReadConditions and QueryConditions)
960
+ DDS::ReturnCode_t return_code = dataReader->delete_contained_entities ();
961
+ if (return_code != DDS::RETCODE_OK)
962
+ {
963
+ std::cerr << " dataReader failed on delete_contained_entities, return_code: " << return_code << std::endl;
964
+ return false ;
965
+ }
966
+
967
+ // Now delete the reader
968
+ return_code = subscriber->delete_datareader (dataReader);
969
+ dataReader = nullptr ;
970
+ if (return_code != DDS::RETCODE_OK)
971
+ {
972
+ std::cerr << " dataReader failed on delete_datareader, return_code: " << return_code << std::endl;
973
+ return false ;
974
+ }
955
975
976
+ std::string existingFilterName;
956
977
// Remove this content filtered topic from the domain if it exists
957
978
if (topicDesc && m_domainParticipant)
958
979
{
980
+ existingFilterName = topicDesc->get_name ();
981
+
982
+ std::cout << " existingFilterName " << existingFilterName << std::endl;
983
+
959
984
for (auto iter = topicGroup->filteredTopics .begin ();
960
985
iter != topicGroup->filteredTopics .end ();
961
986
++iter)
@@ -965,10 +990,17 @@ bool DDSManager::replaceFilter(const std::string& topicName,
965
990
continue ;
966
991
}
967
992
968
- m_domainParticipant->delete_contentfilteredtopic (topicDesc);
993
+ return_code = m_domainParticipant->delete_contentfilteredtopic (topicDesc);
994
+ if (return_code == DDS::RETCODE_OK)
995
+ {
969
996
iter->second = nullptr ;
970
997
topicDesc = nullptr ;
971
998
topicGroup->filteredTopics .erase (iter);
999
+ }
1000
+ else
1001
+ {
1002
+ std::cerr << " domain participant failed on delete_contentfilteredtopic, return_code: " << return_code << std::endl;
1003
+ }
972
1004
break ;
973
1005
}
974
1006
}
@@ -979,19 +1011,25 @@ bool DDSManager::replaceFilter(const std::string& topicName,
979
1011
subscriber->delete_datareader (dataReader);
980
1012
DDS::TopicDescription* targetTopic = nullptr ;
981
1013
982
-
983
1014
// Create a new filtered topic if requested
984
1015
if (!filter.empty ())
985
1016
{
986
1017
// The topic filter name must be unique or it will fail on the
987
1018
// second time it's created
988
- static int counter = 0 ;
1019
+ int counter = 0 ;
1020
+ if (!existingFilterName.empty ())
1021
+ {
1022
+ std::size_t found = existingFilterName.find_last_of (" _" );
1023
+ std::string count_string = existingFilterName.substr (found + 1 );
1024
+ counter = std::stoi (count_string);
1025
+ }
989
1026
++counter;
990
1027
const std::string filterName =
991
1028
topicName + " _" +
992
1029
readerName + " _" +
993
1030
std::to_string (counter);
994
1031
1032
+ // Create the content filter with no swappable params
995
1033
const DDS::StringSeq noParams;
996
1034
DDS::ContentFilteredTopic_var filteredTopic =
997
1035
m_domainParticipant->create_contentfilteredtopic (
@@ -1011,7 +1049,17 @@ bool DDSManager::replaceFilter(const std::string& topicName,
1011
1049
1012
1050
return false ;
1013
1051
}
1052
+ else
1053
+ {
1054
+ std::cerr << " Success in updating content filtered topic '"
1055
+ << topicName
1056
+ << " ' with the filter ["
1057
+ << filter
1058
+ << " ]"
1059
+ << std::endl;
1060
+ }
1014
1061
1062
+ // Save of content filter
1015
1063
topicGroup->filteredTopics [filterName] = filteredTopic;
1016
1064
targetTopic = filteredTopic;
1017
1065
}
@@ -1023,30 +1071,57 @@ bool DDSManager::replaceFilter(const std::string& topicName,
1023
1071
targetTopic = topicGroup->topic ;
1024
1072
}
1025
1073
1026
- // Create the new data reader
1074
+ // Create the new data reader, but first create a listener for it
1027
1075
auto readerListener = std::make_unique<GenericReaderListener>();
1028
1076
readerListener->SetHandler (m_rlHandler);
1029
- dataReader = topicGroup->subscriber ->create_datareader (
1030
- targetTopic,
1031
- topicGroup->dataReaderQos ,
1032
- readerListener.get (),
1033
- DDS::REQUESTED_INCOMPATIBLE_QOS_STATUS |
1034
- DDS::SUBSCRIPTION_MATCHED_STATUS |
1035
- DDS::SAMPLE_LOST_STATUS);
1036
1077
1037
- if (!dataReader )
1078
+ if (readerListener )
1038
1079
{
1039
- std::cerr << " Error creating data reader for '"
1040
- << topicName
1041
- << " '"
1042
- << std::endl;
1080
+ std::cerr << " Success in creating reader listener" << std::endl;
1081
+
1082
+ // move replaces the original listener with the new listener and since there is no longer an existing
1083
+ // reference to the orginial lister it deletes itself since it is a unique pointer.
1084
+ // This must be done here rather than after the new reader, otherwise there will be duplicate reader
1085
+ // listeners
1086
+
1087
+ auto rlEmplaceRes = topicGroup->m_readerListeners .emplace (readerName, std::move (readerListener));
1088
+
1089
+ // create the new data reader
1090
+
1091
+ dataReader = topicGroup->subscriber ->create_datareader (
1092
+ targetTopic,
1093
+ topicGroup->dataReaderQos ,
1094
+ rlEmplaceRes.first ->second .get (),
1095
+ DDS::INCONSISTENT_TOPIC_STATUS |
1096
+ DDS::REQUESTED_INCOMPATIBLE_QOS_STATUS |
1097
+ DDS::SUBSCRIPTION_MATCHED_STATUS |
1098
+ DDS::SAMPLE_LOST_STATUS);
1099
+
1100
+ if (!dataReader)
1101
+ {
1102
+ std::cerr << " Error creating data reader for '"
1103
+ << topicName
1104
+ << " '"
1105
+ << std::endl;
1043
1106
1107
+ return false ;
1108
+ }
1109
+ else
1110
+ {
1111
+ std::cerr << " Success in creating data reader for '"
1112
+ << topicName
1113
+ << " '"
1114
+ << std::endl;
1115
+ }
1116
+ }
1117
+ else
1118
+ {
1119
+ std::cerr << " Failure in creating reader listener" << std::endl;
1044
1120
return false ;
1045
1121
}
1046
1122
1047
1123
// Store the data reader with the reference name
1048
1124
topicGroup->readers [readerName] = dataReader;
1049
- topicGroup->m_readerListeners .emplace (readerName, std::move (readerListener));
1050
1125
lock.unlock ();
1051
1126
1052
1127
// Restart the emitter thread with the new reader if it existed
@@ -1060,6 +1135,78 @@ bool DDSManager::replaceFilter(const std::string& topicName,
1060
1135
1061
1136
} // End DDSManager::replaceFilter
1062
1137
1138
+ bool DDSManager::replaceFilterParams (const std::string& topicName,
1139
+ const std::string& readerName,
1140
+ const DDS::StringSeq &filterParams)
1141
+ {
1142
+
1143
+ // Make sure the data reader name is valid
1144
+ if (readerName.empty ())
1145
+ {
1146
+ std::cerr << " Error replacing topic filter for '"
1147
+ << topicName
1148
+ << " '. The reader name must not be empty."
1149
+ << std::endl;
1150
+
1151
+ return false ;
1152
+ }
1153
+
1154
+
1155
+ decltype (m_sharedLock) lock (m_topicMutex);
1156
+ // Has the subscriber already been registered?
1157
+ DDS::Subscriber_var subscriber = getSubscriber (topicName);
1158
+ if (!subscriber)
1159
+ {
1160
+ std::cerr << " Error replacing topic filter for '"
1161
+ << topicName
1162
+ << " '. The subscriber has not been created."
1163
+ << std::endl;
1164
+
1165
+ return false ;
1166
+ }
1167
+
1168
+ // Make sure this data reader exists
1169
+ DDS::DataReader_var dataReader = getReader (topicName, readerName);
1170
+ if (!dataReader)
1171
+ {
1172
+ std::cerr << " Error replacing topic filter for '"
1173
+ << topicName
1174
+ << " '. The data reader named '"
1175
+ << readerName
1176
+ << " ' does not exist."
1177
+ << std::endl;
1178
+
1179
+ return false ;
1180
+ }
1181
+
1182
+ // Get the ContentFilteredTopic
1183
+ std::shared_ptr<TopicGroup> topicGroup = m_topics[topicName];
1184
+
1185
+
1186
+ DDS::TopicDescription_var topic = dataReader->get_topicdescription ();
1187
+ DDS::ContentFilteredTopic_var topicDesc = DDS::ContentFilteredTopic::_narrow (topic);
1188
+ bool status = false ;
1189
+
1190
+ // Update this content filtered topic if it exists
1191
+ if (topicDesc)
1192
+ {
1193
+ for (auto iter = topicGroup->filteredTopics .begin ();
1194
+ iter != topicGroup->filteredTopics .end ();
1195
+ ++iter)
1196
+ {
1197
+ if (topicDesc == iter->second )
1198
+ {
1199
+ if (iter->second ->set_expression_parameters (filterParams) == DDS::RETCODE_OK)
1200
+ {
1201
+ status = true ;
1202
+ }
1203
+ break ;
1204
+ }
1205
+ }
1206
+ }
1207
+ return status;
1208
+ }
1209
+
1063
1210
1064
1211
// ------------------------------------------------------------------------------
1065
1212
bool DDSManager::setMaxDataRate (const std::string& topicName,
0 commit comments