From b656e1aaa955d7cce2647b9834dd8ef74da70e1b Mon Sep 17 00:00:00 2001 From: twi-devel Date: Sun, 6 Sep 2026 18:45:59 +0200 Subject: [PATCH] Resolves latest issues in Lts/Common Lts/DDS --- qt6-after/qt6-migrated-legatus/CMakeLists.txt | 23 +- .../Lts/Common/CodeGen/CMakeLists.txt | 1 + .../Common/CodeGen/GeneratorGrantleeBase.cpp | 4 + .../Lts/Common/CodeGen/GrantleeWrappers.cpp | 8 +- .../Lts/Common/CodeGen/StructBuilder.cpp | 8 +- .../Lts/Common/LtsSession/CMakeLists.txt | 2 + .../LtsSession/lts_session_data_dds.cpp | 46 ++- .../Common/LtsSession/lts_session_data_dds.h | 89 ++++- .../LtsUtils/LtsUtilsCore/CMakeLists.txt | 8 +- .../Lts/DDS/Core/CMakeLists.txt | 19 +- .../Lts/DDS/DDSConnector/CMakeLists.txt | 2 +- .../Lts/DDS/DTC/generic_dtc_impl.h | 1 + .../Lts/DDS/FTC/generic_ftc_impl.h | 4 +- .../Lts/DDS/FTS/connext.h | 2 +- .../Lts/DDS/Generic/generic_data_reader.h | 2 +- .../Lts/DDS/QosProfile/CMakeLists.txt | 2 +- .../Lts/DDS/Routing/routing_plugin.h | 2 +- .../Trajectory/trajectory_generator_vulcano.h | 2 +- .../qt6-migrated-legatus/cmake/FindRTI.cmake | 9 +- .../cmake/MacroCodeGenIdl.cmake | 8 +- .../DDS/Core/{core.hpp => core.hpp.stub} | 0 ...core_dtc_types.h => core_dtc_types.h.stub} | 0 .../include/DDS/DTC/generic_dtc.h | 24 +- .../include/DDS/DTC/generic_dtc_impl.h | 318 ++++++++++++++++++ .../qt6-migrated-legatus/rti_license.dat | 0 25 files changed, 537 insertions(+), 47 deletions(-) rename qt6-after/qt6-migrated-legatus/include/DDS/Core/{core.hpp => core.hpp.stub} (100%) rename qt6-after/qt6-migrated-legatus/include/DDS/Core/{core_dtc_types.h => core_dtc_types.h.stub} (100%) create mode 100755 qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc_impl.h create mode 100644 qt6-after/qt6-migrated-legatus/rti_license.dat diff --git a/qt6-after/qt6-migrated-legatus/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/CMakeLists.txt index d5fe5d307..c2fc036a0 100755 --- a/qt6-after/qt6-migrated-legatus/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/CMakeLists.txt @@ -96,7 +96,7 @@ include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsCore) include_directories(${CMAKE_SOURCE_DIR}/include/Viewer/SituationMap) include_directories(${CMAKE_SOURCE_DIR}/include/OperatorManagement) include_directories(${CMAKE_SOURCE_DIR}/include/FileManagement) -SET(CMAKE_CXX_STANDARD 23) +SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON) SET(CMAKE_CXX_VISIBILITY_PRESET hidden) @@ -222,7 +222,7 @@ endif() # Find Qt6 core components first (without OpenGL which may not be available) find_package(Qt6 6.2 COMPONENTS Concurrent Core LinguistTools Network - Multimedia Sql SerialPort Test Xml Positioning QUIET) + Multimedia Sql SerialPort Test Xml Positioning Svg QUIET) if(Qt6_FOUND) # Skip GUI find_package - it fails without OpenGL. We'll create manual targets below. @@ -336,14 +336,7 @@ if(NOT TARGET Qt6::Test AND EXISTS "${QT6_LIB_DIR}/libQt6Test.so.6") message(STATUS "Manually configured Qt6 Test target") endif() -# Stub Qt6::Svg target if not available (needed by multiple plugins) -if(NOT TARGET Qt6::Svg) - add_library(Qt6::Svg INTERFACE IMPORTED) - set_target_properties(Qt6::Svg PROPERTIES - INTERFACE_COMPILE_DEFINITIONS "QT_NO_SVG" - ) - message(STATUS "Created stub target for Qt6::Svg (library not available)") -endif() +# Qt6::Svg target should be found by find_package above # Stub Qt6::Multimedia target if not available (needed by OscSystemGuiPlugin, etc.) if(NOT TARGET Qt6::Multimedia) @@ -423,7 +416,15 @@ MESSAGE(STATUS "Qt version is ${Qt6Core_VERSION}, GUI available: ${QT6_GUI_AVAIL # RTI Connext DDS - manuelle Konfiguration da keine CMake Config Files vorhanden # IF(BUILD_RTI) - SET(RTI_INSTALL_DIR "/repo/external/rti_connext_dds-7.7.0" CACHE PATH "RTI Connext DDS installation directory") + # Support environment variable override, otherwise use relative path from repo root + IF(DEFINED ENV{DDS_PATH}) + SET(RTI_INSTALL_DIR "$ENV{DDS_PATH}" CACHE PATH "RTI Connext DDS installation directory") + ELSE() + # CMAKE_SOURCE_DIR is qt6-migrated-legatus, RTI is at ../../../external/ + SET(RTI_INSTALL_DIR "${CMAKE_SOURCE_DIR}/../../../external/rti_connext_dds-7.7.0" CACHE PATH "RTI Connext DDS installation directory") + ENDIF() + # Also set RTI_DIR for FindRTI.cmake compatibility (used by subdirectories) + SET(RTI_DIR "${RTI_INSTALL_DIR}" CACHE PATH "RTI base path" FORCE) IF(EXISTS "${RTI_INSTALL_DIR}") SET(RTI_LIB_DIR "${RTI_INSTALL_DIR}/lib/x64Linux4gcc8.5.0") SET(RTI_INCLUDE_DIR "${RTI_INSTALL_DIR}/include/ndds/hpp") diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/CMakeLists.txt index fddd7a238..838ee46e6 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/CMakeLists.txt @@ -146,6 +146,7 @@ IF(BUILD_GRANTLEE AND TARGET KF6::TextTemplate) LtsCommandLineParser nglcoreapplication Qt6::Core + KF6::TextTemplate ) NGL_WRAP_UI(codegen_gui_uics diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GeneratorGrantleeBase.cpp b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GeneratorGrantleeBase.cpp index 11ffdcf20..a43ef7a31 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GeneratorGrantleeBase.cpp +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GeneratorGrantleeBase.cpp @@ -17,6 +17,10 @@ GeneratorGrantleeBase::GeneratorGrantleeBase(const char* loggerName) , m_structBuilder(nullptr) , m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName)) { + // Add KTextTemplate plugin path for loading default tags/filters + // KTextTemplate plugins are in /usr/lib/x86_64-linux-gnu/qt6/plugins/kf6/ktexttemplate + // QT_PLUGIN_PATH should point to the parent directory containing the category folders + m_engine->addPluginPath(QStringLiteral("/usr/lib/x86_64-linux-gnu/qt6/plugins")); } GeneratorGrantleeBase::~GeneratorGrantleeBase() diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GrantleeWrappers.cpp b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GrantleeWrappers.cpp index 57d0d5aa4..584d62d87 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GrantleeWrappers.cpp +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/GrantleeWrappers.cpp @@ -12,11 +12,11 @@ QString IdlStructWrapper::extensibility2String(dds::core::xtypes::ExtensibilityK { switch (extensiblity.underlying()) { - case dds::core::xtypes::ExtensibilityKind_def::FINAL: + case dds::core::xtypes::ExtensibilityKind_def::type::FINAL: return QStringLiteral("FINAL_EXTENSIBILITY"); - case dds::core::xtypes::ExtensibilityKind_def::MUTABLE: + case dds::core::xtypes::ExtensibilityKind_def::type::MUTABLE: return QStringLiteral("MUTABLE_EXTENSIBILITY"); - case dds::core::xtypes::ExtensibilityKind_def::EXTENSIBLE: + case dds::core::xtypes::ExtensibilityKind_def::type::EXTENSIBLE: return QStringLiteral("EXTENSIBLE_EXTENSIBILITY"); } Q_ASSERT_X(false, "IdlStructWrapper::extensibility2String", "Unknown extensiblity kind"); @@ -71,7 +71,7 @@ QString MemberInformationWrapper::ddsToJsonElement() const const QString getValue = isCppStruct() ? cppMemberName() : cppMemberName() + QStringLiteral("()"); return QStringLiteral("if (element.") + optionalAccess + QStringLiteral(") ") + QStringLiteral("obj[QStringLiteral(\"") + cppMemberName() + QStringLiteral("\")] = ") + cppToJsonPre() + - QStringLiteral("element.") + getValue + cppToJsonPost(); + QStringLiteral("*element.") + getValue + cppToJsonPost(); } QString MemberInformationWrapper::jsonElementToDds() const diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/StructBuilder.cpp b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/StructBuilder.cpp index 1edd5900c..0ba176854 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/StructBuilder.cpp +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/CodeGen/StructBuilder.cpp @@ -856,10 +856,12 @@ bool StructBuilder::fixupQVariantConversions(MemberInformation& mi) const svcName += QStringLiteral("::"); mi.cpp.type = svcName + mi.enumeration->enumName; mi.cpp.fromVariantPre2 = - QStringLiteral("static_cast<") + svcName + mi.enumeration->enumName + QStringLiteral("_def::type>("); + QStringLiteral("static_cast<") + svcName + mi.enumeration->enumName + QStringLiteral(">("); mi.cpp.fromVariantPost = QStringLiteral(".toInt())"); mi.cpp.toVariantPre = QStringLiteral("static_cast("); - mi.cpp.toVariantPost = QStringLiteral(".underlying())"); + mi.cpp.toVariantPost.clear(); + mi.cpp.toJsonPre = QStringLiteral("toJson(static_cast("); + mi.cpp.toJsonPost = QStringLiteral("))"); if (!mi.enumeration->values.isEmpty()) { mi.cpp.defaultValue = @@ -874,6 +876,8 @@ bool StructBuilder::fixupQVariantConversions(MemberInformation& mi) const mi.cpp.type = QStringLiteral("qint64"); mi.cpp.fromVariantPost = QStringLiteral(".toLongLong()"); mi.cpp.fromJsonPost = QStringLiteral(".toDouble()"); + mi.cpp.toJsonPre = QStringLiteral("static_cast("); + mi.cpp.toJsonPost = QStringLiteral(")"); mi.cpp.defaultValue = QLatin1Char('0'); } else if (datatype == QLatin1String("boolean") || datatype == QLatin1String("bool")) diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/CMakeLists.txt index 6622ef302..a0c44d7f2 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/CMakeLists.txt @@ -49,6 +49,7 @@ NGL_TARGET_LINK_LIBRARIES(LtsSessionDataDds $<$:$,ddsconnector,>> PUBLIC $<$:nddscore> + $<$:ddsQoS> NGLLogger Qt6::Core ) @@ -56,6 +57,7 @@ IF(BUILD_RTI) NGL_TARGET_INCLUDE_DIRECTORIES(LtsSessionDataDds PUBLIC ${RTI_INCLUDE_DIR} + ${CMAKE_SOURCE_DIR}/Lts ) NGL_TARGET_LINK_DIRECTORIES(LtsSessionDataDds PRIVATE diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.cpp b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.cpp index b89868c4e..ffe7826a4 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.cpp +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.cpp @@ -13,12 +13,37 @@ #ifdef BUILD_RTI #include #include -#include +#include +#include #include #include #include #include +namespace +{ +// Convert LtsSession::PartitionType to IDL::PartitionType +IDL::PartitionType toIdlPartitionType(LtsSession::PartitionType type) +{ + switch (type) + { + case LtsSession::PartitionType::Any: + return IDL::PartitionType::Any; + case LtsSession::PartitionType::Global: + return IDL::PartitionType::Global; + case LtsSession::PartitionType::Exercise: + return IDL::PartitionType::Exercise; + case LtsSession::PartitionType::AllExercises: + return IDL::PartitionType::AllExercises; + case LtsSession::PartitionType::Replay: + return IDL::PartitionType::Replay; + case LtsSession::PartitionType::Invalid: + default: + return IDL::PartitionType::Any; + } +} +} // namespace + namespace LtsSession { /** @@ -217,7 +242,7 @@ bool LtsSessionDataDds::init(const DdsConnectionParams& connParams) #endif m_ddsConnector = std::make_shared( - connParams.domainId, connParams.partitionType, connParams.partitionId, + connParams.domainId, toIdlPartitionType(connParams.partitionType), connParams.partitionId, connParams.exerciseId, // same as partition Id in live but not in replay type); s_ddsConnections()->insertConnection(connParams, m_ddsConnector); @@ -252,7 +277,7 @@ bool LtsSessionDataDds::init(const dds::domain::DomainParticipant& dp, const Dds if (m_ddsConnector == nullptr) { m_ddsConnector = - std::make_shared(dp, connParams.partitionType, type, connParams.partitionId); + std::make_shared(dp, toIdlPartitionType(connParams.partitionType), type, connParams.partitionId); s_ddsConnections()->insertConnection(connParams, m_ddsConnector); } @@ -286,6 +311,19 @@ QString LtsSessionDataDds::partitionTypeString(PartitionType partitionType) return QStringLiteral("Invalid (%1)").arg(int(partitionType)); } +LtsSession::PartitionType LtsSessionDataDds::toPartitionType(IDL::PartitionType idlType) +{ + switch (idlType) + { + case IDL::PartitionType::Any: return PartitionType::Any; + case IDL::PartitionType::Exercise: return PartitionType::Exercise; + case IDL::PartitionType::Replay: return PartitionType::Replay; + case IDL::PartitionType::AllExercises: return PartitionType::AllExercises; + case IDL::PartitionType::Global: return PartitionType::Global; + default: return PartitionType::Invalid; + } +} + QString LtsSessionDataDds::toString() const { return QStringLiteral("(LtsSessionDataDds: id=%1, partitionId=%2, partitionType=%3(%4), exerciseId=%5)") @@ -313,7 +351,7 @@ int LtsSessionDataDds::partitionId() const PartitionType LtsSessionDataDds::partitionType() const { - return m_ddsConnector ? m_ddsConnector->getPartitionType() : PartitionType::Global; + return m_ddsConnector ? toPartitionType(m_ddsConnector->getPartitionType()) : PartitionType::Global; } QStringList LtsSessionDataDds::qosFile() const diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.h b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.h index bb287c609..205bed2bc 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.h +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.h @@ -23,14 +23,15 @@ #ifdef BUILD_RTI #include #include "INGLLogger.h" +#include "DDS/Core/core_dtc_types.h" namespace DDSConnector { class DdsConnector; } namespace DTC { template class GenericDTCImpl; } -namespace Core { struct PartitionTime; } namespace DataPluginBase { class Interface; } -class Fetcher; +namespace GuiPluginBase { class Interface; } #else // Forward declarations for stub types namespace DataPluginBase { class Interface; } +namespace GuiPluginBase { class Interface; } #endif namespace LtsSession @@ -46,6 +47,8 @@ enum class PartitionType { Invalid = -1 }; +class Fetcher; + struct DdsConnectionParams { int domainId = -1; @@ -150,6 +153,26 @@ class LTSSESSIONDATADDS_EXPORT LtsSessionDataDds : public QObject template bool getDtc(std::shared_ptr &val) const; + // Foreign GUI interface retrieval - used by Fetcher helper class + template + bool getForeignGuiInterface(std::shared_ptr &val) const + { +#ifdef BUILD_RTI + for (const auto &i : m_guiPluginInterfaces) + { + val = std::dynamic_pointer_cast(i); + if (val) + return true; + } + val.reset(); + if (m_logger.isDebug()) + m_logger.debug() << "Cannot find foreign gui ifc " << typeid(S).name() << " in " << toString(); +#else + val.reset(); +#endif + return false; + } + signals: void partitionTimeChanged(qint64 newPartitionTime); void partitionTimeChangedInternal(); @@ -158,6 +181,7 @@ class LTSSESSIONDATADDS_EXPORT LtsSessionDataDds : public QObject #ifdef BUILD_RTI bool initInternal(); void onPartitionTimeChangedInternal(); + static LtsSession::PartitionType toPartitionType(IDL::PartitionType idlType); // Member variables - only with RTI int m_exerciseId; @@ -170,6 +194,8 @@ class LTSSESSIONDATADDS_EXPORT LtsSessionDataDds : public QObject std::shared_ptr> m_dtcPartitionTime; NGL::INGLLogger& m_logger; QMap> m_dataPluginInterfaces; + QMap> m_guiPluginInterfaces; + QStringList m_qosFileList; #else // Stub implementation - minimal members bool initInternal(); @@ -183,6 +209,65 @@ class LTSSESSIONDATADDS_EXPORT LtsSessionDataDds : public QObject #endif }; +#ifdef BUILD_RTI +class Fetcher +{ +public: + Fetcher(LtsSessionDataDds *sessionDataDds, const QString &caller) + : m_sessionDataDds(sessionDataDds) + , m_errors(false) + , m_caller(caller) + , m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsSession.Fetcher")) + , m_optional(false) + { + + } + + LtsSessionDataDds *m_sessionDataDds; + bool m_errors; + QString m_caller; + QString m_whatWillNotWork; + NGL::INGLLogger &m_logger; + bool m_optional; + QString m_resultType; + QString m_getterFunctionType; + + template + void getForeignGuiInterface(std::shared_ptr &foreignGuiInterface, const QString &whatWillNotWork /* only fill if optional */, bool optional) + { + if (!m_sessionDataDds->getForeignGuiInterface(foreignGuiInterface)) + { + m_whatWillNotWork = whatWillNotWork; + m_optional = optional; + m_resultType = QString::fromUtf8(typeid(ForeignGuiInterface).name()); + m_getterFunctionType = QStringLiteral("gui interface"); + print(); + } + } + + bool status() const + { + return !m_errors; + } + + void print() + { + m_errors = true; + + QString msg(QStringLiteral("%1 cannot find '%2' in %3 %4")); + + if (m_optional) + { + INFO_LOG(m_logger) << msg.arg(m_caller, m_resultType, m_sessionDataDds->toString(), QStringLiteral("' - optional but %1 will not work").arg(m_whatWillNotWork)); + } + else // critical + { + ERROR_LOG(m_logger) << msg.arg(m_caller, m_resultType, m_sessionDataDds->toString(), QStringLiteral(" which is required")); + } + } +}; +#endif + } // namespace LtsSession // Template method implementations - must be in header diff --git a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsUtils/LtsUtilsCore/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsUtils/LtsUtilsCore/CMakeLists.txt index 65c2c48f4..1db443f8b 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/Common/LtsUtils/LtsUtilsCore/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/Lts/Common/LtsUtils/LtsUtilsCore/CMakeLists.txt @@ -20,8 +20,8 @@ SET(SRCS_hdr_only ADD_LIBRARY(LtsUtilsCoreHeaderOnly INTERFACE) TARGET_INCLUDE_DIRECTORIES(LtsUtilsCoreHeaderOnly INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${CMAKE_CURRENT_BINARY_DIR}/../.. + ${CMAKE_CURRENT_SOURCE_DIR}/../ + ${CMAKE_CURRENT_BINARY_DIR}/../ ) TARGET_SOURCES(LtsUtilsCoreHeaderOnly INTERFACE ${SRCS_hdr_only}) @@ -40,8 +40,8 @@ SET(SRCS NGL_ADD_LIBRARY2(ALL LtsUtilsCore SHARED ${SRCS}) NGL_TARGET_INCLUDE_DIRECTORIES(LtsUtilsCore PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/../.. - ${CMAKE_CURRENT_BINARY_DIR}/../.. + ${CMAKE_CURRENT_SOURCE_DIR}/../ + ${CMAKE_CURRENT_BINARY_DIR}/../ ) NGL_TARGET_LINK_LIBRARIES(LtsUtilsCore PUBLIC diff --git a/qt6-after/qt6-migrated-legatus/Lts/DDS/Core/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/Lts/DDS/Core/CMakeLists.txt index 40a327b88..5907c69ee 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/DDS/Core/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/Lts/DDS/Core/CMakeLists.txt @@ -37,12 +37,29 @@ CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE}) # generate core_[d|f]tc.h CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE}) +# Get the generated core_dtc.h path for manual MOC handling +SET(CORE_DTC_H_GENERATED "${CMAKE_CURRENT_BINARY_DIR}/core_dtc.h") + NGL_ADD_LIBRARY2(WS AAR HLA SV ddscore SHARED ${SRCS_common}) + +# Skip AUTOMOC for generated header - it will be processed manually with correct dependencies +SET_SOURCE_FILES_PROPERTIES(${CORE_DTC_H_GENERATED} PROPERTIES SKIP_AUTOMOC ON) + +# Ensure AUTOMOC can find generated headers - add include path +TARGET_INCLUDE_DIRECTORIES(ddscore + PUBLIC + ${CMAKE_CURRENT_BINARY_DIR}/../../ +) NGL_TARGET_INCLUDE_DIRECTORIES(ddscore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../ - ${CMAKE_CURRENT_BINARY_DIR}/../../ ) + +# Manually add MOC for the generated core_dtc.h with proper include paths +QT6_WRAP_CPP(ddscore_moc_sources ${CORE_DTC_H_GENERATED} + OPTIONS --include core_dtc.h -I${CMAKE_CURRENT_BINARY_DIR}/../.. -I${CMAKE_CURRENT_SOURCE_DIR}/../.. +) +TARGET_SOURCES(ddscore PRIVATE ${ddscore_moc_sources}) IF(BUILD_RTI) NGL_TARGET_LINK_LIBRARIES(ddscore PRIVATE diff --git a/qt6-after/qt6-migrated-legatus/Lts/DDS/DDSConnector/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/Lts/DDS/DDSConnector/CMakeLists.txt index 4a9c52b7f..92f4818de 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/DDS/DDSConnector/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/Lts/DDS/DDSConnector/CMakeLists.txt @@ -20,7 +20,7 @@ SET(SRCS NGL_ADD_LIBRARY2(AAR SV WS HLA ddsconnector SHARED ${SRCS}) NGL_TARGET_INCLUDE_DIRECTORIES(ddsconnector - INTERFACE + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../ ${CMAKE_SOURCE_DIR} ) diff --git a/qt6-after/qt6-migrated-legatus/Lts/DDS/DTC/generic_dtc_impl.h b/qt6-after/qt6-migrated-legatus/Lts/DDS/DTC/generic_dtc_impl.h index 7cac03ea6..a1d32f909 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/DDS/DTC/generic_dtc_impl.h +++ b/qt6-after/qt6-migrated-legatus/Lts/DDS/DTC/generic_dtc_impl.h @@ -5,6 +5,7 @@ #include "generic_dtc.h" #include +#include #include #include #include diff --git a/qt6-after/qt6-migrated-legatus/Lts/DDS/FTC/generic_ftc_impl.h b/qt6-after/qt6-migrated-legatus/Lts/DDS/FTC/generic_ftc_impl.h index 510c62367..e3f6ae54b 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/DDS/FTC/generic_ftc_impl.h +++ b/qt6-after/qt6-migrated-legatus/Lts/DDS/FTC/generic_ftc_impl.h @@ -475,7 +475,7 @@ class GenericFtcImpl final : public GenericFtc class GenericDataReaderContentFilter final : publi { qint64 ptr = reinterpret_cast(this); const QByteArray name = QByteArray(DDS::topic_type_name::value().c_str()) + - "- content filter 0x" + QByteArray::number(ptr, 16); + "- content filter 0x" + QString::number(ptr, 16).toLatin1(); m_filteredTopic = dds::topic::ContentFilteredTopic(BaseClass::m_ddsTopic, name.data(), m_filter); BaseClass::m_dataReader = DataReader(ddsSubscriber, m_filteredTopic); } diff --git a/qt6-after/qt6-migrated-legatus/Lts/DDS/QosProfile/CMakeLists.txt b/qt6-after/qt6-migrated-legatus/Lts/DDS/QosProfile/CMakeLists.txt index 1bb749af5..3f9de4581 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/DDS/QosProfile/CMakeLists.txt +++ b/qt6-after/qt6-migrated-legatus/Lts/DDS/QosProfile/CMakeLists.txt @@ -24,7 +24,7 @@ ENDIF() NGL_ADD_LIBRARY2(AAR SV HLA WS ddsQoS SHARED ${SRCS}) NGL_TARGET_INCLUDE_DIRECTORIES(ddsQoS INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR}/../../../ + ${CMAKE_CURRENT_SOURCE_DIR}/../../ ) NGL_TARGET_LINK_LIBRARIES(ddsQoS PRIVATE diff --git a/qt6-after/qt6-migrated-legatus/Lts/DDS/Routing/routing_plugin.h b/qt6-after/qt6-migrated-legatus/Lts/DDS/Routing/routing_plugin.h index 76dfd4451..309c645c6 100644 --- a/qt6-after/qt6-migrated-legatus/Lts/DDS/Routing/routing_plugin.h +++ b/qt6-after/qt6-migrated-legatus/Lts/DDS/Routing/routing_plugin.h @@ -21,7 +21,7 @@ static inline QByteArray toReadable(const rti::core::Guid& guid) static inline QByteArray toReadable(const rti::core::SequenceNumber& seqNo, const rti::core::Guid& guid) { - return "SeqNo: " + QByteArray::number(seqNo.value()) + ", Guid-DW: " + toReadable(guid); + return "SeqNo: " + QString::number(seqNo.value()).toLatin1() + ", Guid-DW: " + toReadable(guid); } static inline QByteArray toReadable(const rti::core::SampleIdentity& identiy) diff --git a/qt6-after/qt6-migrated-legatus/Lts/Services/AreaEffectSimulation/Trajectory/trajectory_generator_vulcano.h b/qt6-after/qt6-migrated-legatus/Lts/Services/AreaEffectSimulation/Trajectory/trajectory_generator_vulcano.h index 5ac316dd7..ed8be74e4 100755 --- a/qt6-after/qt6-migrated-legatus/Lts/Services/AreaEffectSimulation/Trajectory/trajectory_generator_vulcano.h +++ b/qt6-after/qt6-migrated-legatus/Lts/Services/AreaEffectSimulation/Trajectory/trajectory_generator_vulcano.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include // std::setprecision diff --git a/qt6-after/qt6-migrated-legatus/cmake/FindRTI.cmake b/qt6-after/qt6-migrated-legatus/cmake/FindRTI.cmake index 63821b87c..5da0938fe 100755 --- a/qt6-after/qt6-migrated-legatus/cmake/FindRTI.cmake +++ b/qt6-after/qt6-migrated-legatus/cmake/FindRTI.cmake @@ -29,7 +29,8 @@ SET(_rti_gcc_arch "") -IF(NOT RTI_DIR) +# Check if RTI_DIR is not set OR is empty (cached empty string from previous failed detection) +IF(NOT RTI_DIR OR RTI_DIR STREQUAL "") SET(_arch "unknown") IF(WIN32) SET(_RTI_DIR $ENV{DDS_PATH}) @@ -63,8 +64,10 @@ IF(NOT RTI_DIR) ELSE(WIN32) SET(_RTI_DIR $ENV{DDS_PATH}) IF(NOT _RTI_DIR) - # Try local external directory first - IF(EXISTS "${CMAKE_SOURCE_DIR}/../external/rti_connext_dds-7.7.0") + # Try local external directory first (check multiple levels for different repo structures) + IF(EXISTS "${CMAKE_SOURCE_DIR}/../../../external/rti_connext_dds-7.7.0") + SET(_RTI_DIR "${CMAKE_SOURCE_DIR}/../../../external/rti_connext_dds-7.7.0") + ELSEIF(EXISTS "${CMAKE_SOURCE_DIR}/../external/rti_connext_dds-7.7.0") SET(_RTI_DIR "${CMAKE_SOURCE_DIR}/../external/rti_connext_dds-7.7.0") ELSEIF(EXISTS "${CMAKE_SOURCE_DIR}/external/rti_connext_dds-7.7.0") SET(_RTI_DIR "${CMAKE_SOURCE_DIR}/external/rti_connext_dds-7.7.0") diff --git a/qt6-after/qt6-migrated-legatus/cmake/MacroCodeGenIdl.cmake b/qt6-after/qt6-migrated-legatus/cmake/MacroCodeGenIdl.cmake index 171202061..d4f4c00ce 100755 --- a/qt6-after/qt6-migrated-legatus/cmake/MacroCodeGenIdl.cmake +++ b/qt6-after/qt6-migrated-legatus/cmake/MacroCodeGenIdl.cmake @@ -56,9 +56,10 @@ MACRO(_CODEGEN_ACTION action srcList xmlIn in_files out_files) - SET(_cg ngl_codegen) + SET(_cg $) + SET(_env "QT_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/qt6/plugins/kf6/ktexttemplate") ADD_CUSTOM_COMMAND(OUTPUT ${${out_files}} - COMMAND ${_cg} + COMMAND ${CMAKE_COMMAND} -E env ${_env} ${_cg} ARGS -s ${xmlIn} -a ${action} -o ${CMAKE_CURRENT_BINARY_DIR} @@ -168,10 +169,11 @@ MACRO(CODEGEN_SQL srcList xmlFile_in) SET(out_dir_sql "${CMAKE_BINARY_DIR}/share/Lts/sql/") SET(out_file_sql "${out_dir_sql}/${svcNameOut}.sql") SET(action "SQL") + SET(_cg $) ADD_CUSTOM_COMMAND(OUTPUT ${out_file_sql} COMMAND ${CMAKE_COMMAND} ARGS -E make_directory ${out_dir_sql} - COMMAND ngl_codegen + COMMAND ${CMAKE_COMMAND} -E env QT_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/qt6/plugins/kf6/ktexttemplate ${_cg} ARGS -s ${xmlFile_in} -a ${action} -o ${out_dir_sql} diff --git a/qt6-after/qt6-migrated-legatus/include/DDS/Core/core.hpp b/qt6-after/qt6-migrated-legatus/include/DDS/Core/core.hpp.stub similarity index 100% rename from qt6-after/qt6-migrated-legatus/include/DDS/Core/core.hpp rename to qt6-after/qt6-migrated-legatus/include/DDS/Core/core.hpp.stub diff --git a/qt6-after/qt6-migrated-legatus/include/DDS/Core/core_dtc_types.h b/qt6-after/qt6-migrated-legatus/include/DDS/Core/core_dtc_types.h.stub similarity index 100% rename from qt6-after/qt6-migrated-legatus/include/DDS/Core/core_dtc_types.h rename to qt6-after/qt6-migrated-legatus/include/DDS/Core/core_dtc_types.h.stub diff --git a/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc.h b/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc.h index 7d0411795..15d842868 100644 --- a/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc.h +++ b/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc.h @@ -1,6 +1,6 @@ /** * @RDE_HEADER@ - * DTC TypeDefinitions - Stub für BUILD_RTI=OFF + * DTC TypeDefinitions * $Id$ * $HeadURL$ * $Author$ @@ -8,12 +8,18 @@ #pragma once -// Stub für BUILD_RTI=OFF - keine RTI Connext DDS Verfügbarkeit -// Diese Header ermöglicht Kompilierung ohne RTI DDS Dependencies - #include #include -#include +#include + +#ifdef BUILD_RTI +// Use actual RTI Connext DDS types +#include +#include +// DataModification enum is provided by LtsUtilsCore/data_modification_enum.h +#else +// Stub für BUILD_RTI=OFF - keine RTI Connext DDS Verfügbarkeit +// Diese Header ermöglicht Kompilierung ohne RTI DDS Dependencies // Forward declarations für DDS-Typen (Stubs) namespace dds { @@ -29,6 +35,14 @@ namespace sub { } } +// Stub enum for BUILD_RTI=OFF +enum class DataModification { + Added, + Modified, + Removed +}; +#endif + namespace NGLLogger { class INGLLogger; diff --git a/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc_impl.h b/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc_impl.h new file mode 100755 index 000000000..f017f15dd --- /dev/null +++ b/qt6-after/qt6-migrated-legatus/include/DDS/DTC/generic_dtc_impl.h @@ -0,0 +1,318 @@ +/** + * @RDE_HEADER@ + * DataTopicClient (DTC) - Generic + * $Id$ + * $HeadURL$ + * $Author$ + */ + +#pragma once + +#include +#include +#include + +#include +#include + +#include "generic_dtc.h" + + +namespace DDSGeneric +{ +class DynamicDataReader; +} +namespace DTC +{ + +template +class GenericDtcImplSubscriberTemplate : public DDSGeneric::SubscriberListenerCallback, public SuperClass +{ +public: + using DataReaderObject = typename SuperClass::DataReaderObject; + using SubscriberCallback = typename SuperClass::SubscriberCallback; + using TopicTypeRead = typename DataReaderObject::TopicType; + using TopicTypeSubscribe = typename DataReaderObject::TopicType; + using DataReader = typename DataReaderObject::DataReader; + + GenericDtcImplSubscriberTemplate(const dds::domain::DomainParticipant &domainParticipant, + const dds::sub::Subscriber &ddsSubscriber, + DDSGeneric::SubscriberListener *subscriberListener, + const std::string &topicName = DDS::Helper::getShortTopicName(DDS::topic_type_name::value())) + : m_subscriberListener(subscriberListener) + , m_dataReaderObject(new DataReaderObject) + , m_subscriberCallback(nullptr) + , m_writerState(0) + , m_logger(DDS::getLogger(DDS::topic_type_name::value(), DDS::DataType::DATA_TOPIC_CLIENT)) + { + createInternal(m_dataReaderObject->create(domainParticipant, ddsSubscriber, topicName)); + } + + GenericDtcImplSubscriberTemplate(const dds::domain::DomainParticipant &domainParticipant, + const dds::sub::Subscriber &ddsSubscriber, + DDSGeneric::SubscriberListener *subscriberListener, + const dds::topic::Filter &filter, + const std::string &topicName) + : m_subscriberListener(subscriberListener) + , m_dataReaderObject(new DataReaderObject) + , m_subscriberCallback(nullptr) + , m_writerState(0) + , m_logger(DDS::getLogger(DDS::topic_type_name::value(), DDS::DataType::DATA_TOPIC_CLIENT)) + { + createInternal(m_dataReaderObject->create(domainParticipant, ddsSubscriber, topicName, filter)); + } + + GenericDtcImplSubscriberTemplate(const dds::domain::DomainParticipant &domainParticipant, + const dds::sub::Subscriber &ddsSubscriber, + DDSGeneric::SubscriberListener *subscriberListener, + const dds::core::xtypes::StructType &structType, + const std::string &topicName) + : m_subscriberListener(subscriberListener) + , m_dataReaderObject(new DataReaderObject) + , m_subscriberCallback(nullptr) + , m_logger(DDS::getLogger(DDS::topic_type_name::value(), DDS::DataType::DATA_TOPIC_CLIENT)) + { + createInternal(m_dataReaderObject->create(domainParticipant, ddsSubscriber, topicName, structType)); + } + + ~GenericDtcImplSubscriberTemplate() + { + if (m_dataReaderObject && m_subscriberCallback) + m_subscriberListener->removeCallback(m_dataReaderObject->getDataReader(), this); + delete m_dataReaderObject; + } + + bool setSubscriberCallback(const SubscriberCallback &subscriberCallback) override final + { + if (m_subscriberCallback) + { + WARNING_LOG(m_logger) << "Can not set subscriber callback - already set ..."; + return false; + } + if (!m_subscriberListener) + { + WARNING_LOG(m_logger) << "Can not set subscriber callback - no subscriber listener ..."; + return false; + } + + m_subscriberCallback = subscriberCallback; + + if (!m_dataReaderObject) + { + WARNING_LOG(m_logger) << "Can not set subscriber callback - no data reader object ..."; + return false; + } + + m_dataReaderObject->setHaveSubscriberCallback(m_subscriberCallback != nullptr); + + return true; + } + + dds::sub::LoanedSamples readAlive() const override final + { + if (!m_dataReaderObject) + return dds::sub::LoanedSamples(); + + bool bSeenUnreadSamples = false; + auto ret = m_dataReaderObject->readAlive(bSeenUnreadSamples); + if (bSeenUnreadSamples) + QTimer::singleShot(0, this, &GenericDtcImplSubscriberTemplate::unreadSamplesDuringRead); + + return ret; + } + + dds::sub::LoanedSamples takeAlive() const override final + { + if (!m_dataReaderObject) + return dds::sub::LoanedSamples(); + + bool bSeenUnreadSamples = false; + auto ret = m_dataReaderObject->takeAlive(bSeenUnreadSamples); + if (bSeenUnreadSamples) + QTimer::singleShot(0, this, &GenericDtcImplSubscriberTemplate::unreadSamplesDuringRead); + + return ret; + } + + dds::sub::LoanedSamples takeDisposed() const override final + { + if (!m_dataReaderObject) + return dds::sub::LoanedSamples(); + + return m_dataReaderObject->takeDisposed(); + } + + bool hasSamples() const override final + { + if (!m_dataReaderObject) + return false; + + return m_dataReaderObject->hasSamples(); + } + + DataReaderObject *dataReader() const override final + { + return m_dataReaderObject; + } + + bool waitForHistoricalData(int timeoutMSec) override + { + if (m_dataReaderObject == nullptr || + m_dataReaderObject->getDataReader() == nullptr) + return false; + + const bool bWaitForever = (timeoutMSec < 0); + auto dr = m_dataReaderObject->getDataReader(); + try + { + if (dr.subscription_matched_status().current_count() == 0) + { + dds::core::cond::WaitSet ws; + dds::core::cond::StatusCondition cond(dr); + cond.enabled_statuses(dds::core::status::StatusMask::subscription_matched()); + ws.attach_condition(cond); + const dds::core::Duration waitTimeout(bWaitForever ? dds::core::Duration::infinite() : dds::core::Duration::from_millisecs(timeoutMSec)); + const dds::core::cond::WaitSet::ConditionSeq seq(ws.wait(waitTimeout)); + // empty sequence -> timeout + if (seq.empty()) + return false; + } + dr.wait_for_historical_data(dds::core::Duration(1)); + } + catch (const dds::core::Exception &) + { + // timeout + return false; + } + return true; + } + +protected: + void unreadSamplesDuringRead() + { + droDataAvailable(DDS::topic_type_name::value(), m_dataReaderObject->topicName()); + } + + void droDataAvailable(const std::string &topicType, const std::string &topicName) override final + { + Q_UNUSED(topicType); + if (m_writerState.testAndSetRelaxed(1, 0)) + { + DEBUG_LOG(m_logger) << "Recreate Reader for topic " << topicName + << ", type name " << DDS::topic_type_name::value(); + if (m_subscriberListener) + m_subscriberListener->removeCallback(m_dataReaderObject->getDataReader(), this); + m_dataReaderObject->recreateReader(); + if (m_subscriberListener) + m_subscriberListener->addCallback(m_dataReaderObject->getDataReader(), this); + } + + DEBUG_LOG(m_logger) << "IN droDataAvailable(), topic name: " << topicName + << ", type name " << DDS::topic_type_name::value() + << ", this: " << this + << ", m_dataReaderObject: " << m_dataReaderObject + << ", hasSamples: " << (m_dataReaderObject ? m_dataReaderObject->hasSamples() : -1); + + if (m_subscriberListener) + m_subscriberListener->enableCallback(m_dataReaderObject->getDataReader(), this); + + if (!m_dataReaderObject || !m_subscriberCallback) + return; + + m_dataReaderObject->read(m_subscriberCallback); + } + + void noWriterAnymore(const std::string &topicType, const std::string &topicName) override + { + Q_UNUSED(topicType); + Q_UNUSED(topicName); + m_writerState = -1; + } + + void writerAvailable(const std::string &topicType, const std::string &topicName) override + { + Q_UNUSED(topicType); + Q_UNUSED(topicName); + m_writerState.testAndSetRelaxed(-1, 1); + } + + bool createInternal(bool droInitOk) + { + if (!droInitOk) + { + ERROR_LOG(m_logger) << "Error initializing DRO for type " << DDS::topic_type_name::value(); + delete m_dataReaderObject; + m_dataReaderObject = nullptr; + return false; + } + + if (m_subscriberListener) + { + DEBUG_LOG(m_logger) << "subscriberListener exists, adding type " + << DDS::topic_type_name::value(); + m_subscriberListener->addCallback(m_dataReaderObject->getDataReader(), this); + } + else + { + DEBUG_LOG(m_logger) << "Cannot add DTC to subscriberListener callback - type: " + << DDS::topic_type_name::value(); + } + m_dataReaderObject->setHaveSubscriberCallback(m_subscriberListener != nullptr); + return true; + } + +private: + DDSGeneric::SubscriberListener *m_subscriberListener; + + // DataReaderObjects (DROs) + DataReaderObject *m_dataReaderObject; + + // Callback for data processing + SubscriberCallback m_subscriberCallback; + + QAtomicInt m_writerState; + + NGL::INGLLogger &m_logger; +}; + +// Typed topic callback (DataReader) +template +class GenericDtcImpl final + : public GenericDtcImplSubscriberTemplate> +{ + using BaseClass = GenericDtcImplSubscriberTemplate>; +public: + using BaseClass::BaseClass; +}; + +// Typed topic callback (DataReader) with SampleInfo +template +class GenericDtcImplSampleInfo final + : public GenericDtcImplSubscriberTemplate> +{ + using BaseClass = GenericDtcImplSubscriberTemplate>; +public: + using BaseClass::BaseClass; +}; + +// Dynamic topic callback (DynamicDataReader) +template +class DdtcImpl final + : public GenericDtcImplSubscriberTemplate> +{ + using BaseClass = GenericDtcImplSubscriberTemplate>; +public: + using BaseClass::BaseClass; +}; + +// Dynamic topic callback (DynamicDataReader) with SampleInfo +template +class DdtcImplSampleInfo final + : public GenericDtcImplSubscriberTemplate> +{ + using BaseClass = GenericDtcImplSubscriberTemplate>; +public: + using BaseClass::BaseClass; +}; + +} // namespace DTC diff --git a/qt6-after/qt6-migrated-legatus/rti_license.dat b/qt6-after/qt6-migrated-legatus/rti_license.dat new file mode 100644 index 000000000..e69de29bb