Files
qt-migration-legatus/qt5-before/dlbo/Lts/Tools/TopicDiscover/topic_discoverer.cpp
T
torstenandCopilot 7173785915 Qt6 Migration: Complete migration with DDS/RTI support and build validation
Major Changes:
- Merged latest Qt5 devel content from dlbo (292 files changed, 7 new dirs)
- Consolidated forward-declarations and include folders
- Removed unneeded modules per Niklas' repo check list

Build System Fixes:
- Fixed CMake VERSION_GREATER syntax in ParticipantManagement/CMakeLists.txt
- Added VLC packages (libvlc-dev, vlc-plugin-base) to docker_build.sh
- Added PostgreSQL dev packages (libpq-dev, postgresql-server-dev-all) to Dockerfile
- Fixed locale warnings (ANSI_X3.4-1968 → C.UTF-8)
- Fixed ArcGIS SDK path warnings when BUILD_ARCGIS=OFF

Code Generation Fixes:
- Fixed IDL enum collisions (PortType→CorePortType/DdsutPortType, PdmEventType)
- Fixed Grantlee template svc_translation.cpp.grantlee:
  - Changed {{ idl_enum.name }}_def:: to {{ idl_enum.name }}::
  - Fixed .underlying() calls for C++11 scoped enums (enum class)
- Removed generated files from repo (moc_*, *_dtc.h, *_ftc.h)

Validation:
- BUILD_RTI=ON: SUCCESS
- BUILD_RTI=OFF: SUCCESS
- C++17 standard maintained for RTI 7.7 compatibility
- Ubuntu 26.04 Docker environment verified

Remaining Warnings (expected):
- BgViewer, KDChart, KDReports, Poppler-Qt6 not found (optional features)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-15 18:20:26 +00:00

195 lines
6.8 KiB
C++

