- Merged 292 changed files from dlbo snapshot - Fixed IDL enum collisions (PortType, PdmEventType) - Fixed Grantlee template for C++11 scoped enums - Fixed CMake VERSION_GREATER syntax - Added missing directories (THP, LtsRestClient, etc.) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
357 lines
13 KiB
C++
Executable File
357 lines
13 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* DDS specific parts for a session
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*
|
|
* Created by Christian Ehrlicher, SLSE, 2017-02-27
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <QObject>
|
|
#include <QMap>
|
|
#include <QUrl>
|
|
#include <memory>
|
|
#include <DDS/Core/core_dtc_types.h>
|
|
//#include <NGLLogger/INGLLogger.h>
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
#include <Common/ProjectConfig/project_defines.h>
|
|
#include <LtsSession/ltssessiondatadds_export.h>
|
|
|
|
|
|
namespace DataPluginBase { class Interface; }
|
|
namespace DDSConnector { class DdsConnector; }
|
|
namespace GuiPluginBase { class Interface; }
|
|
|
|
namespace LtsSession
|
|
{
|
|
struct DdsConnectionParams
|
|
{
|
|
int domainId = -1;
|
|
int partitionId = 0;
|
|
int exerciseId = 0;
|
|
IDL::PartitionType partitionType = IDL::PartitionType::Any;
|
|
QUrl tcpConnectionUrl;
|
|
QStringList qos_file;
|
|
|
|
DdsConnectionParams() = default;
|
|
explicit DdsConnectionParams(const Core::ReplayPartition &rp)
|
|
: domainId(rp.domainId())
|
|
, partitionId(rp.id())
|
|
, exerciseId(rp.exerciseId())
|
|
, partitionType(IDL::PartitionType::Replay)
|
|
{
|
|
setTcpConnectionUrl(rp.tcpConnectionUrl());
|
|
}
|
|
|
|
bool isValid() const { return domainId >= 0 && partitionType != IDL::PartitionType::Any; }
|
|
bool hasSameDomainParams(const DdsConnectionParams &o) const
|
|
{
|
|
return domainId == o.domainId &&
|
|
tcpConnectionUrl == o.tcpConnectionUrl;
|
|
}
|
|
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();
|
|
}
|
|
|
|
void setTcpConnectionUrl(const std::string &url)
|
|
{
|
|
tcpConnectionUrl = QUrl::fromUserInput(QString::fromStdString(url));
|
|
}
|
|
};
|
|
|
|
|
|
class Fetcher;
|
|
|
|
|
|
class LTSSESSIONDATADDS_EXPORT LtsSessionDataDds /* FIXME: Name ist irrefuehrend. "LtsSessionData" hat mit "LtsSessionDataDds" nichts zu tun, klingen aber fast identisch. */
|
|
: public QObject
|
|
{
|
|
Q_OBJECT
|
|
protected:
|
|
// only used from LtsSession, no direct instantiation
|
|
explicit LtsSessionDataDds(QObject *parent = nullptr);
|
|
public:
|
|
~LtsSessionDataDds();
|
|
|
|
bool init(const DdsConnectionParams &connParams);
|
|
bool init(const dds::domain::DomainParticipant &dp,
|
|
const DdsConnectionParams &connParams);
|
|
|
|
std::shared_ptr<DDSConnector::DdsConnector> ddsConnector() { return m_ddsConnector; }
|
|
std::shared_ptr<DDSConnector::DdsConnector> ddsConnectorGlobal() { return m_ddsConnectorGlobal; }
|
|
int domainId() const;
|
|
int exerciseId() const;
|
|
int partitionId() const;
|
|
QStringList qosFile() const;
|
|
IDL::PartitionType partitionType() const;
|
|
static QString partitionTypeString(IDL::PartitionType partitionType);
|
|
bool isExercisePartition() const { return (partitionType() == IDL::PartitionType::Exercise); }
|
|
bool isReplayPartition() const { return (partitionType() == IDL::PartitionType::Replay); }
|
|
QString toString() const;
|
|
Fetcher *fetcher(const QString &yourPluginsName);
|
|
|
|
QUrl tcpConnectionUrl() const;
|
|
DdsConnectionParams connParams() const;
|
|
|
|
qint64 partitionTime() const { return m_curMSecSinceEpoch; }
|
|
|
|
// retrieve DTC/FTC inside DataPlugin::createDataInterface()
|
|
template<typename T>
|
|
bool createTopicClient(std::shared_ptr<T> &member, bool bEnableAll = false, bool bGlobal = false)
|
|
{
|
|
member = T::create(bGlobal ? m_ddsConnectorGlobal : m_ddsConnector);
|
|
if ( bEnableAll && !member->enableAll())
|
|
{
|
|
member = nullptr;
|
|
ERROR_LOG(m_logger) << "Error initializing dtc/ftc for service " << T::identifier();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<typename T, typename S>
|
|
bool createTopicClient(std::shared_ptr<T> &dtc, std::shared_ptr<S> &ftc, bool bEnableAll = false, bool bGlobal = false)
|
|
{
|
|
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;
|
|
ERROR_LOG(m_logger) << "Error initializing dtc/ftc for service " << T::identifier();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
template<typename T, typename S>
|
|
bool 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();
|
|
DEBUG_LOG(m_logger) << "Trying to load dtc " << typeid(T).name() << " - " << typeid(S).name() << " failed!"
|
|
<< ", m_dataPluginInterfaces.size() = " << m_dataPluginInterfaces.size() << " - " << this;
|
|
return false;
|
|
}
|
|
|
|
// TODO: merge with getDtc() --> std::is_same, std::enable_if
|
|
template<typename T, typename S>
|
|
bool getFtc(std::shared_ptr<S> &val) const
|
|
{
|
|
for (const auto &i : m_dataPluginInterfaces)
|
|
{
|
|
auto ifc = std::dynamic_pointer_cast<T>(i);
|
|
if (ifc)
|
|
{
|
|
val = ifc->getFtc();
|
|
return val != nullptr;
|
|
}
|
|
}
|
|
val.reset();
|
|
DEBUG_LOG(m_logger) << "Trying to load ftc " << typeid(T).name() << " - " << typeid(S).name() << " failed!"
|
|
<< ", m_dataPluginInterfaces.size() = " << m_dataPluginInterfaces.size() << " - " << this;
|
|
return false;
|
|
}
|
|
|
|
|
|
// TODO: merge with getDtc() --> std::is_same, std::enable_if
|
|
template<typename T, typename S>
|
|
bool getForeignDataInterface(std::shared_ptr<S> &val) const
|
|
{
|
|
//qWarning() << "getForeignDataInterface is deprecated! get the plugin's dtc/ftc directly with getDtc or getFtc!";
|
|
|
|
for (const auto &i : m_dataPluginInterfaces)
|
|
{
|
|
auto ifc = std::dynamic_pointer_cast<T>(i);
|
|
if (ifc)
|
|
{
|
|
val = ifc->getForeignDataInterface();
|
|
return val != nullptr;
|
|
}
|
|
}
|
|
val.reset();
|
|
DEBUG_LOG(m_logger) << "Trying to load foreign data ifc " << typeid(T).name() << " - " << typeid(S).name() << " failed!"
|
|
<< ", m_dataPluginInterfaces.size() = " << m_dataPluginInterfaces.size() << " - " << this;
|
|
return false;
|
|
}
|
|
|
|
|
|
/* MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMW */
|
|
/* MW DEPRECATED - DO NOT USE IN NEW IMPLEMENTATIONS - CAN BE REMOVED AT ANY TIME WITHOUT WARNING ! MW */
|
|
/* MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMW */
|
|
/* MW */ /* MW */
|
|
/* MW */ template<typename S> /* MW */
|
|
/* MW */ bool getForeignDataInterface_NEW(std::shared_ptr<S> &val) const /* MW */
|
|
/* MW */ { /* MW */
|
|
/* MW */ //qWarning() << "getForeignDataInterface is deprecated! get the plugin's dtc/ftc directly with getDtc or getFtc!"; /* MW */
|
|
/* MW */ /* MW */
|
|
/* MW */ for (const auto &i : m_dataPluginInterfaces) /* MW */
|
|
/* MW */ { /* MW */
|
|
/* MW */ val = std::dynamic_pointer_cast<S>(i); /* MW */
|
|
/* MW */ if (val) /* MW */
|
|
/* MW */ return true; /* MW */
|
|
/* MW */ } /* MW */
|
|
/* MW */ val.reset(); /* MW */
|
|
/* MW */ DEBUG_LOG(m_logger) << "Trying to load foreign data ifc " << typeid(S).name() << " failed!" /* MW */
|
|
/* MW */ << ", m_guiPluginInterfaces.size() = " << m_guiPluginInterfaces.size() << " - " << this; /* MW */
|
|
/* MW */ return false; /* MW */
|
|
/* MW */ } /* MW */
|
|
/* MW */ /* MW */
|
|
/* MWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMWMW */
|
|
|
|
|
|
template<typename S>
|
|
bool getForeignGuiInterface(std::shared_ptr<S> &val) const
|
|
{
|
|
for (const auto &i : m_guiPluginInterfaces)
|
|
{
|
|
val = std::dynamic_pointer_cast<S>(i);
|
|
if (val)
|
|
return true;
|
|
}
|
|
val.reset();
|
|
DEBUG_LOG(m_logger) << "Cannot find foreign gui ifc " << typeid(S).name() << " in " << toString();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
template<typename T, typename S>
|
|
bool interfaceFromGui(std::shared_ptr<S> &val) const // for generic gui interfaces
|
|
{
|
|
for (const auto &i : m_guiPluginInterfaces)
|
|
{
|
|
val = std::dynamic_pointer_cast<T>(i);
|
|
if (val)
|
|
return true;
|
|
}
|
|
val.reset();
|
|
DEBUG_LOG(m_logger) << "Trying to load foreign gui ifc #2 " << typeid(S).name() << " failed!"
|
|
<< ", m_guiPluginInterfaces.size() = " << m_guiPluginInterfaces.size() << " - " << this;
|
|
return false;
|
|
}
|
|
|
|
signals:
|
|
void partitionTimeChanged(qint64 newPartitionTime);
|
|
void partitionTimeChangedInternal();
|
|
|
|
private:
|
|
void onPartitionTimeChangedInternal();
|
|
bool initInternal();
|
|
|
|
protected:
|
|
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
|
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnectorGlobal;
|
|
int m_exerciseId;
|
|
std::shared_ptr<DTC::PartitionTime> m_dtcPartitionTime;
|
|
qint64 m_emittedTime;
|
|
qint64 m_curMSecSinceEpoch;
|
|
bool m_active;
|
|
void setInactive() { m_active = false; }
|
|
|
|
|
|
QMap<QString, std::shared_ptr<DataPluginBase::Interface>> availableDataPluginInterfaces() const;
|
|
void addAvailablaeDataPluginInterfaces(const QMap<QString, std::shared_ptr<DataPluginBase::Interface>> &dataPlugins);
|
|
QMap<QString, std::shared_ptr<DataPluginBase::Interface>> m_dataPluginInterfaces;
|
|
QMap<QString, std::shared_ptr<GuiPluginBase::Interface>> m_guiPluginInterfaces;
|
|
QMap<QString, std::shared_ptr<GuiPluginBase::Interface>> m_initializeThesePlugins;
|
|
Fetcher *m_fetcher;
|
|
QStringList m_qosFileList;
|
|
NGL::INGLLogger &m_logger;
|
|
};
|
|
|
|
|
|
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"));
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace LtsSession
|