Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Common/LtsSession/lts_session_data_dds.h
T

346 lines
10 KiB
C++

/**
* @RDE_HEADER@
* DDS specific parts for a session
* $Id$
* $HeadURL$
* $Author$
*
* Created by Christian Ehrlicher, SLSE, 2017-02-27
*/
#pragma once
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QUrl>
#include <memory>
#include <QtCore/QMap>
// Export macro for shared library
#include "ltssessiondatadds_export.h"
#ifdef BUILD_RTI
#include <dds/domain/DomainParticipant.hpp>
#include <NGLLogger/INGLLogger.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include "Core/core.hpp"
#include "Core/core_dtc_types.h"
#include "Lts/Common/ProjectConfig/project_defines.h"
namespace DDSConnector { class DdsConnector; }
namespace DataPluginBase { class Interface; }
namespace GuiPluginBase { class Interface; }
#else
// Forward declarations for stub types
namespace DataPluginBase { class Interface; }
namespace GuiPluginBase { class Interface; }
#endif
namespace LtsSession
{
// Stub enum for PartitionType
enum class PartitionType {
Any = 0,
Exercise,
Replay,
AllExercises,
Global,
Invalid = -1
};
class Fetcher;
struct DdsConnectionParams
{
int domainId = -1;
int partitionId = 0;
int exerciseId = 0;
PartitionType partitionType = PartitionType::Any;
QUrl tcpConnectionUrl;
QStringList qos_file;
DdsConnectionParams() = default;
bool isValid() const
{
return domainId >= 0 && partitionType != PartitionType::Any;
}
bool operator==(const DdsConnectionParams& o) const
{
return domainId == o.domainId && partitionId == o.partitionId && exerciseId == o.exerciseId &&
qos_file == o.qos_file && partitionType == o.partitionType && tcpConnectionUrl == o.tcpConnectionUrl;
}
bool operator!=(const DdsConnectionParams& o) const
{
return !operator==(o);
}
bool operator<(const DdsConnectionParams& o) const
{
if (domainId != o.domainId)
return domainId < o.domainId;
if (partitionId != o.partitionId)
return partitionId < o.partitionId;
if (exerciseId != o.exerciseId)
return exerciseId < o.exerciseId;
if (qos_file != o.qos_file)
return qos_file < o.qos_file;
if (partitionType != o.partitionType)
return partitionType < o.partitionType;
return tcpConnectionUrl.toString() < o.tcpConnectionUrl.toString();
}
#ifdef BUILD_RTI
bool hasSameDomainParams(const DdsConnectionParams& o) const
{
return domainId == o.domainId && partitionType == o.partitionType;
}
#endif
};
// Base class for session DDS data - always compiled, but RTI functionality guarded
class LTSSESSIONDATADDS_EXPORT LtsSessionDataDds : public QObject
{
Q_OBJECT
public:
explicit LtsSessionDataDds(QObject* parent = nullptr);
~LtsSessionDataDds();
// Initialization
#ifdef BUILD_RTI
bool init(const DdsConnectionParams& connParams);
bool init(const dds::domain::DomainParticipant& dp, const DdsConnectionParams& connParams);
Fetcher* fetcher(const QString& yourPluginsName);
#else
virtual bool init(const DdsConnectionParams& connParams);
virtual bool init(const void* dp, const DdsConnectionParams& connParams);
virtual void* fetcher(const QString& yourPluginsName);
#endif
// Accessors
int domainId() const;
int exerciseId() const;
int partitionId() const;
PartitionType partitionType() const;
static QString partitionTypeString(PartitionType partitionType);
QStringList qosFile() const;
QUrl tcpConnectionUrl() const;
DdsConnectionParams connParams() const;
bool isExercisePartition() const { return partitionType() == PartitionType::Exercise; }
bool isReplayPartition() const { return partitionType() == PartitionType::Replay; }
QString toString() const;
qint64 partitionTime() const { return m_emittedTime; }
// Data plugin interfaces
#ifdef BUILD_RTI
QMap<QString, std::shared_ptr<DataPluginBase::Interface>> availableDataPluginInterfaces() const;
void addAvailablaeDataPluginInterfaces(const QMap<QString, std::shared_ptr<DataPluginBase::Interface>>& dataPlugins);
#else
QMap<QString, void*> availableDataPluginInterfaces() const { return QMap<QString, void*>(); }
void addAvailablaeDataPluginInterfaces(const QMap<QString, void*>& /*dataPlugins*/) {}
#endif
// retrieve DTC/FTC inside DataPlugin::createDataInterface() - always available
template<typename T>
bool createTopicClient(std::shared_ptr<T> &member, bool bEnableAll = false, bool bGlobal = false);
template<typename T, typename S>
bool createTopicClient(std::shared_ptr<T> &dtc, std::shared_ptr<S> &ftc, bool bEnableAll = false, bool bGlobal = false);
template<typename T, typename S>
bool getDtc(std::shared_ptr<S> &val) const;
// Foreign GUI interface retrieval - used by Fetcher helper class
template<typename S>
bool getForeignGuiInterface(std::shared_ptr<S> &val) const
{
#ifdef BUILD_RTI
for (const auto &i : m_guiPluginInterfaces)
{
val = std::dynamic_pointer_cast<S>(i);
if (val)
return true;
}
val.reset();
if (m_logger.isDebugEnabled())
DEBUG_LOG(m_logger) << "Cannot find foreign gui ifc " << typeid(S).name() << " in " << toString();
#else
val.reset();
#endif
return false;
}
signals:
void partitionTimeChanged(qint64 newPartitionTime);
void partitionTimeChangedInternal();
protected:
#ifdef BUILD_RTI
bool initInternal();
void onPartitionTimeChangedInternal();
static LtsSession::PartitionType toPartitionType(IDL::PartitionType idlType);
static IDL::PartitionType toIdlPartitionType(LtsSession::PartitionType type);
// Member variables - only with RTI
int m_exerciseId;
qint64 m_emittedTime;
qint64 m_curMSecSinceEpoch;
bool m_active;
Fetcher* m_fetcher;
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorGlobal;
std::shared_ptr<DTC::PartitionTime> m_dtcPartitionTime;
NGL::INGLLogger& m_logger;
QMap<QString, std::shared_ptr<DataPluginBase::Interface>> m_dataPluginInterfaces;
QMap<QString, std::shared_ptr<GuiPluginBase::Interface>> m_guiPluginInterfaces;
QStringList m_qosFileList;
#else
// Stub implementation - minimal members
bool initInternal();
void onPartitionTimeChangedInternal();
int m_exerciseId;
qint64 m_emittedTime;
qint64 m_curMSecSinceEpoch;
bool m_active;
void* m_fetcher;
#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 <typename ForeignGuiInterface>
void getForeignGuiInterface(std::shared_ptr<ForeignGuiInterface> &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
#ifdef BUILD_RTI
template<typename T>
bool LtsSession::LtsSessionDataDds::createTopicClient(std::shared_ptr<T> &member, bool bEnableAll, bool bGlobal)
{
member = T::create(bGlobal ? m_ddsConnectorGlobal : m_ddsConnector);
if ( bEnableAll && !member->enableAll())
{
member = nullptr;
if (m_logger.isErrorEnabled())
NGL::LogStreamHelper(m_logger, NGL::LogLevel::Error, __FILE__, __LINE__, Q_FUNC_INFO) << "Error initializing dtc/ftc for service " << T::identifier();
return false;
}
return true;
}
template<typename T, typename S>
bool LtsSession::LtsSessionDataDds::createTopicClient(std::shared_ptr<T> &dtc, std::shared_ptr<S> &ftc, bool bEnableAll, bool bGlobal)
{
dtc = T::create(bGlobal ? m_ddsConnectorGlobal : m_ddsConnector);
ftc = S::create(bGlobal ? m_ddsConnectorGlobal : m_ddsConnector);
if ( (bEnableAll && !dtc->enableAll()) || !ftc->enableAll())
{
dtc = nullptr;
ftc = nullptr;
if (m_logger.isErrorEnabled())
NGL::LogStreamHelper(m_logger, NGL::LogLevel::Error, __FILE__, __LINE__, Q_FUNC_INFO) << "Error initializing dtc/ftc for service " << T::identifier();
return false;
}
return true;
}
template<typename T, typename S>
bool LtsSession::LtsSessionDataDds::getDtc(std::shared_ptr<S> &val) const
{
for (const auto &i : m_dataPluginInterfaces)
{
auto ifc = std::dynamic_pointer_cast<T>(i);
if (ifc)
{
val = ifc->getDtc();
return val != nullptr;
}
}
val.reset();
if (m_logger.isDebugEnabled())
NGL::LogStreamHelper(m_logger, NGL::LogLevel::Debug, __FILE__, __LINE__, Q_FUNC_INFO) << "Trying to load dtc " << typeid(T).name() << " - " << typeid(S).name() << " failed!"
<< ", m_dataPluginInterfaces.size() = " << m_dataPluginInterfaces.size() << " - " << this;
return false;
}
#else
// Stub implementations for non-BUILD_RTI
template<typename T>
bool LtsSession::LtsSessionDataDds::createTopicClient(std::shared_ptr<T> &/*member*/, bool /*bEnableAll*/, bool /*bGlobal*/)
{
return false;
}
template<typename T, typename S>
bool LtsSession::LtsSessionDataDds::createTopicClient(std::shared_ptr<T> &/*dtc*/, std::shared_ptr<S> &/*ftc*/, bool /*bEnableAll*/, bool /*bGlobal*/)
{
return false;
}
template<typename T, typename S>
bool LtsSession::LtsSessionDataDds::getDtc(std::shared_ptr<S> &/*val*/) const
{
return false;
}
#endif // BUILD_RTI