#include "topic_discoverer.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QCoreApplication>
#include <DDS/QosProfile/DDS_DefaultQos.h>
BuiltinAnyListener::BuiltinAnyListener(QObject *parent)
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TopicDiscoverer.BuiltinAnyListener"))
{
Q_UNUSED(parent)
}
dds::core::xtypes::StructType BuiltinAnyListener::structType(const std::string &typeName)
{
QReadLocker l(&m_safeTypeLock);
return m_structTypes.value(typeName, dds::core::xtypes::StructType("NULL"));
}
// This gets called when a participant has been discovered
template <typename S>
void BuiltinAnyListener::on_data_available(dds::sub::DataReader<S> &reader)
{
// We only process newly seen participants
dds::sub::LoanedSamples<S> samples
= reader.select().state(dds::sub::status::DataState::new_instance()).take();
for (typename dds::sub::LoanedSamples<S>::iterator sampleIt = samples.begin();
sampleIt != samples.end();
++sampleIt)
{
if (!sampleIt->info().valid())
continue;
const std::string &topicName = sampleIt->data().topic_name();
const std::string &typeName = sampleIt->data().type_name();
if (QString::fromStdString(typeName).contains(QLatin1String("rti::"), Qt::CaseInsensitive))
continue;
dds::core::optional<dds::core::xtypes::DynamicType> dynamicType = sampleIt->data()->type();
if (!dynamicType.is_set() || dynamicType.get().kind() != dds::core::xtypes::TypeKind::STRUCTURE_TYPE)
continue;
const dds::core::xtypes::StructType &structType = static_cast<dds::core::xtypes::StructType&>(dynamicType.get());
DEBUG_LOG(m_logger) << "Built-in Reader: found subscriber: "
<< " topicName: " << topicName
<< " topicType: " << typeName
;
{
QWriteLocker l(&m_safeTypeLock);
m_structTypes.insert(typeName, structType);
}
emit topicDescription(topicName, typeName);
}
}
/***********************************************************************************************/
BuiltinPublicationListener::BuiltinPublicationListener(QObject *parent)
: BuiltinAnyListener(parent)
{
}
void BuiltinPublicationListener::on_data_available(dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> &reader)
{
BuiltinAnyListener::on_data_available(reader);
}
/***********************************************************************************************/
BuiltinSubscriberListener::BuiltinSubscriberListener(QObject *parent)
: BuiltinAnyListener(parent)
{
}
void BuiltinSubscriberListener::on_data_available(dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> &reader)
{
BuiltinAnyListener::on_data_available(reader);
}
/***********************************************************************************************/
TopicDiscoverer::TopicDiscoverer(int domainId, QObject *parent)
: QObject(parent)
, m_domainId(domainId)
, m_domainParticipant(nullptr)
, m_publisherListener(nullptr)
, m_subscriberListener(nullptr)
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TopicDiscoverer"))
{
qRegisterMetaType<std::string>("std::string");
}
void TopicDiscoverer::init(DDS::QosProfile::ConnectionType ct, const QUrl &tcpDiscoveryUrl)
{
// make sure to get the same qos as a normal dp/publisher/subscriber
DDS::QosProfile::setDefault();
// By default, the participant is enabled upon construction.
// At that time our listeners for the builtin topics have not
// been installed, so we disable the participant until we
// set up the listeners.
dds::domain::qos::DomainParticipantFactoryQos factoryQos =
dds::domain::DomainParticipant::participant_factory_qos();
factoryQos << dds::core::policy::EntityFactory::ManuallyEnable();
dds::domain::DomainParticipant::participant_factory_qos(factoryQos);
// Create a DomainParticipant with given Qos.
m_domainParticipant = dds::domain::DomainParticipant(m_domainId, DDS::QosProfile::domainParticipantDefault(ct, tcpDiscoveryUrl));
dds::domain::qos::DomainParticipantQos dpQos = m_domainParticipant.qos();
rti::core::policy::EntityName entityName;
entityName.name(QString(qAppName() +
QStringLiteral(" - DP ") +
QString::number(m_domainId)
).toStdString());
dpQos << entityName;
m_domainParticipant.qos(dpQos);
// Installing listeners for the builtin topics requires several steps
// First get the builtin subscriber.
dds::sub::Subscriber builtin_subscriber = dds::sub::builtin_subscriber(m_domainParticipant);
// Get builtin subscriber's datareader for publishers.
std::vector< dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> > publication_reader;
dds::sub::find< dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> >
(
builtin_subscriber,
dds::topic::publication_topic_name(),
std::back_inserter(publication_reader)
);
BuiltinPublicationListener *bipl = new BuiltinPublicationListener(this);
// Install our listener using ListenerBinder.
m_publisherListener = rti::core::bind_and_manage_listener(publication_reader[0],
bipl,
dds::core::status::StatusMask::data_available()
);
connect(bipl, &BuiltinPublicationListener::topicDescription,
this, &TopicDiscoverer::onTopicDescription);
/*------------------------------*/
// Get builtin subscriber's datareader for subscribers.
std::vector< dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> > subscription_reader;
dds::sub::find< dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> >
(
builtin_subscriber,
dds::topic::subscription_topic_name(),
std::back_inserter(subscription_reader)
);
BuiltinSubscriberListener *bisl = new BuiltinSubscriberListener(this);
// Install our listener using ListenerBinder.
m_subscriberListener = rti::core::bind_and_manage_listener(subscription_reader[0],
bisl,
dds::core::status::StatusMask::data_available()
);
connect(bisl, &BuiltinSubscriberListener::topicDescription,
this, &TopicDiscoverer::onTopicDescription);
/*------------------------------*/
// Done! All the listeners are installed, so we can enable the
// participant now.
m_domainParticipant.enable();
}
void TopicDiscoverer::onTopicDescription(const std::string &topicName,
const std::string &typeName)
{
INFO_LOG(m_logger) << "Built-in Reader: found Topic: "
<< " topicName: " << topicName
<< " typeName: " << typeName
;
BuiltinAnyListener* bal = qobject_cast<BuiltinAnyListener*>(sender());
if (!bal)
return;
dds::core::xtypes::StructType type = bal->structType(typeName);
if (type.name() != "NULL")
emit topicDescription(topicName, typeName, type);
}