Continues migration with DDS, Common

This commit is contained in:
torsten committed 2026-07-17 12:41:42 +02:00
1 parent 9b15cee841
commit fa48db111e
668 files changed
+111841 -2

No files matched your search

+97
View File
@@ -0,0 +1,97 @@
#
# $Id$
# $HeadURL$
# $Author$
#
INCLUDE(MacroRTIDDSGen)
INCLUDE(MacroCodeGenIdl)
SET(xml_FILE core.xml)
#
# --- Library svcCoreCommon / ddscore --------------------------------------------------------------------------------
#
SET(SRCS_common
core_export.h
function_reply_object.cpp
function_reply_object.h
logger.cpp
logger.h
)
# Generates core.idl / core_enums.idl
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
# Generate core.sql
CODEGEN_SQL(SRCS_common ${xml_FILE})
# Generate *.cpp/*.hpp from core_enums.idl / core.idl
RTIDDSGEN(SRCS_common core_enums.idl)
RTIDDSGEN(SRCS_common core.idl)
# Generate core_dt[s,c]_types.h, core_ft[s,c]_types.h
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
# generate core_[d|f]tc.h
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
NGL_ADD_LIBRARY(WS AAR HLA SV ddscore SHARED ${SRCS_common})
NGL_TARGET_LINK_LIBRARIES(ddscore
PRIVATE
NGLLogger
PUBLIC
LtsUtilsCoreHeaderOnly
ddsdts
Qt5::Core
RTI::nddsc # DDS_GroupDataQosPolicy_initialize (wo auch immer das herkommt)
RTI::nddscore # RTI_LOG_ANY_FAILURE_s (wo auch immer das herkommt)
RTI::nddscpp2
)
NGL_TARGET_INCLUDE_DIRECTORIES(ddscore
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../../
${CMAKE_CURRENT_BINARY_DIR}/../../
)
NGL_INSTALL_TARGET(ddscore)
#
# --- Library svcCoreClient --------------------------------------------------------------------------------
#
SET(SRCS_client
core_export.h
pacemaker.h
pacemaker.cpp
topic_lock_master.h
topic_lock_master.cpp
)
# generate core_[d|f]tc_impl.[cpp|h]
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS HLA svcCoreClient SHARED ${SRCS_client})
NGL_TARGET_INCLUDE_DIRECTORIES(svcCoreClient
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../../
${CMAKE_CURRENT_BINARY_DIR}/../../
)
NGL_TARGET_LINK_LIBRARIES(svcCoreClient
PRIVATE
RTI::nddscpp2
ddsconnector
PUBLIC
ddscore
ddsftc
)
NGL_INSTALL_TARGET(svcCoreClient)
#
# --- Library svcCoreServer --------------------------------------------------------------------------------
# not used (no core service needed)
#
#
# --- Topic Type Plugin --------------------------------------------------------------
#
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
+204
View File
@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service namespace="Core" abbreviation="CORE" procNames="Core" exerciseDependency="Global">
<rcs>
<Id Id="$Id$"/>
<HeadURL HeadURL="$HeadURL$"/>
<Author Author="$Author$"/>
</rcs>
<tables>
<table name="ft_reply_state" comment="static data (not project specific) generate from enum">
<column name="id" datatype="integer" isPrimaryKey="1"/>
<column name="name" datatype="text"/>
</table>
<table name="replay_type" comment="Type of replay (Data for reports/events or situation)">
<column name="id" datatype="integer" isPrimaryKey="1"/>
<column name="name" datatype="text"/>
</table>
<table name="running_state">
<column name="id" datatype="integer" isPrimaryKey="1"/>
<column name="name" datatype="text"/>
</table>
<table name="service_group_type">
<column name="id" datatype="integer" isPrimaryKey="1"/>
<column name="name" datatype="text"/>
</table>
<table name="z_reference">
<column name="id" datatype="integer" isPrimaryKey="1"/>
<column name="name" datatype="text"/>
</table>
</tables>
<views/>
<topicTypes>
<topicType name="BaseEntity">
<column name="id" idlType="long" isKey="1"/>
<column name="name" idlType="string"/>
<column name="isDeleted" idlType="boolean"/>
<column name="isUsed" idlType="boolean" comment="Defines if it is used by others (i.e. foreign key constraint)"/>
</topicType>
<topicType name="BaseEntityTranslatable">
<column name="id" idlType="long" isKey="1"/>
<column name="name" idlType="string" isTranslatable="1"/>
<column name="isDeleted" idlType="boolean"/>
<column name="isUsed" idlType="boolean" comment="Defines if it is used by others (i.e. foreign key constraint)"/>
</topicType>
<topicType name="BaseEntityWithSampleTime" baseValueType="BaseEntity">
<column name="sampleTime" idlType="long long" comment="Timestamp"/>
</topicType>
<topicType name="CurrentRunningState" isDataObject="1" routeToClient="0" routeToServer="0" routeInReplay="0">
<column name="pid" idlType="long long" isKey="1"/>
<column name="runningState" idlType="RunningState"/>
<column name="ports" idlType="sequence&lt;PortInformation&gt;" isOptional="1"/>
<column name="errorString" idlType="string" isOptional="1"/>
</topicType>
<topicType name="FunctionReply">
<column name="id" idlType="long"/>
<column name="errorString" idlType="string"/>
<column name="errorParams" idlType="sequence&lt;string&gt;"/>
<column name="additionalInfo" idlType="string"/>
</topicType>
<topicType name="FunctionReplyWithState" baseValueType="FunctionReply">
<column name="replyState" idlType="FtReplyState"/>
</topicType>
<topicType name="GeoPositionAbsoluteTime" baseValueType="GeoPosition">
<column name="absoluteTime" idlType="long long" comment="Timestamp"/>
</topicType>
<topicType name="GeoPositionRelativeTime" baseValueType="GeoPosition">
<column name="relativeTime" idlType="long long" comment="Timestamp"/>
</topicType>
<topicType name="GeoPosition" baseValueType="GeoPosition2D">
<column name="z" idlType="double" comment="height above ground"/>
</topicType>
<topicType name="GeoPosition2D">
<column name="lon" idlType="double" comment="[m]"/>
<column name="lat" idlType="double" comment="[m]"/>
</topicType>
<topicType name="LockEntityError">
<column name="workstationName" idlType="string"/>
<column name="operatorName" idlType="string"/>
</topicType>
<topicType name="TryLockEntityReply" baseValueType="FunctionReply">
<column name="alreadyLocked" idlType="LockEntityError" isOptional="1"/>
</topicType>
<topicType name="LockedEntity" isDataObject="1" routeToClient="0" routeToServer="0" routeInReplay="0" baseValueType="LockedEntityBase">
<column name="id" idlType="long long" isKey="1"/>
</topicType>
<topicType name="LockedEntityBase">
<column name="operatorId" idlType="long"/>
<column name="workstationId" idlType="long"/>
<column name="exerciseId" idlType="long"/>
<column name="entityId" idlType="long long"/>
<column name="entityTypeName" idlType="string"/>
</topicType>
<topicType name="TryLockEntityRequest" baseValueType="LockedEntityBase">
<column name="id" idlType="long"/>
</topicType>
<topicType name="TryUnlockEntityRequest">
<column name="id" idlType="long"/>
</topicType>
<topicType name="Orientation">
<column name="heave" idlType="double"/>
<column name="pitch" idlType="double"/>
<column name="roll" idlType="double"/>
</topicType>
<topicType name="PartitionTime" isDataObject="1" routeToClient="1" routeToServer="0" routeInReplay="0">
<column name="timeStamp" idlType="long long"/>
</topicType>
<topicType name="PortInformation">
<column name="number" idlType="long"/>
<column name="type" idlType="PortType"/>
<column name="properties" idlType="string"/>
</topicType>
<topicType name="RelativePosition">
<column name="offsetX" idlType="double" comment="in meter"/>
<column name="offsetY" idlType="double" comment="in meter"/>
<column name="offsetZ" idlType="double" comment="in meter"/>
</topicType>
<topicType name="RelativePositionAbsoluteTime" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="RelativePosition">
<column name="absoluteTime" idlType="long long" comment="TimeStamp"/>
</topicType>
<topicType name="RelativePositionRelativeTime" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" baseValueType="RelativePosition">
<column name="relativeTime" idlType="long long" comment="TimeStamp"/>
</topicType>
<topicType name="RemoveElementRequest">
<column name="id" idlType="long"/>
</topicType>
<topicType name="ReplayPartition" isDataObject="1" routeToClient="1" routeToServer="0" routeInReplay="0">
<column name="id" idlType="long" isKey="1"/>
<column name="name" idlType="string"/>
<column name="exerciseId" idlType="long"/>
<column name="workstationId" idlType="long"/>
<column name="operatorId" idlType="long"/>
<column name="replayType" idlType="ReplayType"/>
<column name="domainId" idlType="long"/>
<column name="tcpConnectionUrl" idlType="string"/>
</topicType>
<topicType name="Velocity">
<column name="x" idlType="double"/>
<column name="y" idlType="double"/>
<column name="z" idlType="double"/>
</topicType>
</topicTypes>
<functionTopics>
<functionTopic name="TryLockEntity" requestTopicType="TryLockEntityRequest" replyTopicType="TryLockEntityReply" requestTopicName="TryLockEntityRequest" replyTopicName="TryLockEntityReply" routeInReplay="1"/>
<!-- <functionTopic name="TryLockEntity" requestTopicType="LockedEntityBase" replyTopicType="TryLockEntityReply" requestTopicName="TryLockEntityRequest" replyTopicName="TryLockEntityReply" routeInReplay="1"/>-->-->
<functionTopic name="TryUnlockEntity" requestTopicType="TryUnlockEntityRequest" replyTopicType="FunctionReply" requestTopicName="TryUnlockEntityRequest" replyTopicName="TryUnlockEntityReply" routeInReplay="1"/>
</functionTopics>
<enumerations>
<enumeration name="FtReplyState" table="ft_reply_state">
<attribute key="NotStarted" value="0"/>
<attribute key="InProgress" value="1"/>
<attribute key="Completed" value="2"/>
<attribute key="Error" value="4"/>
</enumeration>
<enumeration name="PortType">
<attribute key="Unknown" value="0"/>
<attribute key="WebSocketServer" value="1"/>
<attribute key="WebSocketPositionServer" value="2"/>
<attribute key="WebSocketAdlerServer" value="3"/>
</enumeration>
<enumeration name="PositionReportingSource">
<attribute key="Gps" value="0"/>
<attribute key="Wls" value="1"/>
<attribute key="Ops" value="2"/>
<attribute key="External" value="3"/>
<attribute key="SetByOperator" value="4"/>
<attribute key="MovementSimulation" value="5"/>
<attribute key="OpsTunnel" value="6"/>
<attribute key="OpsBuilding" value="7"/>
</enumeration>
<enumeration name="ReplayType" table="replay_type">
<attribute key="UnknownData" value="0"/>
<attribute key="SituationData" value="1"/>
<attribute key="ReportData" value="2"/>
<attribute key="EventData" value="3"/>
<attribute key="OtherData" value="4"/>
<attribute key="SnapshotData" value="5"/>
</enumeration>
<enumeration name="RunningState" table="running_state">
<attribute key="NotYetStarted" value="0"/>
<attribute key="Starting" value="1"/>
<attribute key="StartingError" value="2"/>
<attribute key="Running" value="3"/>
<attribute key="Stopping" value="4"/>
<attribute key="StoppedNormally" value="5"/>
<attribute key="StoppedError" value="6"/>
</enumeration>
<enumeration name="ServiceGroupType" table="service_group_type">
<attribute key="Master" value="0"/>
<attribute key="Core" value="1"/>
<attribute key="ExercisePreparation" value="2"/>
<attribute key="ExerciseExecution" value="3"/>
<attribute key="ExercisePaused" value="4"/>
<attribute key="ExerciseAfterActionReview" value="5"/>
<attribute key="Playback" value="6"/>
</enumeration>
<enumeration name="ZReference" table="z_reference">
<attribute key="ZrUndefined" value="0"/>
<attribute key="Zr_Unused" value="1"/>
<attribute key="ZrRelativeAGL" value="100"/>
<attribute key="ZrAbsolute" value="200"/>
<attribute key="ZrDrapedOnGround" value="300"/>
<attribute key="ZrRelativeToDefinedValue" value="400"/>
</enumeration>
</enumerations>
</service>
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <QtCore/qglobal.h>
#ifndef CORE_COMMON_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define CORE_COMMON_EXPORT
# else
# if defined(MAKE_DDSCORE_LIB)
# define CORE_COMMON_EXPORT Q_DECL_EXPORT
# ifndef WIN32
# ifdef NDDSUSERDllExport
# undef NDDSUSERDllExport
# endif
# define NDDSUSERDllExport Q_DECL_EXPORT
# endif
# else
# define CORE_COMMON_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef CORE_CLIENT_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define CORE_CLIENT_EXPORT
# else
# if defined(MAKE_SVCCORECLIENT_LIB)
# define CORE_CLIENT_EXPORT Q_DECL_EXPORT
# else
# define CORE_CLIENT_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef CORE_SERVER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define CORE_SERVER_EXPORT
# else
# if defined(MAKE_SVCCORESERVER_LIB)
# define CORE_SERVER_EXPORT Q_DECL_EXPORT
# else
# define CORE_SERVER_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+48
View File
@@ -0,0 +1,48 @@
#include "function_reply_object.h"
#include <QtCore/QString>
#include <QtCore/QCoreApplication>
namespace Core
{
FunctionReplyObject &FunctionReplyObject::arg(qint64 val)
{
m_args.push_back(std::to_string(val));
return *this;
}
FunctionReplyObject &FunctionReplyObject::arg(const std::string &str)
{
m_args.push_back(str);
return *this;
}
FunctionReplyObject &FunctionReplyObject::arg(const QString &str)
{
m_args.push_back(str.toStdString());
return *this;
}
std::string FunctionReplyObject::operator()() const
{
if (m_args.empty())
return m_str;
QString ret(QString::fromStdString(m_str));
for (const std::string &s : m_args)
ret = ret.arg(QString::fromStdString(s));
return ret.toStdString();
}
QString FunctionReplyObject::translated() const
{
QString ret(QCoreApplication::translate("dds", m_str.c_str()));
for (const std::string &s : m_args)
ret = ret.arg(QString::fromStdString(s));
return ret;
}
}
+95
View File
@@ -0,0 +1,95 @@
#pragma once
#include <string>
#include <vector>
#include "core_export.h"
#ifndef tr_lts
#define tr_lts(ctx, t) (t)
#endif
namespace Core
{
class CORE_COMMON_EXPORT FunctionReplyObject
{
public:
explicit FunctionReplyObject(int id = -1, const char *str = nullptr)
: m_str(str ? str : std::string())
, m_id(id)
{}
explicit FunctionReplyObject(const char *str)
: m_str(str ? str : std::string())
{}
explicit FunctionReplyObject(int id, const std::string &errStr, const std::vector<std::string> &errArgs)
: m_str(errStr)
, m_args(errArgs)
, m_id(id)
{}
explicit FunctionReplyObject(int id, std::string &&errStr, std::vector<std::string> &&errArgs)
: m_str(std::move(errStr))
, m_args(std::move(errArgs))
, m_id(id)
{}
explicit FunctionReplyObject(int id, const std::string &errStr, const std::vector<std::string> &errArgs, const std::string &additionalInfo)
: m_str(errStr)
, m_additionalInfo(additionalInfo)
, m_args(errArgs)
, m_id(id)
{}
explicit FunctionReplyObject(int id, std::string &&errStr, std::vector<std::string> &&errArgs, std::string &&additionalInfo)
: m_str(std::move(errStr))
, m_additionalInfo(std::move(additionalInfo))
, m_args(std::move(errArgs))
, m_id(id)
{}
~FunctionReplyObject() = default;
FunctionReplyObject &arg(qint64 val);
FunctionReplyObject &arg(const std::string &str);
FunctionReplyObject &arg(const QString &str);
bool error() const { return !m_str.empty(); }
void setId(int id) { m_id = id; }
FunctionReplyObject &setStr(const char *str) { m_str = str; return *this; }
FunctionReplyObject &setAdditionalInfo(const char *additionalInfo) { m_additionalInfo = additionalInfo; return *this; }
int id() const { return m_id; }
std::string str() const { return m_str; }
std::string additionalInfo() const { return m_additionalInfo; }
std::vector<std::string> args() const { return m_args; }
std::string operator()() const;
QString translated() const;
int64_t uniqueId() const { return m_uniqueId; }
void setUniqueId(int64_t uniqueId) { m_uniqueId = uniqueId; }
private:
std::string m_str;
std::string m_additionalInfo;
std::vector<std::string> m_args;
int64_t m_uniqueId = 0;
int m_id = -1;
};
}
+31
View File
@@ -0,0 +1,31 @@
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace Core
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "CORE.";
std::string loggerName;
const size_t len = strlen(name);
loggerName.reserve(sizeof(ns) + len);
loggerName.append(ns, sizeof(ns) - 1);
loggerName.append(name, len);
try
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger( loggerName );
}
catch ( const std::exception &ex )
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
}
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include <NGLLogger/INGLLogger.h>
#include "core_export.h"
namespace Core
{
using LOGGER_T = NGL::INGLLogger&;
CORE_COMMON_EXPORT LOGGER_T getLogger(const char *name);
}
+117
View File
@@ -0,0 +1,117 @@
#include "pacemaker.h"
#include <QCoreApplication>
#include <QThread>
#include <QTimer>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <DDS/DTS/generic_dts.h>
#include <DDS/DTS/generic_dts_impl.h>
#include <DDS/DDSConnector/dds_connector.h>
namespace Core
{
Pacemaker::Pacemaker(DDSConnector::DdsConnector *ddsConnector)
: QObject(nullptr)
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("Core.Pacemaker"))
{
init(ddsConnector);
}
Pacemaker::~Pacemaker()
{
m_paceThread->requestInterruption();
m_paceThread->quit();
m_paceThread->wait();
delete m_paceThread;
m_publishTimer->deleteLater();
delete m_dtsCurrentRunningState;
}
void Pacemaker::setNewState(Core::RunningState newState, const QString &errorString)
{
if (QThread::currentThread() == this->thread())
setNewStateInternal(newState, errorString);
else
QTimer::singleShot(0, this, [this, newState, errorString]() { setNewStateInternal(newState, errorString); });
}
void Pacemaker::setNewStateInternal(Core::RunningState newState, const QString &errorString)
{
m_state.runningState(newState);
if (errorString.isEmpty())
m_state.errorString().reset();
else
m_state.errorString(errorString.toStdString());
publishState();
}
void Pacemaker::addPort(unsigned short number, Core::PortType portType, const QString &properties)
{
if (QThread::currentThread() == this->thread())
addPortInternal(number, portType, properties);
else
QTimer::singleShot(0, this, [this, number, portType, properties]() { addPortInternal(number, portType, properties); });
}
void Pacemaker::addPortInternal(unsigned short number, Core::PortType portType,const QString &properties)
{
if (!m_state.ports().is_set())
m_state.ports() = std::vector<Core::PortInformation>();
m_state.ports().get().push_back(Core::PortInformation(number, portType, properties.toStdString()));
publishState();
}
void Pacemaker::publishState()
{
if (!m_dtsCurrentRunningState)
return;
m_dtsCurrentRunningState->write(m_state);
}
void Pacemaker::init(DDSConnector::DdsConnector *ddsConnector)
{
m_dtsCurrentRunningState = ddsConnector->createDTS<DTS::CurrentRunningStateImpl>();
if (!m_dtsCurrentRunningState)
{
WARNING_LOG(m_logger) << "Can not initialize DTS::CurrentRunningState!";
return;
}
m_state.pid(QCoreApplication::applicationPid());
m_state.runningState(Core::RunningState::Starting);
m_paceThread = new QThread;
this->moveToThread(m_paceThread);
startTimer();
publishState();
}
void Pacemaker::startTimer()
{
if (m_publishTimer)
return;
m_publishTimer = new QTimer();
m_publishTimer->moveToThread(m_paceThread);
connect(m_publishTimer, &QTimer::timeout,
this, &Pacemaker::publishState);
m_publishTimer->setSingleShot(false);
m_publishTimer->setInterval(m_publishTimerDelay);
connect(m_paceThread, &QThread::started, this, [this](){
m_publishTimer->start();
});
m_paceThread->start();
}
}
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include <QtCore/QObject>
#include <QtCore/QThread>
#include <DDS/Core/core_dts_types.h>
#include "core_export.h"
namespace DDSConnector
{
class DdsConnector;
}
class QTimer;
namespace NGL
{
class INGLLogger;
}
namespace Core
{
class CORE_CLIENT_EXPORT Pacemaker final : public QObject
{
Q_OBJECT
public:
explicit Pacemaker(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector)
: Pacemaker(ddsConnector.get())
{}
explicit Pacemaker(DDSConnector::DdsConnector *ddsConnector);
~Pacemaker();
void startTimer();
public Q_SLOTS:
void setNewState(Core::RunningState newState, const QString &errorString = QString());
void addPort(unsigned short number, Core::PortType portType, const QString &properties = QStringLiteral(""));
void publishState();
private:
void init(DDSConnector::DdsConnector *ddsConnector);
void setNewStateInternal(Core::RunningState newState, const QString &errorString = QString());
void addPortInternal(unsigned short number, Core::PortType portType, const QString &properties = QStringLiteral(""));
private:
static constexpr const int m_publishTimerDelay = 3000;
CurrentRunningState m_state;
QTimer *m_publishTimer = nullptr;
QThread *m_paceThread = nullptr;
DTS::CurrentRunningStateImpl *m_dtsCurrentRunningState;
NGL::INGLLogger &m_logger;
};
}
+47
View File
@@ -0,0 +1,47 @@
#include "topic_lock_master.h"
#include <DDS/DDSConnector/dds_connector.h>
namespace Core
{
TopicLockMaster::TopicLockMaster(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector)
: QObject(nullptr)
, m_coreDtc(nullptr)
{
init(ddsConnector);
}
TopicLockMaster::~TopicLockMaster()
{
m_coreDtc.reset();
}
bool TopicLockMaster::init(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector)
{
if (!ddsConnector)
return false;
m_coreDtc = Core::Interface::Dtc::create(ddsConnector);
if (!m_coreDtc)
return false;
m_coreDtc->enableAll();
m_coreDtc->lockedEntitys([this] (const LockedEntity &data) {
m_lockedEntitys << key(data.entityId(), data.exerciseId(), QString::fromStdString(data.entityTypeName()));
});
connect(m_coreDtc.get(), &Interface::Dtc::lockedEntityChanged, this,
[this] (const LockedEntity &data, DataModification modType)
{
key k(data.entityId(), data.exerciseId(), QString::fromStdString(data.entityTypeName()));
if (modType == DataModification::eAdded)
m_lockedEntitys << k;
else if (modType == DataModification::eRemoved)
m_lockedEntitys.remove(k);
} );
return true;
}
}
+64
View File
@@ -0,0 +1,64 @@
#pragma once
#include <Core/core_dtc.h>
#include <QSet>
#include <QString>
namespace DDSConnector
{
class DdsConnector;
}
namespace Core
{
struct key
{
inline key() = default;
inline key(int64_t id, int exId, const QString &name)
: entityTypeName(name)
, entityId(id)
, exerciseId(exId)
{}
inline bool operator==(const key &o) const
{
return entityId == o.entityId &&
exerciseId == o.exerciseId &&
entityTypeName == o.entityTypeName;
}
QString entityTypeName;
int64_t entityId = 0;
int exerciseId = 0;
};
inline uint qHash(const Core::key &k, uint seed = 0)
{
return ::qHash(k.entityTypeName, seed) ^ ::qHash(k.entityId, seed) ^ ::qHash(k.exerciseId, seed);
}
class CORE_CLIENT_EXPORT TopicLockMaster : public QObject
{
Q_OBJECT
public:
explicit TopicLockMaster(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector);
~TopicLockMaster();
bool init(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector);
template<typename E>
bool isLocked(const E &data, int exerciseId)
{
auto it = m_lockedEntitys.constFind(key(data.id(), exerciseId, QString::fromStdString(typeid(E).name())));
return !(it == m_lockedEntitys.cend());
}
private:
QSet<key> m_lockedEntitys;
std::shared_ptr<Core::Interface::Dtc> m_coreDtc;
};
}