From f2970327faee2b9616bb76629cb366cd1fc687fa Mon Sep 17 00:00:00 2001 From: jinchao <383321154@qq.com> Date: Tue, 20 May 2025 15:39:40 +0800 Subject: [PATCH] =?UTF-8?q?XNCore=E9=87=8D=E6=9E=84=E5=AE=8C=E6=88=90?= =?UTF-8?q?=EF=BC=8C=E6=9A=82=E6=9C=AA=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Release/include/XNCore/XNBaseFrameObject.h | 69 ++-- Release/include/XNCore/XNBaseFrameObject_p.h | 19 +- Release/include/XNCore/XNCore_global.h | 116 ++++++- Release/include/XNCore/XNDDSInterface.h | 193 +++++++---- Release/include/XNCore/XNDDSManager.h | 92 +++-- Release/include/XNCore/XNEventManager.h | 41 ++- Release/include/XNCore/XNEventManager_p.h | 145 +++++--- Release/include/XNCore/XNFramework.h | 205 +++++------ Release/include/XNCore/XNFramework_p.h | 54 ++- Release/include/XNCore/XNLogger.h | 88 +++-- Release/include/XNCore/XNModelManager.h | 58 +--- Release/include/XNCore/XNModelManager_p.h | 20 +- Release/include/XNCore/XNModelObject.h | 114 +++---- Release/include/XNCore/XNModelObject_p.h | 48 ++- Release/include/XNCore/XNObject.h | 78 +++-- Release/include/XNCore/XNObject_p.h | 26 +- Release/include/XNCore/XNScenarioManager.h | 96 +----- Release/include/XNCore/XNScenarioManager_p.h | 14 +- Release/include/XNCore/XNServiceManager.h | 35 +- Release/include/XNCore/XNServiceManager_p.h | 16 +- Release/include/XNCore/XNServiceObject.h | 84 +++-- Release/include/XNCore/XNServiceObject_p.h | 26 +- Release/include/XNCore/XNThread.h | 175 +++++----- Release/include/XNCore/XNThreadManager.h | 95 ++---- Release/include/XNCore/XNThreadManager_p.h | 39 +-- Release/include/XNCore/XNThread_p.h | 76 +++++ Release/include/XNCore/XNTimeManager.h | 56 +-- Release/include/XNCore/XNTimeManager_p.h | 17 +- XNCore/.vscode/settings.json | 3 +- XNCore/CMakeLists.txt | 2 +- XNCore/XNBaseFrameObject.cpp | 20 +- XNCore/XNBaseFrameObject.h | 69 ++-- XNCore/XNBaseFrameObject_p.h | 19 +- XNCore/XNCore_Function.cpp | 10 + XNCore/XNCore_global.h | 116 ++++++- XNCore/XNDDSInterface.h | 193 +++++++---- XNCore/XNDDSManager.cpp | 34 +- XNCore/XNDDSManager.h | 92 +++-- XNCore/XNDDSManager_p.h | 15 - XNCore/XNEventManager.cpp | 267 ++++++++------- XNCore/XNEventManager.h | 41 ++- XNCore/XNEventManager_p.h | 145 +++++--- XNCore/XNFramework.cpp | 318 ++++++++---------- XNCore/XNFramework.h | 205 +++++------ XNCore/XNFramework_p.h | 54 ++- XNCore/XNLogger.cpp | 59 ++-- XNCore/XNLogger.h | 88 +++-- XNCore/XNModelManager.cpp | 165 +++++---- XNCore/XNModelManager.h | 58 +--- XNCore/XNModelManager_p.h | 20 +- XNCore/XNModelObject.cpp | 276 ++++++++------- XNCore/XNModelObject.h | 114 +++---- XNCore/XNModelObject_p.h | 48 ++- XNCore/XNObject.cpp | 37 +- XNCore/XNObject.h | 78 +++-- XNCore/XNObject_p.h | 26 +- XNCore/XNScenarioManager.cpp | 234 +++++++------ XNCore/XNScenarioManager.h | 96 +----- XNCore/XNScenarioManager_p.h | 14 +- XNCore/XNServiceManager.cpp | 131 ++++---- XNCore/XNServiceManager.h | 35 +- XNCore/XNServiceManager_p.h | 16 +- XNCore/XNServiceObject.cpp | 184 +++++----- XNCore/XNServiceObject.h | 84 +++-- XNCore/XNServiceObject_p.h | 26 +- XNCore/XNThread.cpp | 309 ++++++----------- XNCore/XNThread.h | 175 +++++----- XNCore/XNThreadManager.cpp | 178 +++++----- XNCore/XNThreadManager.h | 95 ++---- XNCore/XNThreadManager_p.h | 39 +-- XNCore/XNThread_p.h | 76 +++++ XNCore/XNTimeManager.cpp | 76 ++--- XNCore/XNTimeManager.h | 56 +-- XNCore/XNTimeManager_p.h | 17 +- .../XNGroundHandling/.vscode/settings.json | 72 +++- .../XNGroundHandling/XNGroundHandling.cpp | 10 + .../XNGroundHandling/XNGroundHandling.h | 2 +- .../XNGroundHandling.hpp | 26 +- .../XNGroundHandling.idl | 2 +- .../XNGroundHandlingCdrAux.hpp | 2 +- .../XNGroundHandlingCdrAux.ipp | 5 +- .../XNGroundHandlingInterface.cxx | 22 +- .../XNGroundHandlingInterface.hpp | 100 +++++- .../XNGroundHandlingTypeObjectSupport.cxx | 15 +- 84 files changed, 3437 insertions(+), 3327 deletions(-) create mode 100644 Release/include/XNCore/XNThread_p.h create mode 100644 XNCore/XNCore_Function.cpp mode change 100755 => 100644 XNCore/XNDDSInterface.h delete mode 100755 XNCore/XNDDSManager_p.h create mode 100644 XNCore/XNThread_p.h diff --git a/Release/include/XNCore/XNBaseFrameObject.h b/Release/include/XNCore/XNBaseFrameObject.h index b9ac873..26c0f65 100644 --- a/Release/include/XNCore/XNBaseFrameObject.h +++ b/Release/include/XNCore/XNBaseFrameObject.h @@ -12,34 +12,29 @@ #include "XNObject.h" -class XNBaseFrameObjectPrivate; +struct XNBaseFrameObjectPrivate; /** * @brief 框架对象基类 */ class XNCORE_EXPORT XNBaseFrameObject : public XNObject { - /** - * @brief 宏定义,用于支持Qt的元对象系统 - */ - Q_OBJECT - /** * @brief 宏定义,用于禁用拷贝构造函数 */ - Q_DISABLE_COPY(XNBaseFrameObject) + XN_METATYPE(XNBaseFrameObject, XNObject) /** * @brief 宏定义,用于声明私有数据成员 */ - Q_DECLARE_PRIVATE(XNBaseFrameObject); + XN_DECLARE_PRIVATE(XNBaseFrameObject) public: /** * @brief 构造函数 * @param parent 父对象 */ - XNBaseFrameObject(QObject *parent = nullptr); + XNBaseFrameObject(); /** * @brief 析构函数 @@ -52,44 +47,34 @@ protected: * @param dd 私有数据成员 * @param parent 父对象 */ - XNBaseFrameObject(XNBaseFrameObjectPrivate &dd, QObject *parent = nullptr); - -signals: - /** - * @brief 初始化 - */ - void Initialize(); - - /** - * @brief 初始化失败 - */ - void InitializeFailed(); - - /** - * @brief 准备执行 - */ - void PrepareForExecute(); - - /** - * @brief 准备执行失败 - */ - void PrepareForExecuteFailed(); - -public slots: - /** - * @brief 初始化 - */ - virtual void OnInitialize() = 0; - - /** - * @brief 准备执行 - */ - virtual void OnPrepareForExecute() = 0; + XNBaseFrameObject(PrivateType *p); public: + /** + * @brief 初始化 + */ + virtual bool Initialize() = 0; + + /** + * @brief 准备执行 + */ + virtual bool PrepareForExecute() = 0; + /** * @brief 获取框架对象状态 * @return 框架对象状态 */ XNFrameObjectStatus GetFrameObjectStatus(); + + /** + * @brief 获取框架对象 + * @return 框架对象 + */ + XNFrameworkPtr GetFramework(); + + /** + * @brief 设置框架对象 + * @param framework 框架对象 + */ + void SetFramework(XNFrameworkPtr framework); }; diff --git a/Release/include/XNCore/XNBaseFrameObject_p.h b/Release/include/XNCore/XNBaseFrameObject_p.h index 6f36523..1177b7c 100644 --- a/Release/include/XNCore/XNBaseFrameObject_p.h +++ b/Release/include/XNCore/XNBaseFrameObject_p.h @@ -16,22 +16,13 @@ /** * @brief 框架对象基类的私有数据成员 */ -class XNBaseFrameObjectPrivate : public XNObjectPrivate -{ -public: - /** - * @brief 构造函数 - * @param q 框架对象基类指针 - */ - explicit XNBaseFrameObjectPrivate(XNBaseFrameObject *q) : XNObjectPrivate(q) {} - - /** - * @brief 宏定义,用于声明公有数据成员 - */ - Q_DECLARE_PUBLIC(XNBaseFrameObject) - +struct XNBaseFrameObjectPrivate : public XNObjectPrivate { /** * @brief 框架对象状态 */ XNFrameObjectStatus _status = XNFrameObjectStatus::NotReady; + /** + * @brief 框架对象 + */ + XNFrameworkPtr _framework; }; diff --git a/Release/include/XNCore/XNCore_global.h b/Release/include/XNCore/XNCore_global.h index 682f264..bc921ab 100644 --- a/Release/include/XNCore/XNCore_global.h +++ b/Release/include/XNCore/XNCore_global.h @@ -1,14 +1,13 @@ -#ifndef XNCORE_GLOBAL_H -#define XNCORE_GLOBAL_H - -#include +#pragma once #if defined(XNCORE_LIBRARY) -# define XNCORE_EXPORT Q_DECL_EXPORT +# define XNCORE_EXPORT __attribute__((visibility("default"))) #else -# define XNCORE_EXPORT Q_DECL_IMPORT +# define XNCORE_EXPORT __attribute__((visibility("default"))) #endif +#define FORCEINLINE __attribute__((always_inline)) + #ifdef __linux__ # include # include @@ -20,8 +19,34 @@ # include # include # include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif +#include +#include +#include +#include +#include +#include +#include +#include #define FAST_DDS_MACRO eprosima::fastdds::dds /** @@ -40,6 +65,9 @@ using XNCallBack = std::function; //DDS回调函数类型别名 using XNDDSCallBack = std::function; +//事件回调函数类型别名 +using XNEventCallback = std::function; + /** * @brief 纳秒睡眠相关时间结构体 * @details 用于线程睡眠时间控制 @@ -54,6 +82,17 @@ struct PERIOD_INFO { */ long period_ns; }; +/** + * @brief 系统时间点类型别名 + */ +using XNTimePoint = std::chrono::system_clock::time_point; + +/** + * @brief 将ISO格式的时间字符串转换为系统时间点 + * @param timeStr ISO格式的时间字符串 (YYYY-MM-DDTHH:mm:ss) + * @return 系统时间点 + */ +XNTimePoint parseISOTime(const std::string &timeStr); /** * @brief 系统运行状态枚举类 @@ -155,10 +194,63 @@ enum class XNFrameObjectStatus { Unknown }; -#define XN_DLL_INITIALIZE(ClassName) \ - extern "C" void Initial##ClassName() \ - { \ - qRegisterMetaType(#ClassName); \ - } +template +FORCEINLINE ToType XNStaticCastHelper(const FromType &from) +{ + return std::static_pointer_cast(from); +} -#endif // XNCORE_GLOBAL_H +template +FORCEINLINE ToType XNCastHelper(const FromType &from) +{ + return std::dynamic_pointer_cast(from); +} + +#define XN_CAST(from, to) XNStaticCastHelper(from) + +#define XN_THISPTR std::static_pointer_cast(shared_from_this()) + +#define XNCLASS_PTR_DECLARE(a) \ + using a##Ptr = std::shared_ptr; \ + using a##WPtr = std::weak_ptr; \ + using a##UPtr = std::unique_ptr; \ + using a##ConsPtr = std::shared_ptr; + +#define XNSTRUCT_PTR_DECLARE(a) \ + using a##Ptr = std::shared_ptr; \ + using a##WPtr = std::weak_ptr; \ + using a##UPtr = std::unique_ptr; \ + using a##ConsPtr = std::shared_ptr; + +#define XN_NOCOPYABLE(Class) \ +public: \ + using NoCopyable = Class; \ + \ +private: \ + Class(const Class &) = delete; \ + Class &operator=(const Class &) = delete; + +#define XN_DECLARE_PRIVATE(Class) \ + XN_NOCOPYABLE(Class) \ +protected: \ + friend class Class##Private; \ + inline Class##Private *GetPP() const \ + { \ + return reinterpret_cast(_Private_Ptr); \ + } \ + using PrivateType = Class##Private; + +#define T_D() PrivateType *const d = GetPP() + +struct XNNullClass { +}; + +#define XN_METATYPE_P(cls) \ +public: \ + using ThisType = cls; \ + using SuperType = XNNullClass; + +#define XN_METATYPE(cls, sup) \ +public: \ + using ThisType = cls; \ + using SuperType = sup; diff --git a/Release/include/XNCore/XNDDSInterface.h b/Release/include/XNCore/XNDDSInterface.h index 5b1f610..b884b45 100644 --- a/Release/include/XNCore/XNDDSInterface.h +++ b/Release/include/XNCore/XNDDSInterface.h @@ -45,44 +45,6 @@ public: XNDDSInterface() = default; virtual ~XNDDSInterface() = default; - template - void getByteArray(eprosima::fastcdr::optional data, uint8_t *buffer, size_t bufferSize) - { - if (bufferSize < getTypeSize()) - return; - - if constexpr (std::is_arithmetic_v) { - if (data) { - std::memcpy(buffer, &data.value(), sizeof(T)); - } else { - T zero = 0; - std::memcpy(buffer, &zero, sizeof(T)); - } - } else if constexpr (is_std_array_v) { - if (data) { - getByteArrayFromStdArray(data.value(), buffer, bufferSize); - } else { - T zero = {}; - getByteArrayFromStdArray(zero, buffer, bufferSize); - } - } - } - - template - void getByteArrayFromStdArray(std::array data, uint8_t *buffer, size_t bufferSize) - { - if (bufferSize < getTypeSize() * N) - return; - - for (std::size_t i = 0; i < N; ++i) { - if constexpr (std::is_arithmetic_v) { - std::memcpy(buffer + i * getTypeSize(), &data[i], getTypeSize()); - } else { - getByteArrayFromStdArray(data[i], buffer + i * getTypeSize(), getTypeSize()); - } - } - } - void getUDPPackage(uint8_t *buffer, size_t bufferSize) { if (bufferSize < MAX_UDP_PACKET_SIZE) @@ -112,42 +74,6 @@ public: } } - template - std::string getString(eprosima::fastcdr::optional data) - { - if constexpr (std::is_arithmetic_v) { - if (data) { - return std::to_string(data.value()); - } else { - return std::to_string(0); - } - } else if constexpr (std::is_same_v) { - if (data) { - return getStringFromStdArray(data.value()); - } else { - T zero = {}; - return getStringFromStdArray(zero); - } - } - return std::string(); - } - - template - std::string getStringFromStdArray(std::array data) - { - std::stringstream ss; - for (std::size_t i = 0; i < N; ++i) { - if (i > 0) - ss << ","; - if constexpr (std::is_arithmetic_v) { - ss << data[i]; - } else { - ss << getStringFromStdArray(data[i]); - } - } - return ss.str(); - } - std::string getData(const std::string &varName) { int index1 = -1; @@ -221,6 +147,81 @@ public: return list2[index2]; } +protected: + template + void getByteArray(eprosima::fastcdr::optional data, uint8_t *buffer, size_t bufferSize) + { + if (bufferSize < getTypeSize()) + return; + + if constexpr (std::is_arithmetic_v) { + if (data) { + std::memcpy(buffer, &data.value(), sizeof(T)); + } else { + T zero = 0; + std::memcpy(buffer, &zero, sizeof(T)); + } + } else if constexpr (is_std_array_v) { + if (data) { + getByteArrayFromStdArray(data.value(), buffer, bufferSize); + } else { + T zero = {}; + getByteArrayFromStdArray(zero, buffer, bufferSize); + } + } + } + + template + void getByteArrayFromStdArray(std::array data, uint8_t *buffer, size_t bufferSize) + { + if (bufferSize < getTypeSize() * N) + return; + + for (std::size_t i = 0; i < N; ++i) { + if constexpr (std::is_arithmetic_v) { + std::memcpy(buffer + i * getTypeSize(), &data[i], getTypeSize()); + } else { + getByteArrayFromStdArray(data[i], buffer + i * getTypeSize(), getTypeSize()); + } + } + } + + template + std::string getString(eprosima::fastcdr::optional data) + { + if constexpr (std::is_arithmetic_v) { + if (data) { + return std::to_string(data.value()); + } else { + return std::to_string(0); + } + } else if constexpr (std::is_same_v) { + if (data) { + return getStringFromStdArray(data.value()); + } else { + T zero = {}; + return getStringFromStdArray(zero); + } + } + return std::string(); + } + + template + std::string getStringFromStdArray(std::array data) + { + std::stringstream ss; + for (std::size_t i = 0; i < N; ++i) { + if (i > 0) + ss << ","; + if constexpr (std::is_arithmetic_v) { + ss << data[i]; + } else { + ss << getStringFromStdArray(data[i]); + } + } + return ss.str(); + } + protected: struct ByteArrayFunc { std::function func; @@ -239,3 +240,47 @@ protected: getByteArrayFunction.push_back( \ {[this](uint8_t *buffer, size_t size) { getByteArray(data.NAME(), buffer, size); }, \ getTypeSize()}) + +#define ASSIGN_VALUE_GET(NAME) \ + if (data.NAME()) { \ + auto temp = data.NAME().value(); \ + if constexpr (std::is_arithmetic_v) { \ + model_data->NAME = temp; \ + } else if constexpr (std::is_std_array_v) { \ + size_t arraySize = std::tuple_size::value; \ + for (size_t i = 0; i < arraySize; ++i) { \ + if constexpr (std::is_arithmetic_v) { \ + model_data->NAME[i] = temp[i]; \ + } else if constexpr (std::is_std_array_v) { \ + size_t arraySize2 = std::tuple_size::value; \ + for (size_t j = 0; j < arraySize2; ++j) { \ + model_data->NAME[i][j] = temp[i][j]; \ + } \ + } \ + } \ + } \ + } + +#define ASSIGN_VALUE_SET(NAME) \ + if constexpr (std::is_arithmetic_v) { \ + data.NAME(model_data->NAME); \ + } else if constexpr (std::is_std_array_v) { \ + using thisType = typename decltype(data.NAME())::type; \ + thisType temp; \ + size_t arraySize1 = std::tuple_size::value; \ + using subType = thisType::value_type; \ + if constexpr (std::is_arithmetic_v) { \ + for (size_t i = 0; i < arraySize1; ++i) { \ + temp[i] = model_data->NAME[i]; \ + } \ + } else if constexpr (std::is_std_array_v) { \ + size_t arraySize2 = std::tuple_size::value; \ + std::array temp; \ + for (size_t i = 0; i < arraySize1; ++i) { \ + for (size_t j = 0; j < arraySize2; ++j) { \ + temp[i][j] = model_data->NAME[i][j]; \ + } \ + } \ + } \ + data.NAME(temp); \ + } diff --git a/Release/include/XNCore/XNDDSManager.h b/Release/include/XNCore/XNDDSManager.h index b7274c1..216edbf 100644 --- a/Release/include/XNCore/XNDDSManager.h +++ b/Release/include/XNCore/XNDDSManager.h @@ -1,14 +1,6 @@ #pragma once #include "XNBaseFrameObject.h" - -#include -#include -#include -#include -#include -#include -#include -#include +#include "XNBaseFrameObject_p.h" struct PublisherInfo { FAST_DDS_MACRO::Publisher *publisher; @@ -22,8 +14,8 @@ struct SubscriberInfo { struct TopicInfo { FAST_DDS_MACRO::Topic *topic; - QMap publishers_; - QMap subscribers_; + std::map publishers_; + std::map subscribers_; }; template @@ -46,50 +38,54 @@ private: std::function callback_; }; -class XNDDSManagerPrivate; +struct XNDDSManagerPrivate : public XNBaseFrameObjectPrivate { + FAST_DDS_MACRO::DomainParticipant *participant_; + std::map topics_; + std::mutex mutex_; +}; class XNDDSManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNDDSManager) - Q_DISABLE_COPY(XNDDSManager) + XN_METATYPE(XNDDSManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNDDSManager) public: - explicit XNDDSManager(QObject *parent = nullptr); + XNDDSManager(); ~XNDDSManager(); protected: - XNDDSManager(XNDDSManagerPrivate &dd, QObject *parent = nullptr); + XNDDSManager(PrivateType *p); -public slots: - virtual void OnInitialize() override; +public: + virtual bool Initialize() override; - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; - void SetDomainID(quint32 domainID); + void SetDomainID(uint32_t domainID); public: template - FAST_DDS_MACRO::DataWriter *RegisterPublisher(const QString &topicName, quint32 publisherID) + FAST_DDS_MACRO::DataWriter *RegisterPublisher(const std::string &topicName, + uint32_t publisherID) { - std::lock_guard lock(mutex_); - if (!topics_.contains(topicName)) { - topics_[topicName] = TopicInfo(); - TopicInfo &tmp = topics_[topicName]; + T_D(); + std::lock_guard lock(d->mutex_); + if (d->topics_.find(topicName) == d->topics_.end()) { + d->topics_[topicName] = TopicInfo(); + TopicInfo &tmp = d->topics_[topicName]; FAST_DDS_MACRO::TypeSupport typeSupport(new T()); - typeSupport.register_type(participant_); - tmp.topic = - participant_->create_topic(topicName.toStdString(), typeSupport.get_type_name(), - FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); + typeSupport.register_type(d->participant_); + tmp.topic = d->participant_->create_topic(topicName, typeSupport.get_type_name(), + FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); if (tmp.topic == nullptr) { LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName); - topics_.remove(topicName); + d->topics_.erase(topicName); return nullptr; } } - TopicInfo &tmp = topics_[topicName]; + TopicInfo &tmp = d->topics_[topicName]; tmp.publishers_[publisherID] = PublisherInfo(); tmp.publishers_[publisherID].publisher = - participant_->create_publisher(FAST_DDS_MACRO::PUBLISHER_QOS_DEFAULT, nullptr); + d->participant_->create_publisher(FAST_DDS_MACRO::PUBLISHER_QOS_DEFAULT, nullptr); if (tmp.publishers_[publisherID].publisher == nullptr) { LOG_ERROR("0x2131 Create Publisher %1 for Topic %2 Failed!", publisherID, topicName); return nullptr; @@ -119,29 +115,28 @@ public: } template - void RegisterSubscriber(const QString &topicName, quint32 subscriberID, + void RegisterSubscriber(const std::string &topicName, uint32_t subscriberID, std::function fun) { - Q_D(XNDDSManager); - std::lock_guard lock(mutex_); - if (!topics_.contains(topicName)) { - topics_[topicName] = TopicInfo(); - TopicInfo &tmp = topics_[topicName]; + T_D(); + std::lock_guard lock(d->mutex_); + if (d->topics_.find(topicName) == d->topics_.end()) { + d->topics_[topicName] = TopicInfo(); + TopicInfo &tmp = d->topics_[topicName]; FAST_DDS_MACRO::TypeSupport typeSupport(new T()); - typeSupport.register_type(participant_); - tmp.topic = - participant_->create_topic(topicName.toStdString(), typeSupport.get_type_name(), - FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); + typeSupport.register_type(d->participant_); + tmp.topic = d->participant_->create_topic(topicName, typeSupport.get_type_name(), + FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); if (tmp.topic == nullptr) { LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName); - topics_.remove(topicName); + d->topics_.erase(topicName); return; } } - TopicInfo &tmp = topics_[topicName]; + TopicInfo &tmp = d->topics_[topicName]; tmp.subscribers_[subscriberID] = SubscriberInfo(); tmp.subscribers_[subscriberID].subscriber = - participant_->create_subscriber(FAST_DDS_MACRO::SUBSCRIBER_QOS_DEFAULT, nullptr); + d->participant_->create_subscriber(FAST_DDS_MACRO::SUBSCRIBER_QOS_DEFAULT, nullptr); if (tmp.subscribers_[subscriberID].subscriber == nullptr) { LOG_ERROR("0x2135 Create Subscriber %1 for Topic %2 Failed!", subscriberID, topicName); } @@ -157,9 +152,4 @@ public: } LOG_INFO("0x2137 Create Subscriber %1 for Topic %2 Success!", subscriberID, topicName); } - -private: - FAST_DDS_MACRO::DomainParticipant *participant_; - QMap topics_; - std::mutex mutex_; }; diff --git a/Release/include/XNCore/XNEventManager.h b/Release/include/XNCore/XNEventManager.h index 4c5067c..4d046fd 100644 --- a/Release/include/XNCore/XNEventManager.h +++ b/Release/include/XNCore/XNEventManager.h @@ -1,6 +1,6 @@ #pragma once #include "XNBaseFrameObject.h" -#include + // 事件优先级定义 namespace XNEvent { @@ -11,19 +11,18 @@ enum class Priority { Low = 3 // 低优先级 }; } + // 前向声明私有类 -class XNEventManagerPrivate; +struct XNEventManagerPrivate; // 事件管理器类,继承自XNBaseFrameObject class XNEventManager : public XNBaseFrameObject { - Q_OBJECT // 启用Qt的元对象系统 - Q_DECLARE_PRIVATE(XNEventManager) // 声明私有实现类 - Q_DISABLE_COPY(XNEventManager) // 禁用拷贝构造和赋值操作 - - public : - // 构造函数,创建事件管理器实例 - explicit XNEventManager(QObject *parent = nullptr); + XN_METATYPE(XNEventManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNEventManager) +public: + // 构造函数,创建事件管理器实例 + XNEventManager(); // 析构函数 ~XNEventManager(); @@ -34,21 +33,20 @@ class XNEventManager : public XNBaseFrameObject // @param async: 是否异步处理该事件 // @param priority: 事件优先级 // @return: 返回处理器ID,失败返回-1 - int RegisterEventHandler(const QString &eventName, - std::function callback, quint32 objectId, - bool async = false, + int RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + uint32_t objectId, bool async = false, XNEvent::Priority priority = XNEvent::Priority::Normal); // 移除事件处理器 // @param eventName: 事件名称 // @param handlerId: 处理器ID // @return: 移除是否成功 - bool RemoveEventHandler(const QString &eventName, int handlerId); + bool RemoveEventHandler(const std::string &eventName, int handlerId); // 触发指定事件 // @param eventName: 要触发的事件名称 // @param eventData: 事件携带的数据 // @param forceAsync: 强制异步处理 // @param priority: 事件优先级 - void TriggerEvent(const QString &eventName, const QVariant &eventData = QVariant(), + void TriggerEvent(const std::string &eventName, const std::any &eventData = std::any(), bool forceAsync = false, XNEvent::Priority priority = XNEvent::Priority::Normal); @@ -64,17 +62,16 @@ class XNEventManager : public XNBaseFrameObject // 设置实时线程池参数 void SetRTThreadPoolConfig(int maxThreads, int minPriority, int maxPriority); + // 事件处理完成回调 + void EventProcessed(const std::string &eventName, bool success); + protected: // 保护构造函数,用于继承实现 - XNEventManager(XNEventManagerPrivate &dd, QObject *parent = nullptr); + XNEventManager(PrivateType *p); -public slots: +public: // 初始化事件管理器 - virtual void OnInitialize() override; + virtual bool Initialize() override; // 准备执行 - virtual void OnPrepareForExecute() override; - -signals: - // 事件处理完成信号 - void EventProcessed(const QString &eventName, bool success); + virtual bool PrepareForExecute() override; }; \ No newline at end of file diff --git a/Release/include/XNCore/XNEventManager_p.h b/Release/include/XNCore/XNEventManager_p.h index 7d38fd4..a381b4b 100644 --- a/Release/include/XNCore/XNEventManager_p.h +++ b/Release/include/XNCore/XNEventManager_p.h @@ -1,9 +1,6 @@ #pragma once #include "XNBaseFrameObject_p.h" #include "XNEventManager.h" -#include -#include -#include #include #include #include @@ -12,78 +9,130 @@ #include #include #include +#include +#include +#include +#include // 事件处理器信息结构 struct EventHandlerInfo { - std::function callback; // 回调函数 - quint32 objectId; // 对象ID - int localId; // 本地ID + std::function callback; // 回调函数 + uint32_t objectId; // 对象ID + uint32_t localId; // 本地ID bool isAsync; // 是否异步处理 XNEvent::Priority priority; // 事件优先级 - int threadPriority; // 线程优先级 + uint32_t threadPriority; // 线程优先级 // 获取全局处理器ID - int GetHandlerId() const { return (objectId << 16) | (localId & 0xFFFF); } + uint32_t GetHandlerId() const { return (objectId << 16) | (localId & 0xFFFF); } // 从全局处理器ID中提取对象ID - static quint32 GetObjectId(int handlerId) { return handlerId >> 16; } + static uint32_t GetObjectId(uint32_t handlerId) { return handlerId >> 16; } // 从全局处理器ID中提取本地ID - static int GetLocalId(int handlerId) { return handlerId & 0xFFFF; } + static uint32_t GetLocalId(uint32_t handlerId) { return handlerId & 0xFFFF; } }; // 事件任务基类 -class BaseEventTask : public QRunnable +class BaseEventTask { public: - BaseEventTask(const QString &name, const QVariant &data, - std::function callback, XNEventManager *manager) + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + BaseEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) : eventName(name), eventData(data), eventCallback(callback), eventManager(manager) { - setAutoDelete(true); } virtual ~BaseEventTask() = default; + /** + * @brief 执行任务 + */ + virtual void execute() = 0; + protected: - QString eventName; - QVariant eventData; - std::function eventCallback; + std::string eventName; + std::any eventData; + std::function eventCallback; XNEventManager *eventManager; }; -// 实时事件任务 -class RTEventTask +// 异步事件任务 +class AsyncEventTask : public BaseEventTask { public: - RTEventTask(const QString &name, const QVariant &data, - std::function callback, XNEventManager *manager) - : eventName(name), eventData(data), eventCallback(callback), eventManager(manager) + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + AsyncEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) + : BaseEventTask(name, data, callback, manager) { } - void execute() + /** + * @brief 执行任务 + */ + void execute() override { try { eventCallback(eventData); if (eventManager) { - QMetaObject::invokeMethod(eventManager, "EventProcessed", Qt::QueuedConnection, - Q_ARG(QString, eventName), Q_ARG(bool, true)); + eventManager->EventProcessed(eventName, true); } } catch (const std::exception &e) { - LOG_ERROR( - QString("RT event handler exception for %1: %2").arg(eventName).arg(e.what())); + LOG_ERROR("Async event handler exception for " + eventName + ": " + e.what()); if (eventManager) { - QMetaObject::invokeMethod(eventManager, "EventProcessed", Qt::QueuedConnection, - Q_ARG(QString, eventName), Q_ARG(bool, false)); + eventManager->EventProcessed(eventName, false); } } } +}; -private: - QString eventName; - QVariant eventData; - std::function eventCallback; - XNEventManager *eventManager; +// 实时事件任务 +class RTEventTask : public BaseEventTask +{ +public: + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + RTEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) + : BaseEventTask(name, data, callback, manager) + { + } + + /** + * @brief 执行任务 + */ + void execute() override + { + try { + eventCallback(eventData); + if (eventManager) { + eventManager->EventProcessed(eventName, true); + } + } catch (const std::exception &e) { + LOG_ERROR("RT event handler exception for " + eventName + ": " + e.what()); + if (eventManager) { + eventManager->EventProcessed(eventName, false); + } + } + } }; // 实时线程管理器 @@ -167,35 +216,27 @@ private: }; // 事件管理器的私有实现类 -class XNEventManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - // 声明公共接口类 - Q_DECLARE_PUBLIC(XNEventManager) - - // 构造函数,初始化私有实现 - explicit XNEventManagerPrivate(XNEventManager *q) : XNBaseFrameObjectPrivate(q) {} - +struct XNEventManagerPrivate : public XNBaseFrameObjectPrivate { // 存储事件及其对应的处理器信息列表 // key: 事件名称 // value: 该事件对应的所有处理器信息列表 - QMap> eventHandlers; + std::map> eventHandlers; // 处理器ID到事件名称的反向映射,用于快速查找 - QMap handlerToEvent; + std::map handlerToEvent; // 本地ID计数器 int localIdCounter = 0; // 互斥锁,用于保护事件处理器表的线程安全访问 - QMutex eventMutex; + std::mutex eventMutex; - // 线程池,用于异步执行事件处理器 - QThreadPool threadPool; - - // 实时线程池 - QThreadPool rtThreadPool; + // 线程池相关 + std::vector workerThreads; + std::queue taskQueue; + std::mutex taskMutex; + std::condition_variable taskCond; + bool running = true; RTThreadManager rtManager; - QThreadPool normalThreadPool; // 用于非实时任务 }; diff --git a/Release/include/XNCore/XNFramework.h b/Release/include/XNCore/XNFramework.h index 2665e62..bf31993 100644 --- a/Release/include/XNCore/XNFramework.h +++ b/Release/include/XNCore/XNFramework.h @@ -12,195 +12,164 @@ #include "XNObject.h" -class XNFrameworkPrivate; +struct XNFrameworkPrivate; /** * @brief 框架类 */ class XNCORE_EXPORT XNFramework : public XNObject { - /** - * @brief 宏定义,用于支持Qt的元对象系统 - */ - Q_OBJECT - /** * @brief 宏定义,用于禁用拷贝构造函数 */ - Q_DISABLE_COPY(XNFramework) + XN_METATYPE(XNFramework, XNObject) /** * @brief 宏定义,用于声明私有数据成员 */ - Q_DECLARE_PRIVATE(XNFramework); - - /** - * @brief 宏定义,用于声明属性workPath - */ - Q_PROPERTY(QString workPath READ GetWorkPath WRITE SetWorkPath) - - /** - * @brief 宏定义,用于声明属性modelPath - */ - Q_PROPERTY(QString modelPath READ GetModelPath WRITE SetModelPath) - - /** - * @brief 宏定义,用于声明属性cpuAffinity - */ - Q_PROPERTY(quint32 cpuAffinity READ GetCpuAffinity WRITE SetCpuAffinity) - + XN_DECLARE_PRIVATE(XNFramework) public: /** * @brief 构造函数 * @param parent 父对象 */ - explicit XNFramework(QObject *parent = nullptr); + XNFramework(); /** * @brief 析构函数 */ virtual ~XNFramework(); +protected: + /** + * @brief 构造函数 + * @param p 私有数据成员 + */ + XNFramework(PrivateType *p); + +public: + /** + * @brief 获取DDS管理器 + * @return DDS管理器 + */ + XNDDSManagerPtr GetDDSManager(); + + /** + * @brief 获取事件管理器 + * @return 事件管理器 + */ + XNEventManagerPtr GetEventManager(); + + /** + * @brief 获取模型管理器 + * @return 模型管理器 + */ + XNModelManagerPtr GetModelManager(); + + /** + * @brief 获取场景管理器 + * @return 场景管理器 + */ + XNScenarioManagerPtr GetScenarioManager(); + + /** + * @brief 获取服务管理器 + * @return 服务管理器 + */ + XNServiceManagerPtr GetServiceManager(); + + /** + * @brief 获取线程管理器 + * @return 线程管理器 + */ + XNThreadManagerPtr GetThreadManager(); + + /** + * @brief 获取时间管理器 + * @return 时间管理器 + */ + XNTimeManagerPtr GetTimeManager(); + /** * @brief 获取工作路径 * @return 工作路径 */ - QString GetWorkPath(); + std::string GetWorkPath(); + + /** + * @brief 设置工作路径 + * @param workPath 工作路径 + */ + void SetWorkPath(const std::string &workPath); /** * @brief 获取模型库路径 * @return 模型库路径 */ - QString GetModelPath(); + std::string GetModelPath(); + + /** + * @brief 设置模型库路径 + * @param modelPath 模型库路径 + */ + void SetModelPath(const std::string &modelPath); /** * @brief 获取服务库路径 * @return 服务库路径 */ - QString GetServicePath(); + std::string GetServicePath(); + + /** + * @brief 设置服务库路径 + * @param servicePath 服务库路径 + */ + void SetServicePath(const std::string &servicePath); /** * @brief 获取CPU亲和性 * @return CPU亲和性 */ - quint32 GetCpuAffinity(); + uint32_t GetCpuAffinity(); + + /** + * @brief 设置CPU亲和性 + * @param cpuAffinity CPU亲和性 + */ + void SetCpuAffinity(uint32_t cpuAffinity); /** * @brief 设置场景XML * @param scenarioXml 场景XML */ - void SetScenarioXml(const QString &scenarioXml); - -signals: - /** - * @brief 初始化 - */ - void Initialize(); - - /** - * @brief 初始化成功 - */ - void InitializeSuccess(bool isSuccess); + void SetScenarioXml(const std::string &scenarioXml); /** * @brief 准备执行 */ void PrepareForExecute(); - /** - * @brief 准备执行成功 - */ - void PrepareForExecuteSuccess(bool isSuccess); - /** * @brief 分析场景XML * @param scenarioXml 场景XML */ - void AnalyzeScenarioXml(const QString &scenarioXml); + void AnalyzeScenarioXml(const std::string &scenarioXml); /** * @brief 仿真控制 * @param objectId 对象ID * @param cmd 命令 */ - void SimControl(quint32 objectId, SimControlCmd cmd); - -public slots: - /** - * @brief 设置工作路径 - * @param workPath 工作路径 - */ - void SetWorkPath(const QString &workPath); - - /** - * @brief 设置模型库路径 - * @param modelPath 模型库路径 - */ - void SetModelPath(const QString &modelPath); - - /** - * @brief 设置服务库路径 - * @param servicePath 服务库路径 - */ - void SetServicePath(const QString &servicePath); - - /** - * @brief 设置CPU亲和性 - * @param cpuAffinity CPU亲和性 - */ - void SetCpuAffinity(quint32 cpuAffinity); + void SimControl(uint32_t objectId, SimControlCmd cmd); /** * @brief 初始化 */ - void OnInitialize(); - - /** - * @brief 初始化成功 - */ - void OnInitializeSuccess(); - - /** - * @brief 初始化失败 - */ - void OnInitializeFailed(); - - /** - * @brief 解析配置文件成功 - */ - void OnAnalyzeScenarioXmlSuccess(); - - /** - * @brief 解析配置文件失败 - */ - void OnAnalyzeScenarioXmlFailed(); - - /** - * @brief 准备执行 - */ - void OnPrepareForExecute(); - - /** - * @brief 准备执行成功 - */ - void OnPrepareForExecuteSuccess(); - - /** - * @brief 准备执行失败 - */ - void OnPrepareForExecuteFailed(); + void Initialize(); /** * @brief 仿真控制 * @param cmd 命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); - -protected: - /** - * @brief 构造函数 - * @param dd 私有数据成员 - * @param parent 父对象 - */ - XNFramework(XNFrameworkPrivate &dd, QObject *parent = nullptr); + void OnSimControl(uint32_t objectId, SimControlCmd cmd); }; diff --git a/Release/include/XNCore/XNFramework_p.h b/Release/include/XNCore/XNFramework_p.h index 89058f6..cb27a74 100644 --- a/Release/include/XNCore/XNFramework_p.h +++ b/Release/include/XNCore/XNFramework_p.h @@ -16,43 +16,65 @@ /** * @brief 框架类的私有数据成员 */ -class XNFrameworkPrivate : public XNObjectPrivate -{ -public: - /** - * @brief 构造函数 - * @param q 框架类指针 - */ - explicit XNFrameworkPrivate(XNFramework *q) : XNObjectPrivate(q) {} +struct XNFrameworkPrivate : public XNObjectPrivate { /** - * @brief 宏定义,用于声明公有数据成员 + * @brief DDS管理器 */ - Q_DECLARE_PUBLIC(XNFramework) + XNDDSManagerPtr ddsManager; + + /** + * @brief 事件管理器 + */ + XNEventManagerPtr eventManager; + + /** + * @brief 模型管理器 + */ + XNModelManagerPtr modelManager; + + /** + * @brief 场景管理器 + */ + XNScenarioManagerPtr scenarioManager; + + /** + * @brief 服务管理器 + */ + XNServiceManagerPtr serviceManager; + + /** + * @brief 线程管理器 + */ + XNThreadManagerPtr threadManager; + + /** + * @brief 时间管理器 + */ + XNTimeManagerPtr timeManager; -private: /** * @brief 工作路径 */ - QString workPath; + std::string workPath; /** * @brief 模型路径 */ - QString modelPath; + std::string modelPath; /** * @brief 服务路径 */ - QString servicePath; + std::string servicePath; /** * @brief CPU亲和性 */ - quint32 uCpuAffinity; + uint32_t uCpuAffinity; /** * @brief 场景XML */ - QString scenarioXml; + std::string scenarioXml; }; diff --git a/Release/include/XNCore/XNLogger.h b/Release/include/XNCore/XNLogger.h index 149bfc7..0165e28 100644 --- a/Release/include/XNCore/XNLogger.h +++ b/Release/include/XNCore/XNLogger.h @@ -9,13 +9,15 @@ * */ #pragma once -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include +#include +#include +#include /** * @brief 日志类 @@ -34,7 +36,6 @@ public: */ static XNLogger &instance() { - // 懒汉式单例,C++11 及以上版本的标准保证了局部静态变量的初始化是线程安全的 static XNLogger instance; return instance; } @@ -44,7 +45,7 @@ public: * @param level 日志等级 * @param message 日志消息 */ - void log(LogLevel level, const QString &message); + void log(LogLevel level, const std::string &message); /** * @brief 启用控制台输出 @@ -64,7 +65,7 @@ private: /** * @brief 构造函数 */ - XNLogger(); // 默认构造函数 + XNLogger(); /** * @brief 析构函数 @@ -74,17 +75,17 @@ private: /** * @brief 禁止拷贝构造 */ - XNLogger(const XNLogger &) = delete; // 禁止拷贝构造 + XNLogger(const XNLogger &) = delete; /** * @brief 禁止赋值 */ - XNLogger &operator=(const XNLogger &) = delete; // 禁止赋值 + XNLogger &operator=(const XNLogger &) = delete; /** * @brief 日志文件路径 */ - QString logFilePath; + std::string logFilePath; /** * @brief 控制台输出控制 @@ -99,44 +100,50 @@ private: /** * @brief 日志文件 */ - QFile logFile; + std::ofstream logFile; /** * @brief 互斥锁 */ - QMutex mutex; + std::mutex mutex; /** * @brief 日志等级转换为字符串 * @param level 日志等级 * @return 日志等级字符串 */ - QString logLevelToString(LogLevel level) const; + std::string logLevelToString(LogLevel level) const; + + /** + * @brief 获取当前时间字符串 + * @return 格式化的时间字符串 + */ + std::string getCurrentTimeString() const; /** * @brief 控制台输出字体恢复颜色常量 */ - const QString COLOR_RESET = "\033[0m"; + const std::string COLOR_RESET = "\033[0m"; /** * @brief 调试颜色常量 */ - const QString COLOR_DEBUG = "\033[34m"; // 蓝色 + const std::string COLOR_DEBUG = "\033[34m"; // 蓝色 /** * @brief 信息颜色常量 */ - const QString COLOR_INFO = "\033[32m"; // 绿色 + const std::string COLOR_INFO = "\033[32m"; // 绿色 /** * @brief 警告颜色常量 */ - const QString COLOR_WARNING = "\033[33m"; // 黄色 + const std::string COLOR_WARNING = "\033[33m"; // 黄色 /** * @brief 错误颜色常量 */ - const QString COLOR_ERROR = "\033[31m"; // 红色 + const std::string COLOR_ERROR = "\033[31m"; // 红色 }; /** @@ -154,9 +161,9 @@ public: */ template inline static typename std::enable_if<(sizeof...(Args) > 0), void>::type - log(XNLogger::LogLevel level, const QString &message, Args... args) + log(XNLogger::LogLevel level, const std::string &message, Args... args) { - QString formattedMessage = formatMessage(message, args...); + std::string formattedMessage = formatMessage(message, args...); XNLogger::instance().log(level, formattedMessage); } @@ -165,7 +172,7 @@ public: * @param level 日志等级 * @param message 日志消息 */ - inline static void log(XNLogger::LogLevel level, const QString &message) + inline static void log(XNLogger::LogLevel level, const std::string &message) { XNLogger::instance().log(level, message); } @@ -173,27 +180,44 @@ public: private: // 辅助函数,用于格式化消息 template - static QString convertToString(const T &arg) + static std::string convertToString(const T &arg) { if constexpr (std::is_arithmetic::value) { - return QString::number(arg); // 处理数值类型 + return std::to_string(arg); // 处理数值类型 } else { - return arg; + return std::string(arg); } } // 递归变参函数,用于处理多个参数 template - static QString formatMessage(const QString &message, T arg, Args... args) + static std::string formatMessage(const std::string &message, T arg, Args... args) { - return formatMessage(message.arg(convertToString(arg)), args...); // 递归调用 + // 查找下一个参数占位符 + std::string result = message; + size_t paramIndex = 0; + size_t pos = 0; + + // 找到当前参数对应的占位符 + while (true) { + std::string placeholder = "%" + std::to_string(paramIndex + 1); + pos = result.find(placeholder); + if (pos != std::string::npos) { + // 替换占位符,使用placeholder的长度 + result.replace(pos, placeholder.length(), convertToString(arg)); + break; + } + paramIndex++; + if (paramIndex > 100) { // 防止无限循环 + return result; + } + } + + return formatMessage(result, args...); } // 基础情况 - static QString formatMessage(const QString &message) - { - return message; // 处理没有参数的情况 - } + static std::string formatMessage(const std::string &message) { return message; } }; /** diff --git a/Release/include/XNCore/XNModelManager.h b/Release/include/XNCore/XNModelManager.h index bcbd0f4..4c030b6 100644 --- a/Release/include/XNCore/XNModelManager.h +++ b/Release/include/XNCore/XNModelManager.h @@ -12,7 +12,9 @@ #include "XNBaseFrameObject.h" class XNModelObject; -class XNModelManagerPrivate; +XNCLASS_PTR_DECLARE(XNModelObject) + +struct XNModelManagerPrivate; /** * @brief 模型管理器类 @@ -20,18 +22,14 @@ class XNModelManagerPrivate; */ class XNModelManager : public XNBaseFrameObject { - /** - * @brief 使用禁止复制类宏定义自身禁止复制 - */ - Q_OBJECT - Q_DECLARE_PRIVATE(XNModelManager) - Q_DISABLE_COPY(XNModelManager) + XN_METATYPE(XNModelManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNModelManager) public: /** * @brief 模型管理器类默认构造函数 */ - explicit XNModelManager(QObject *parent = nullptr); + XNModelManager(); /** * @brief 模型管理器类默认析构函数 @@ -44,20 +42,20 @@ protected: * @param p:私有结构体指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNModelManager(XNModelManagerPrivate &dd, QObject *parent = nullptr); + XNModelManager(PrivateType *p); -public slots: +public: /** * @brief 系统开始运行前的最后准备工作 * @details 系统运行前模型管理器做最后处理的接口 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 初始化模型管理器 * @details 模型管理器的初始化接口 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 加载模型 @@ -65,31 +63,23 @@ public slots: * @param className: QString类型,模型类名 * @details 加载模型 */ - void OnLoadModel(const QString &modelPath, const QString &className); + void LoadModel(const std::string &modelPath, const std::string &className, uint32_t initialType, + uint32_t threadID); - /** - * @brief 设置仿真系统运行基频 - * @param dBaseFreq: double类型,频率值,单位Hz - * @details 仿真系统所有线程以此基频的 1 或 1/2 或 1/4 或 1/8 或 1/16 或 1/32 倍运行 - */ - void OnSetBaseFreq(const double &dBaseFreq); - -public: /** * @brief 注册模型信息 * @return UINT32: 模型的全局唯一ID * @details 模型通过此接口注册自身,并获取自身全局唯一ID */ - quint32 RegisterModel(); + uint32_t RegisterModel(); /** * @brief 获取模型指针 * @param modelID: UINT32类型,模型全局唯一ID * @return XNModelObjectPtr: 模型基类指针 */ - XNModelObject *GetModel(quint32 modelID); + XNModelObjectPtr GetModel(uint32_t modelID); -public slots: /** * @brief 注册模型函数 * @param ModelID: UINT32类型,模型全局唯一ID @@ -98,22 +88,6 @@ public slots: * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) * @param RunPriorty: UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 */ - void OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); - -signals: - /** - * @brief 注册函数信号 - * @param id: UINT32类型,模型全局唯一ID - * @param fun: 函数指针 - * @param freqGroup: UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 - * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) - * @param RunPriorty: UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 - */ - void RegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); - - void InitializeSuccess(); - - void PrepareForExecuteSuccess(); + void RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, uint32_t freqGroup, + uint32_t RunPos, uint32_t RunPriorty); }; \ No newline at end of file diff --git a/Release/include/XNCore/XNModelManager_p.h b/Release/include/XNCore/XNModelManager_p.h index b7f04d6..ea7b447 100644 --- a/Release/include/XNCore/XNModelManager_p.h +++ b/Release/include/XNCore/XNModelManager_p.h @@ -1,25 +1,17 @@ #pragma once #include "XNBaseFrameObject_p.h" -#include -#include - -class XNModelManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNModelManager) - - explicit XNModelManagerPrivate(XNModelManager *q) : XNBaseFrameObjectPrivate(q) {} +struct XNModelManagerPrivate : public XNBaseFrameObjectPrivate { + XNFrameworkPtr framework; /** * @brief 模型ID库 * @details 所有模型已用ID的存储库 */ - QVector ModelIDAssigned; - + std::vector ModelIDAssigned; /** - * @brief 仿真系统运行基频 - * @details 仿真系统所有线程以此基频的 1 或 1/2 或 1/4 或 1/8 或 1/16 或 1/32 倍运行 + * @brief 模型ID与模型指针的映射表 + * @details 所有模型ID与模型指针的映射表 */ - double dBaseFreq; + std::map ModelMap; }; diff --git a/Release/include/XNCore/XNModelObject.h b/Release/include/XNCore/XNModelObject.h index 9d988eb..eb1a203 100644 --- a/Release/include/XNCore/XNModelObject.h +++ b/Release/include/XNCore/XNModelObject.h @@ -12,7 +12,7 @@ #include "XNObject.h" #include "XNEventManager.h" -class XNModelObjectPrivate; +struct XNModelObjectPrivate; /** * @brief 模型基类 @@ -20,22 +20,14 @@ class XNModelObjectPrivate; */ class XNModelObject : public XNObject { - Q_OBJECT - Q_DISABLE_COPY(XNModelObject) - Q_DECLARE_PRIVATE(XNModelObject) - - Q_PROPERTY(QString description READ GetDescription WRITE SetDescription) - Q_PROPERTY(QString author READ GetAuthor WRITE SetAuthor) - Q_PROPERTY(QString xmlPath READ GetXmlPath WRITE SetXmlPath) - Q_PROPERTY(QDateTime createTime READ GetCreateTime WRITE SetCreateTime) - Q_PROPERTY(QDateTime changeTime READ GetChangeTime WRITE SetChangeTime) - Q_PROPERTY(QString version READ GetVersion WRITE SetVersion) + XN_METATYPE(XNModelObject, XNObject) + XN_DECLARE_PRIVATE(XNModelObject) public: /** * @brief 模型基类默认构造函数 */ - XNModelObject(QObject *parent = nullptr); + XNModelObject(); /** * @brief 模型基类默认析构函数 @@ -45,89 +37,89 @@ public: protected: /** * @brief 模型基类带参构造函数 - * @param dd:XNModelObjectPrivate类型,私有结构体指针 - * @param parent:QObject类型,父对象指针 + * @param p:XNModelObjectPrivate类型,私有结构体指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNModelObject(XNModelObjectPrivate &dd, QObject *parent = nullptr); + XNModelObject(PrivateType *p); + +public: + void SetFramework(XNFrameworkPtr framework); + +protected: + XNFrameworkPtr GetFramework() const; public: /** * @brief 获取模型描述 * @return const QString&:模型描述 */ - const QString &GetDescription(); + const std::string &GetDescription(); /** * @brief 设置模型描述 * @param sDescription:QString类型,模型描述 */ - void SetDescription(const QString &sDescription); + void SetDescription(const std::string &sDescription); /** * @brief 获取作者 * @return const QString&: 作者 */ - const QString &GetAuthor(); + const std::string &GetAuthor(); /** * @brief 设置作者 * @param sAuthor: QString类型,作者 */ - void SetAuthor(const QString &sAuthor); + void SetAuthor(const std::string &sAuthor); /** * @brief 获取模型配置文件路径 * @return const QString&: 模型配置文件路径 */ - const QString &GetXmlPath(); + const std::string &GetXmlPath(); /** * @brief 设置模型配置文件路径 * @param sXmlPath:QString类型,模型配置文件路径 */ - void SetXmlPath(const QString &sXmlPath); + void SetXmlPath(const std::string &sXmlPath); /** * @brief 获取模型创建时间 - * @return const QDateTime&:模型创建时间 + * @return const XNTimePoint&:模型创建时间 */ - const QDateTime &GetCreateTime(); + const XNTimePoint &GetCreateTime(); /** * @brief 设置模型创建时间 - * @param cTime: QDateTime类型,模型创建时间 + * @param cTime: XNTimePoint类型,模型创建时间 */ - void SetCreateTime(const QDateTime &cTime); + void SetCreateTime(const XNTimePoint &cTime); /** * @brief 获取模型修改时间 - * @return const QDateTime&:模型修改时间 + * @return const XNTimePoint&:模型修改时间 */ - const QDateTime &GetChangeTime(); + const XNTimePoint &GetChangeTime(); /** * @brief 设置模型修改时间 - * @param cTime: QDateTime类型,模型修改时间 + * @param cTime: XNTimePoint类型,模型修改时间 */ - void SetChangeTime(const QDateTime &cTime); + void SetChangeTime(const XNTimePoint &cTime); /** * @brief 获取模型版本号 * @return const XNString&: 模型版本号 */ - const QString &GetVersion(); - /** - * @brief 设置模型版本号 - * @param sVersion: QString类型,模型版本号 - */ - void SetVersion(const QString &sVersion); + const std::string &GetVersion(); /** - * @brief 设置仿真系统运行基频 - * @param dBaseFreq: double类型,频率值,单位Hz + * @brief 设置模型版本号 + * @param sVersion: std::string类型,模型版本号 */ - void SetBaseFreq(const double &dBaseFreq); + void SetVersion(const std::string &sVersion); /** * @brief 单步执行函数 @@ -142,8 +134,8 @@ public: * @param async: 是否异步处理 * @return: 返回处理器ID,失败返回-1 */ - int RegisterEventHandler(const QString &eventName, - std::function callback, bool async = false, + int RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + bool async = false, XNEvent::Priority priority = XNEvent::Priority::Normal); /** @@ -152,7 +144,7 @@ public: * @param eventData: 事件携带的数据 * @param forceAsync: 强制异步处理 */ - void TriggerEvent(const QString &eventName, const QVariant &eventData = QVariant(), + void TriggerEvent(const std::string &eventName, const std::any &eventData = std::any(), bool forceAsync = false, XNEvent::Priority priority = XNEvent::Priority::Normal); @@ -162,8 +154,7 @@ public: * @param callback: 事件处理回调函数 * @return: 返回处理器ID,失败返回-1 */ - int RegisterRTEventHandler(const QString &eventName, - std::function callback) + int RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback) { return RegisterEventHandler(eventName, callback, true, XNEvent::Priority::RealTime); } @@ -173,37 +164,23 @@ public: * @param eventName: 要触发的事件名称 * @param eventData: 事件携带的数据 */ - void TriggerRTEvent(const QString &eventName, const QVariant &eventData = QVariant()) + void TriggerRTEvent(const std::string &eventName, const std::any &eventData = std::any()) { TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); } -signals: - /** - * @brief 注册周期性执行的函数 - * @param id: quint32类型,模型ID - * @param fun: QFunctionPointer类型,需要提交的函数的包装 - * @param freqGroup:UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 - * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) - * @param RunPriorty:INT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 - * @details 向线程管理器添加要周期性执行的函数 - */ - void RegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); - -public slots: /** * @brief 初始化函数 * @details * 模型的初始化函数接口,子类继承时要调用父类初始化接口,或在此函数中使用AddMyFunction方法注册需要被线程调用的函数 */ - virtual void OnInitialize(); + virtual void Initialize(uint32_t initialType, uint32_t threadID); /** * @brief 仿真系统运行前做最后处理 * @details 系统运行前模型做最后处理的接口 */ - virtual void OnPrepareForExecute(); + virtual void PrepareForExecute(); public: virtual void RegisterDDSParticipant(); @@ -218,11 +195,11 @@ public: { \ XNModelObject::RegisterDDSParticipant(); \ Q_D(class); \ - XNModelManager *modelManager = qobject_cast(parent()); \ - if (modelManager == nullptr) \ + auto framework = GetFramework(); \ + if (!framework) \ return; \ - XNDDSManager *ddsManager = modelManager->parent()->findChild(); \ - if (ddsManager == nullptr) \ + XNDDSManagerPtr ddsManager = framework->GetDDSManager(); \ + if (!ddsManager) \ return; \ quint32 MyID = getUniqueId(); @@ -233,4 +210,11 @@ public: ddsManager->RegisterSubscriber( \ #topic, MyID, std::bind(fun, this, std::placeholders::_1)); -#define XN_REGISTER_PARTICIPANT_END(class) } \ No newline at end of file +#define XN_REGISTER_PARTICIPANT_END(class) } + +#define XN_MODEL_INITIALIZE(ClassName) \ + extern "C" XNModelObjectPtr Initial##ClassName() \ + { \ + ClassNamePtr obj = std::make_shared(); \ + return obj; \ + } diff --git a/Release/include/XNCore/XNModelObject_p.h b/Release/include/XNCore/XNModelObject_p.h index e562d83..6374413 100644 --- a/Release/include/XNCore/XNModelObject_p.h +++ b/Release/include/XNCore/XNModelObject_p.h @@ -10,62 +10,49 @@ */ #pragma once #include "XNObject_p.h" -#include -#include -#include -#include /** * @brief 模型基类私有结构体 */ -class XNModelObjectPrivate : public XNObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNModelObject) - - /** - * @brief 构造函数 - * @param q 模型基类指针 - */ - explicit XNModelObjectPrivate(XNModelObject *q) : XNObjectPrivate(q) {} - +struct XNModelObjectPrivate : public XNObjectPrivate { + XNFrameworkPtr _framework; /** * @brief 模型描述 */ - QString _sDescription; + std::string _sDescription; /** * @brief 模型作者 */ - QString _sAuthor; + std::string _sAuthor; /** * @brief 模型配置文件路径 */ - QString _sXmlPath; + std::string _sXmlPath; /** * @brief 数据包模型动态库路径 */ - QString _sLibPath; + std::string _sLibPath; /** * @brief 模型创建时间 */ - QDateTime _cCreatTime; + XNTimePoint _cCreatTime; /** * @brief 模型修改时间 */ - QDateTime _cChangeTime; + XNTimePoint _cChangeTime; /** * @brief 模型版本号 */ - QString _sVersion; + std::string _sVersion; /** * @brief 数据包模型动态库句柄 */ - QLibrary *_dynamicLib = nullptr; + void *_dynamicLib = nullptr; /** * @brief 发布者信息 */ - QHash _dataWriters; + std::unordered_map _dataWriters; /** * @brief 模型运行时间 @@ -75,25 +62,30 @@ public: /** * @brief 模型运行次数 */ - quint64 _runCnt; + uint64_t _runCnt; /** * @brief 模型运行频率 */ - quint32 _runFreq; + uint32_t _runFreq; /** * @brief 模型运行节点 */ - quint32 _runNode; + uint32_t _runNode; /** * @brief 模型运行优先级 */ - quint32 _runPriority; + uint32_t _runPriority; /** * @brief 模型设置频率 */ double _setFreq; + + /** + * @brief 模型线程ID + */ + uint32_t _threadID; }; diff --git a/Release/include/XNCore/XNObject.h b/Release/include/XNCore/XNObject.h index d34afe8..5c29f1d 100644 --- a/Release/include/XNCore/XNObject.h +++ b/Release/include/XNCore/XNObject.h @@ -10,75 +10,83 @@ */ #pragma once -#include -#include -#include - #include "XNCore_global.h" #include "XNLogger.h" -class XNObjectPrivate; +struct XNObjectPrivate; /** * @brief 基础对象类 */ -class XNCORE_EXPORT XNObject : public QObject +class XNCORE_EXPORT XNObject : public std::enable_shared_from_this { + XN_METATYPE_P(XNObject) + XN_NOCOPYABLE(XNObject) +protected: + using PrivateType = XNObjectPrivate; /** - * @brief 宏定义,用于支持Qt的元对象系统 + * @brief 私有数据成员 */ - Q_OBJECT - - /** - * @brief 宏定义,用于禁用拷贝构造函数 - */ - Q_DISABLE_COPY(XNObject) - - /** - * @brief 宏定义,用于声明私有数据成员 - */ - Q_DECLARE_PRIVATE(XNObject) - - /** - * @brief 宏定义,用于声明属性uniqueId - */ - Q_PROPERTY(quint32 UniqueId READ getUniqueId WRITE setUniqueId) + PrivateType *_Private_Ptr; public: /** * @brief 构造函数 - * @param parent 父对象 */ - explicit XNObject(QObject *parent = nullptr); + XNObject(); /** * @brief 析构函数 */ virtual ~XNObject(); +protected: + /** + * @brief 构造函数 + * @param p 私有数据成员 + */ + XNObject(PrivateType *p); + +public: /** * @brief 获取唯一ID * @return 唯一ID */ - quint32 getUniqueId(); + uint32_t GetUniqueId(); /** * @brief 设置唯一ID * @param uniqueId 唯一ID */ - void setUniqueId(const quint32 &uniqueId); + void SetUniqueId(const uint32_t &uniqueId); -protected: /** - * @brief 构造函数 - * @param dd 私有数据成员 - * @param parent 父对象 + * @brief 获取对象名称 + * @return 对象名称 */ - XNObject(XNObjectPrivate &dd, QObject *parent = nullptr); + const std::string &GetObjectName(); -protected: /** - * @brief 私有数据成员 + * @brief 设置对象名称 + * @param name 对象名称 */ - XNObjectPrivate *d_ptr; + void SetObjectName(const std::string &name); }; + +class XNFramework; +class XNDDSManager; +class XNEventManager; +class XNModelManager; +class XNScenarioManager; +class XNServiceManager; +class XNThreadManager; +class XNTimeManager; + +XNCLASS_PTR_DECLARE(XNFramework) +XNCLASS_PTR_DECLARE(XNDDSManager) +XNCLASS_PTR_DECLARE(XNEventManager) +XNCLASS_PTR_DECLARE(XNModelManager) +XNCLASS_PTR_DECLARE(XNScenarioManager) +XNCLASS_PTR_DECLARE(XNServiceManager) +XNCLASS_PTR_DECLARE(XNThreadManager) +XNCLASS_PTR_DECLARE(XNTimeManager) \ No newline at end of file diff --git a/Release/include/XNCore/XNObject_p.h b/Release/include/XNCore/XNObject_p.h index 1837b73..ee9ae44 100644 --- a/Release/include/XNCore/XNObject_p.h +++ b/Release/include/XNCore/XNObject_p.h @@ -15,28 +15,20 @@ /** * @brief 基础对象类的私有数据成员 */ -class XNObjectPrivate -{ -public: - /** - * @brief 宏定义,用于声明公有数据成员 - */ - Q_DECLARE_PUBLIC(XNObject) - - /** - * @brief 构造函数 - * @param q 基础对象类指针 - */ - explicit XNObjectPrivate(XNObject *q) : q_ptr(q) {} - +struct XNObjectPrivate { + virtual ~XNObjectPrivate(); /** * @brief 基础对象类指针 */ - XNObject *q_ptr; + XNObject *_Public_Ptr; -private: /** * @brief 唯一ID */ - quint32 uUniqueID; + uint32_t uUniqueID; + + /** + * @brief 对象名称 + */ + std::string sObjectName; }; diff --git a/Release/include/XNCore/XNScenarioManager.h b/Release/include/XNCore/XNScenarioManager.h index 1115f80..9870c3c 100644 --- a/Release/include/XNCore/XNScenarioManager.h +++ b/Release/include/XNCore/XNScenarioManager.h @@ -11,7 +11,7 @@ #pragma once #include "XNBaseFrameObject.h" -class XNScenarioManagerPrivate; +struct XNScenarioManagerPrivate; /** * @brief 运行环境描述管理器类 @@ -19,14 +19,13 @@ class XNScenarioManagerPrivate; */ class XNScenarioManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNScenarioManager) - Q_DISABLE_COPY(XNScenarioManager) + XN_METATYPE(XNScenarioManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNScenarioManager) public: /** * @brief 运行环境描述管理器类默认构造函数 */ - explicit XNScenarioManager(QObject *parent = nullptr); + XNScenarioManager(); /** * @brief 运行环境描述管理器类析构函数 @@ -39,110 +38,39 @@ protected: * @param p:私有结构体指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNScenarioManager(XNScenarioManagerPrivate &dd, QObject *parent = nullptr); + XNScenarioManager(PrivateType *p); public: /** * @brief 获取运行环境名称 * @return const XNString&: 运行环境名称 */ - const QString &GetSimName(); + const std::string &GetSimName(); /** * @brief 设置运行环境名称 * @param simName: XNString类型,运行环境名称 */ - void SetSimName(QString &simName); + void SetSimName(const std::string &simName); - /** - * @brief 获取运行环境开始时间 - * @return const XNTime&: 运行环境开始时间 - */ - const QDateTime &GetSimStartTime(); - - /** - * @brief 设置运行环境开始时间 - * @param startTime: QDateTime类型,运行环境开始时间 - */ - void SetSimStartTime(QDateTime &startTime); - -signals: - /** - * @brief 信号,用于通知线程管理器添加线程 - */ - void AddThreadPool(QString name, FreqLevel freq, quint32 priority, quint32 CPUAff, - double RunInter); - - /** - * @brief 信号,用于通知模型管理器加载模型 - */ - void LoadModel(const QString &modelPath, const QString &className); - - /** - * @brief 信号,用于通知服务管理器加载服务 - */ - void LoadService(const QString &servicePath, const QString &className); - - /** - * @brief 信号,用于通知框架设置工作路径 - */ - void SetWorkPath(const QString &workPath); - - /** - * @brief 信号,用于通知框架设置模型库路径 - */ - void SetModelPath(const QString &modelPath); - - /** - * @brief 信号,用于通知框架设置服务库路径 - */ - void SetServicePath(const QString &servicePath); - - /** - * @brief 信号,用于通知框架设置CPU亲和性 - */ - void SetCpuAffinity(quint32 cpuAffinity); - - /** - * @brief 设置基础运行频率 - * @param freq: 基础运行频率,单位Hz - */ - void SetBaseFreq(const double &freq); - - /** - * @brief 设置DDS域ID - * @param domainID: DDS域ID - */ - void SetDomainID(quint32 domainID); - - /** - * @brief 解析配置文件成功 - */ - void AnalyzeScenarioXmlSuccess(); - - /** - * @brief 解析配置文件失败 - */ - void AnalyzeScenarioXmlFailed(); - -public slots: +public: /** * @brief 初始化运行环境描述管理器 * @return true: 初始化成功 * @return false: 初始化失败 * @details 运行环境描述管理器的初始化接口函数 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 仿真运行前最后处理 * @note 运行环境描述管理器在系统运行开始前的准备工作 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 运行环境配置文件解析 - * @param XmlPath: QString类型,运行环境配置文件解析路径 + * @param XmlPath: std::string类型,运行环境配置文件解析路径 */ - virtual void AnalysisScenarioXml(const QString &XmlPath); + virtual bool AnalysisScenarioXml(const std::string &XmlPath); }; diff --git a/Release/include/XNCore/XNScenarioManager_p.h b/Release/include/XNCore/XNScenarioManager_p.h index e41c85b..c3453f3 100644 --- a/Release/include/XNCore/XNScenarioManager_p.h +++ b/Release/include/XNCore/XNScenarioManager_p.h @@ -14,19 +14,9 @@ /** * @brief 运行环境描述管理器类私有结构体 */ -class XNScenarioManagerPrivate : public XNBaseFrameObjectPrivate -{ - -public: - Q_DECLARE_PUBLIC(XNScenarioManager) - explicit XNScenarioManagerPrivate(XNScenarioManager *q) : XNBaseFrameObjectPrivate(q) {} +struct XNScenarioManagerPrivate : public XNBaseFrameObjectPrivate { /** * @brief 运行环境名称 */ - QString _ScenarioName; - - /** - * @brief 运行环境开始时间 - */ - QDateTime _SimStartTime; + std::string _ScenarioName; }; diff --git a/Release/include/XNCore/XNServiceManager.h b/Release/include/XNCore/XNServiceManager.h index 74573a3..eb0a5bb 100644 --- a/Release/include/XNCore/XNServiceManager.h +++ b/Release/include/XNCore/XNServiceManager.h @@ -3,26 +3,35 @@ // 添加前向声明 class XNServiceObject; -class XNServiceManagerPrivate; +XNCLASS_PTR_DECLARE(XNServiceObject) + +struct XNServiceManagerPrivate; class XNServiceManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNServiceManager) - Q_DISABLE_COPY(XNServiceManager) + XN_METATYPE(XNServiceManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNServiceManager) public: - explicit XNServiceManager(QObject *parent = nullptr); + /** + * @brief 服务管理器类默认构造函数 + */ + XNServiceManager(); + + /** + * @brief 服务管理器类析构函数 + */ virtual ~XNServiceManager(); protected: - XNServiceManager(XNServiceManagerPrivate &dd, QObject *parent = nullptr); - -public slots: - virtual void OnInitialize() override; - virtual void OnPrepareForExecute() override; - void OnLoadService(const QString &servicePath, const QString &serviceName); + XNServiceManager(PrivateType *p); public: - XNServiceObject *GetService(quint32 serviceID); - quint32 RegisterService(); + virtual bool Initialize() override; + virtual bool PrepareForExecute() override; + void LoadService(const std::string &servicePath, const std::string &serviceName, + uint32_t initialType); + +public: + XNServiceObjectPtr GetService(uint32_t serviceID); + uint32_t RegisterService(); }; diff --git a/Release/include/XNCore/XNServiceManager_p.h b/Release/include/XNCore/XNServiceManager_p.h index 79d9380..864da21 100644 --- a/Release/include/XNCore/XNServiceManager_p.h +++ b/Release/include/XNCore/XNServiceManager_p.h @@ -1,16 +1,16 @@ #pragma once #include "XNBaseFrameObject_p.h" -class XNServiceManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNServiceManager) - - explicit XNServiceManagerPrivate(XNServiceManager *q) : XNBaseFrameObjectPrivate(q) {} - +struct XNServiceManagerPrivate : public XNBaseFrameObjectPrivate { /** * @brief 服务ID库 * @details 所有服务已用ID的存储库 */ - QVector ServiceIDAssigned; + std::vector ServiceIDAssigned; + + /** + * @brief 服务列表 + * @details 所有服务的存储库 + */ + std::map ServiceList; }; \ No newline at end of file diff --git a/Release/include/XNCore/XNServiceObject.h b/Release/include/XNCore/XNServiceObject.h index 49f7802..8d32457 100644 --- a/Release/include/XNCore/XNServiceObject.h +++ b/Release/include/XNCore/XNServiceObject.h @@ -3,68 +3,59 @@ #include "XNObject.h" #include "XNServiceManager.h" #include "XNEventManager.h" - -class XNServiceObjectPrivate; +struct XNServiceObjectPrivate; class XNServiceObject : public XNObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNServiceObject) - Q_DISABLE_COPY(XNServiceObject) - - Q_PROPERTY(QString description READ GetDescription WRITE SetDescription) - Q_PROPERTY(QString author READ GetAuthor WRITE SetAuthor) - Q_PROPERTY(QString xmlPath READ GetXmlPath WRITE SetXmlPath) - Q_PROPERTY(QDateTime createTime READ GetCreateTime WRITE SetCreateTime) - Q_PROPERTY(QDateTime changeTime READ GetChangeTime WRITE SetChangeTime) - Q_PROPERTY(QString version READ GetVersion WRITE SetVersion) - + XN_METATYPE(XNServiceObject, XNObject) + XN_DECLARE_PRIVATE(XNServiceObject) public: - explicit XNServiceObject(QObject *parent = nullptr); + XNServiceObject(); virtual ~XNServiceObject(); protected: - explicit XNServiceObject(XNServiceObjectPrivate &dd, QObject *parent = nullptr); + XNServiceObject(PrivateType *p); public: - const QString &GetVersion(); - const QString &GetDescription(); - const QString &GetAuthor(); - const QString &GetXmlPath(); - const QDateTime &GetCreateTime(); - const QDateTime &GetChangeTime(); + const std::string &GetVersion(); + const std::string &GetDescription(); + const std::string &GetAuthor(); + const std::string &GetXmlPath(); + const XNTimePoint &GetCreateTime(); + const XNTimePoint &GetChangeTime(); - void SetVersion(const QString &version); - void SetDescription(const QString &description); - void SetAuthor(const QString &author); - void SetXmlPath(const QString &xmlPath); - void SetCreateTime(const QDateTime &createTime); - void SetChangeTime(const QDateTime &changeTime); + void SetVersion(const std::string &version); + void SetDescription(const std::string &description); + void SetAuthor(const std::string &author); + void SetXmlPath(const std::string &xmlPath); + void SetCreateTime(const XNTimePoint &createTime); + void SetChangeTime(const XNTimePoint &changeTime); - int RegisterEventHandler(const QString &eventName, - std::function callback, bool async = false, + int RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + bool async = false, XNEvent::Priority priority = XNEvent::Priority::Normal); - void TriggerEvent(const QString &eventName, const QVariant &eventData = QVariant(), + void TriggerEvent(const std::string &eventName, const std::any &eventData = std::any(), bool forceAsync = false, XNEvent::Priority priority = XNEvent::Priority::Normal); - int RegisterRTEventHandler(const QString &eventName, - std::function callback); + int RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback); - void TriggerRTEvent(const QString &eventName, const QVariant &eventData = QVariant()); + void TriggerRTEvent(const std::string &eventName, const std::any &eventData = std::any()); -public slots: - virtual void OnInitialize(); - virtual void OnPrepareForExecute(); + virtual void Initialize(uint32_t initialType); + virtual void PrepareForExecute(); -public: virtual void RegisterDDSParticipant(); -private: - XNEventManager *GetEventManager() const; + void SetFramework(XNFrameworkPtr framework); + +protected: + XNFrameworkPtr GetFramework() const; }; +XNCLASS_PTR_DECLARE(XNServiceObject) + #define XN_DECLARE_DDS_SERVICE() \ public: \ virtual void RegisterDDSParticipant() override; @@ -74,11 +65,11 @@ public: { \ XNServiceObject::RegisterDDSParticipant(); \ Q_D(class); \ - XNServiceManager *serviceManager = qobject_cast(parent()); \ - if (serviceManager == nullptr) \ + auto framework = GetFramework(); \ + if (!framework) \ return; \ - XNDDSManager *ddsManager = serviceManager->parent()->findChild(); \ - if (ddsManager == nullptr) \ + XNDDSManagerPtr ddsManager = framework->GetDDSManager(); \ + if (!ddsManager) \ return; \ quint32 MyID = getUniqueId(); @@ -90,3 +81,10 @@ public: #topic, MyID, std::bind(fun, this, std::placeholders::_1)); #define XN_REGISTER_SERVICE_END_SERVICE(class) } + +#define XN_SERVICE_INITIALIZE(ClassName) \ + extern "C" XNServiceObjectPtr Initial##ClassName() \ + { \ + ClassNamePtr obj = std::make_shared(); \ + return obj; \ + } diff --git a/Release/include/XNCore/XNServiceObject_p.h b/Release/include/XNCore/XNServiceObject_p.h index 574b159..32bc8ba 100644 --- a/Release/include/XNCore/XNServiceObject_p.h +++ b/Release/include/XNCore/XNServiceObject_p.h @@ -1,21 +1,13 @@ #pragma once #include "XNObject_p.h" -#include -#include -#include "XNEventManager.h" -class XNServiceObjectPrivate : public XNObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNServiceObject) - explicit XNServiceObjectPrivate(XNServiceObject *q) : XNObjectPrivate(q) {} - QString _sDescription; - QString _sAuthor; - QString _sXmlPath; - QDateTime _cCreateTime; - QDateTime _cChangeTime; - QString _sVersion; - QHash _dataWriters; - - XNEventManager *pEventManager; +struct XNServiceObjectPrivate : public XNObjectPrivate { + std::string _sDescription; + std::string _sAuthor; + std::string _sXmlPath; + XNTimePoint _cCreateTime; + XNTimePoint _cChangeTime; + std::string _sVersion; + std::unordered_map _dataWriters; + XNFrameworkPtr pFramework; }; diff --git a/Release/include/XNCore/XNThread.h b/Release/include/XNCore/XNThread.h index 936140e..87e1bd0 100644 --- a/Release/include/XNCore/XNThread.h +++ b/Release/include/XNCore/XNThread.h @@ -9,36 +9,43 @@ * */ #pragma once -#include -#include -#include "XNCore_global.h" +#include "XNObject.h" -class XNThreadPrivate; +struct XNThreadPrivate; /** * @brief 调度线程类 * @details 调度所有模型提交的周期性执行函数 */ -class XNCORE_EXPORT XNThread : public QObject +class XNCORE_EXPORT XNThread : public XNObject { - Q_OBJECT - Q_DISABLE_COPY(XNThread) - Q_DECLARE_PRIVATE(XNThread) + XN_METATYPE(XNThread, XNObject) + XN_DECLARE_PRIVATE(XNThread) public: - explicit XNThread(QObject *parent = nullptr); - XNThread(QObject *parent = nullptr, QString name = "", FreqLevel freq = FreqLevel::BaseFreq, - quint32 priority = 99, quint32 CPUAff = 0, double RunInter = BASE_RUN_INTER); + XNThread() = delete; -protected: - XNThreadPrivate *d_ptr; - -public: /** * @brief 默认析构函数 */ virtual ~XNThread(); + explicit XNThread(std::string name = "", double freq = BASE_RUN_FREQ, uint32_t priority = 99, + uint32_t CPUAff = 0); + +public: + /** + * @brief 获取框架对象 + * @return 框架对象 + */ + XNFrameworkPtr GetFramework(); + + /** + * @brief 设置框架对象 + * @param framework 框架对象 + */ + void SetFramework(XNFrameworkPtr framework); + /** * @brief 线程初始化 * @return true: 初始化成功 @@ -46,26 +53,19 @@ public: */ bool Initialize(); -public slots: /** * @brief 仿真控制 * @param objectId: 对象ID * @param cmd: 仿真控制命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); + void SimControl(uint32_t objectId, SimControlCmd cmd); /** * @brief 设置线程运行的开始时间 * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 * @details 通过设置统一的开始时间,使个线程能同步执行 */ - void OnSetStartTime(const timespec &simTime); - - /** - * @brief 设置线程运行间隔 - * @param dRunInter: double类型,线程运行间隔,单位纳秒 - */ - void SetRunInter(const double &dRunInter); + void SetStartTime(const timespec &simTime); /** * @brief 加入线程 @@ -78,19 +78,73 @@ public slots: */ void Detach(); -public: /** * @brief 获取线程ID * @return const quint32&: 线程ID */ - const quint32 &GetThreadID(); + const uint32_t &GetThreadID(); /** * @brief 设置线程ID * @param threadID: 线程ID */ - void SetThreadID(const quint32 &threadID); + void SetThreadID(const uint32_t &threadID); + /** + * @brief 获取运行状态 + * @return RunStatus: 运行状态枚举 + */ + RunStatus GetRunStatus(); + + /** + * @brief 获取线程运行频率 + * @return const double&:线程运行频率 + */ + const double &GetRunFrequecy(); + + /** + * @brief 设置线程运行频率 + * @param eRunFrequecy: double类型,线程运行频率 + */ + void SetRunFrequecy(const double &dRunFrequecy); + + /** + * @brief 获取线程运行优先级 + * @return const UINT32&:运行优先级,0~99,99最高 + */ + const uint32_t &GetRunPriority(); + + /** + * @brief 设置线程运行优先级 + * @param uRunPriority: UINT32类型,运行优先级,0~99,99最高 + */ + void SetRunPriority(const uint32_t &uRunPriority); + + /** + * @brief 设置线程CPU亲和性掩码 + * @return const UINT32&: CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + */ + const uint32_t &GetCPUAffinity(); + + /** + * @brief 获取线程CPU亲和性掩码 + * @param uCPUAffinity: UINT32类型,CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + */ + void SetCPUAffinity(const uint32_t &uCPUAffinity); + + /** + * @brief 向线程添加周期性函数 + * @param fun:XNCallBack函数包装器类型,需要提交的函数的包装 + * @param freq:FreqLevel类型,提交的函数运行频率组 + * @param pos:UINT32类型,提交的函数运行节点号 + * @param priorty:UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 + * @details 根据运行频率组和节点号向调度线程任务表中添加周期性函数 + */ + void AddFunction(XNCallBack fun, FreqLevel freq, uint32_t pos, uint32_t priorty); + +private: /** * @brief 控制线程开始 * @return true: 线程启动成功 @@ -120,61 +174,6 @@ public: */ void Stop(bool force = false); - /** - * @brief 获取运行状态 - * @return RunStatus: 运行状态枚举 - */ - RunStatus GetRunStatus(); - - /** - * @brief 获取线程运行频率族 - * @return const FreqLevel&:线程运行频率族 - */ - const FreqLevel &GetRunFrequecy(); - - /** - * @brief 设置线程运行频率族 - * @param eRunFrequecy: FreqLevel枚举类,线程运行频率族 - */ - void SetRunFrequecy(const FreqLevel &eRunFrequecy); - - /** - * @brief 获取线程运行优先级 - * @return const UINT32&:运行优先级,0~99,99最高 - */ - const quint32 &GetRunPriority(); - - /** - * @brief 设置线程运行优先级 - * @param uRunPriority: UINT32类型,运行优先级,0~99,99最高 - */ - void SetRunPriority(const quint32 &uRunPriority); - - /** - * @brief 设置线程CPU亲和性掩码 - * @return const UINT32&: CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 - * 例如:0x00000003表示使用0,1号CPU - */ - const quint32 &GetCPUAffinity(); - - /** - * @brief 获取线程CPU亲和性掩码 - * @param uCPUAffinity: UINT32类型,CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 - * 例如:0x00000003表示使用0,1号CPU - */ - void SetCPUAffinity(const quint32 &uCPUAffinity); - - /** - * @brief 向线程添加周期性函数 - * @param fun:XNCallBack函数包装器类型,需要提交的函数的包装 - * @param freq:FreqLevel类型,提交的函数运行频率组 - * @param pos:UINT32类型,提交的函数运行节点号 - * @param priorty:UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 - * @details 根据运行频率组和节点号向调度线程任务表中添加周期性函数 - */ - void AddFunction(XNCallBack fun, FreqLevel freq, quint32 pos, quint32 priorty); - -private: /** * @brief 执行线程CPU亲和性设置 * @return true: 设置线程CPU亲和性成功 @@ -189,8 +188,10 @@ private: */ static void *ThreadFunction(void *args); - /** - * @brief 初始化周期性函数表 - */ - void InitialFunPool(); -}; \ No newline at end of file + // /** + // * @brief 初始化周期性函数表 + // */ + //void InitialFunPool(); +}; + +XNCLASS_PTR_DECLARE(XNThread) \ No newline at end of file diff --git a/Release/include/XNCore/XNThreadManager.h b/Release/include/XNCore/XNThreadManager.h index e5ef942..968a90d 100644 --- a/Release/include/XNCore/XNThreadManager.h +++ b/Release/include/XNCore/XNThreadManager.h @@ -11,7 +11,7 @@ #pragma once #include "XNBaseFrameObject.h" -class XNThreadManagerPrivate; +struct XNThreadManagerPrivate; /** * @brief 线程管理器类 @@ -19,15 +19,14 @@ class XNThreadManagerPrivate; */ class XNThreadManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNThreadManager) - Q_DISABLE_COPY(XNThreadManager) + XN_METATYPE(XNThreadManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNThreadManager) public: /** * @brief 线程管理器类默认构造函数 */ - explicit XNThreadManager(QObject *parent = nullptr); + XNThreadManager(); /** * @brief 线程管理器类析构函数 @@ -41,53 +40,32 @@ protected: * @param parent:QObject类型,父对象指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNThreadManager(XNThreadManagerPrivate &dd, QObject *parent = nullptr); + XNThreadManager(PrivateType *p); -signals: - /** - * @brief 设置仿真开始时间信号 - * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 - * @details 通过设置统一的开始时间,使个线程能同步执行 - */ - void SetStartTime(const timespec &simTime); - - /** - * @brief 设置线程运行间隔信号 - * @param dRunInter: double类型,线程运行间隔,单位纳秒 - */ - void SetRunInter(const double &dRunInter); - - /** - * @brief 仿真控制信号 - * @param objectId: 对象ID - * @param cmd: 仿真控制命令 - */ - void SimControl(quint32 objectId, SimControlCmd cmd); - -public slots: +public: /** * @brief 开始控制 * @details 控制线程管理器开始运行接口 */ - void OnStart(); + void Start(); /** * @brief 停止控制 * @details 控制线程管理器停止运行接口 */ - void OnAbort(); + void Abort(); /** * @brief 暂停控制 * @details 控制线程管理器暂停运行接口 */ - void OnPause(); + void Pause(); /** * @brief 继续控制 * @details 控制线程管理器继续运行接口 */ - void OnContinue(); + void Continue(); /** * @brief 初始化线程管理器 @@ -95,29 +73,21 @@ public slots: * @return false: 初始化失败 * @details 线程管理器的初始化接口函数 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 仿真运行前最后处理 * @note 线程管理器在所有线程开始执行前的准备工作 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 仿真控制 * @param objectId: 对象ID * @param cmd: 仿真控制命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); + void SimControl(uint32_t objectId, SimControlCmd cmd); - /** - * @brief 设置仿真系统运行基频 - * @param dBaseFreq: double类型,频率值,单位Hz - * @details 仿真系统所有线程以此基频的 1 或 1/2 或 1/4 或 1/8 或 1/16 或 1/32 倍运行 - */ - void OnSetBaseFreq(const double &dBaseFreq); - -public: /** * @brief 获取运行状态 * @return RunStatus: 枚举类,线程运行状态 @@ -125,50 +95,29 @@ public: */ RunStatus GetStatus(); - /** - * @brief 获得仿真系统运行基频 - * @return const double&: 频率值,单位Hz - */ - const double &GetBaseFreq(); - - /** - * @brief 获得仿真系统运行基础间隔 - * @return const double&: 运行周期值,单位纳秒 - * @details 模型基础运行间隔由基频计算获得 - */ - const double &GetBaseInter(); - - /** - * @brief 通过运行间隔设置基频 - * @param dBaseInter:double类型,运行周期值,单位纳秒 - * @details 使用运行间隔计算得到基频并设置 - */ - void SetBaseFreqByInter(const double &dBaseInter); - /** * @brief 获取线程数量 * @return quint32: 线程数量 */ - quint32 GetThreadCount(); + uint32_t GetThreadCount(); -public slots: /** * @brief 添加一个线程 * @param name: XNString类型,线程名称 - * @param freq: FreqLevel枚举类型,线程运行频率组 + * @param freq: double类型,线程运行频率,单位Hz * @param priority: UINT32类型,线程运行优先级,99~0,优先级数值越大,优先级越高 * @param CPUAff: UINT32类型,线程的CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 * 例如:0x00000003表示使用0,1号CPU - * @param RunInter: double类型,线程的运行周期,单位纳秒 * @details 按照设置的参数创建线程 */ - virtual void OnAddThreadPool(QString name, FreqLevel freq, quint32 priority, quint32 CPUAff, - double RunInter); + virtual uint32_t AddThreadPool(std::string name, double freq, uint32_t priority, + uint32_t CPUAff); /** * @brief 向线程中添加周期性函数 * @param id: UINT32类型,模型全局唯一ID * @param fun: XNCallBack函数包装器类型,需要提交的函数的包装 + * @param threadID: UINT32类型,线程ID * @param freqGroup: UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) * @param RunPriorty: UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 @@ -176,8 +125,8 @@ public slots: * @return false: 添加失败 * @details 根据运行频率组和节点号向对应的线程中添加周期性函数 */ - void OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); + void RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, uint32_t freqGroup, + uint32_t RunPos, uint32_t RunPriorty); private: /** @@ -187,7 +136,7 @@ private: * @return true:提交的函数频率与节点号符合规则 * @return false:提交的函数频率与节点号不符合规则 */ - bool IsFunParamRight(quint32 ModelID, quint32 freqGroup, quint32 RunPos); + bool IsFunParamRight(uint32_t ModelID, uint32_t freqGroup, uint32_t RunPos); - quint32 AllocateThreadID(); + uint32_t AllocateThreadID(); }; \ No newline at end of file diff --git a/Release/include/XNCore/XNThreadManager_p.h b/Release/include/XNCore/XNThreadManager_p.h index a3f4686..ecc2bd3 100644 --- a/Release/include/XNCore/XNThreadManager_p.h +++ b/Release/include/XNCore/XNThreadManager_p.h @@ -20,55 +20,46 @@ struct funInfo { * @brief 周期性函数包装器 */ XNCallBack fun; + /** + * @brief 线程ID + */ + uint32_t threadID; /** * @brief 运行频率组 */ - quint32 freqGroup; + uint32_t freqGroup; /** * @brief 运行节点 */ - quint32 RunPos; + uint32_t RunPos; /** * @brief 运行优先级 */ - quint32 RunPriority; + uint32_t RunPriority; }; /** * @brief 声明周期性函数存储结构体的智能指针 */ -using funInfoPtr = QSharedPointer; +using funInfoPtr = std::shared_ptr; /** * @brief 线程管理器类私有结构体 */ -class XNThreadManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - XNThreadManagerPrivate(XNThreadManager *q) : XNBaseFrameObjectPrivate(q) {} - Q_DECLARE_PUBLIC(XNThreadManager) -private: +struct XNThreadManagerPrivate : public XNBaseFrameObjectPrivate { /** * @brief 所有线程运行状态 */ RunStatus _eRunStatus; + /** + * @brief 线程列表 + */ + std::map threadList; /** * @brief 周期性函数存储列表 */ - QMap > funList; - /** - * @brief 基础运行频率 - */ - double dRunFreq = BASE_RUN_FREQ; - /** - * @brief 基础运行间隔 - */ - double dRunInter = BASE_RUN_INTER; + std::map > funList; /** * @brief 线程ID */ - QSet threadIDMap; - /** - * @brief 线程数量 - */ - quint32 threadCount = 0; + std::set threadIDMap; }; diff --git a/Release/include/XNCore/XNThread_p.h b/Release/include/XNCore/XNThread_p.h new file mode 100644 index 0000000..654eefe --- /dev/null +++ b/Release/include/XNCore/XNThread_p.h @@ -0,0 +1,76 @@ +#pragma once +#include "XNObject_p.h" +/** + * @brief 线程类私有结构体 + */ +struct XNThreadPrivate : public XNObjectPrivate { + /** + * @brief 框架对象 + */ + XNFrameworkPtr _framework; + /** + * @brief 线程运行优先级 + */ + uint32_t _uPriority = 0; + /** + * @brief 线程CPU亲和性掩码 + * @details 按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。例如:0x00000003表示使用0,1号CPU + */ + uint32_t _uAffinity = 0; + /** + * @brief 线程运行频率 + */ + double _setFreq = BASE_RUN_FREQ; + /** + * @brief 线程调度任务表 + */ + std::vector > > _funVec; + /** + * @brief pthread线程调度参数 + */ + sched_param param; + /** + * @brief pthread线程属性 + */ + pthread_attr_t attr; + /** + * @brief pthread线程 + */ + pthread_t thread; + /** + * @brief 线程睡眠时间控制 + */ + PERIOD_INFO pinfo; + /** + * @brief 线程控制锁 + */ + pthread_mutex_t _mtx = PTHREAD_MUTEX_INITIALIZER; + /** + * @brief 线程控制条件变量 + */ + pthread_cond_t _cond = PTHREAD_COND_INITIALIZER; + /** + * @brief 线程运行状态 + */ + RunStatus _eRunStatus = RunStatus::NotStart; + /** + * @brief 线程执行进度 + */ + uint32_t _RunPosition = 0; + /** + * @brief 线程执行计数 + */ + int count = 0; + /** + * @brief 线程执行时间统计 + */ + timespec _lastRunTime; + /** + * @brief 线程运行状态主题写入器 + */ + FAST_DDS_MACRO::DataWriter *writer; + /** + * @brief 线程ID + */ + uint32_t _threadID = 0; +}; diff --git a/Release/include/XNCore/XNTimeManager.h b/Release/include/XNCore/XNTimeManager.h index 214162d..8b39434 100644 --- a/Release/include/XNCore/XNTimeManager.h +++ b/Release/include/XNCore/XNTimeManager.h @@ -10,9 +10,9 @@ */ #pragma once #include "XNBaseFrameObject.h" -#include +#include -class XNTimeManagerPrivate; +struct XNTimeManagerPrivate; /** * @brief 时间管理器类 @@ -20,16 +20,14 @@ class XNTimeManagerPrivate; */ class XNCORE_EXPORT XNTimeManager : public XNBaseFrameObject { - Q_OBJECT - Q_DISABLE_COPY(XNTimeManager); - Q_DECLARE_PRIVATE(XNTimeManager); + XN_METATYPE(XNTimeManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNTimeManager) public: /** * @brief 构造函数 - * @param parent: 父对象 */ - explicit XNTimeManager(QObject *parent = nullptr); + XNTimeManager(); /** * @brief 析构函数 @@ -39,63 +37,46 @@ public: protected: /** * @brief 构造函数 - * @param dd: 私有数据成员 - * @param parent: 父对象 + * @param p: 私有数据成员 */ - XNTimeManager(XNTimeManagerPrivate &dd, QObject *parent = nullptr); + XNTimeManager(PrivateType *p); public: /** * @brief 获取当前仿真时间 - * @return QDateTime: 当前仿真时间 + * @return std::chrono::system_clock::time_point: 当前仿真时间 */ - QDateTime GetSimTime(); + XNTimePoint GetSimTime(); -signals: - /** - * @brief 设置仿真开始时间信号 - * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 - * @details 通过设置统一的开始时间,使个线程能同步执行 - */ - void SetStartTime(const timespec &simTime); - - /** - * @brief 仿真控制信号 - * @param objectId: 对象ID - * @param cmd: 仿真控制命令 - */ - void SimControl(quint32 objectId, SimControlCmd cmd); - -public slots: /** * @brief 设置仿真开始时间 - * @param simTime: timespec类型,仿真开始时间 + * @param simTime: timespec类型,仿真开始时间 */ - void OnSetStartTime(const timespec &simTime); + void SetStartTime(const timespec &simTime); /** * @brief 开始控制 * @details 控制时间管理器线程开始运行接口 */ - void OnStart(); + void Start(); /** * @brief 停止控制 * @details 控制时间管理器线程停止运行接口 */ - void OnAbort(); + void Abort(); /** * @brief 暂停控制 * @details 控制时间管理器线程暂停运行接口 */ - void OnPause(); + void Pause(); /** * @brief 继续控制 * @details 控制时间管理器线程继续运行接口 */ - void OnContinue(); + void Continue(); /** * @brief 初始化时间管理器 @@ -103,22 +84,21 @@ public slots: * @return false: 初始化失败 * @details 时间管理器的初始化接口函数 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 仿真运行前最后处理 * @note 时间管理器在开始执行前的准备工作 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 仿真控制 * @param objectId: 对象ID * @param cmd: 仿真控制命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); + void SimControl(uint32_t objectId, SimControlCmd cmd); -public: /** * @brief 获取运行状态 * @return RunStatus: 枚举类,时间管理器线程运行状态 diff --git a/Release/include/XNCore/XNTimeManager_p.h b/Release/include/XNCore/XNTimeManager_p.h index 57e5068..382edd1 100644 --- a/Release/include/XNCore/XNTimeManager_p.h +++ b/Release/include/XNCore/XNTimeManager_p.h @@ -11,21 +11,12 @@ #pragma once #include "XNBaseFrameObject_p.h" #include "XNThread.h" +#include /** * @brief 时间管理器类私有结构体 */ -class XNTimeManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNTimeManager) - - explicit XNTimeManagerPrivate(XNTimeManager *q) : XNBaseFrameObjectPrivate(q) - { - _eRunStatus = RunStatus::NotStart; - } - -private: +struct XNTimeManagerPrivate : public XNBaseFrameObjectPrivate { /* * @brief 仿真运行状态 */ @@ -33,11 +24,11 @@ private: /** * @brief 仿真开始时间 */ - QDateTime _SimStartTime; + std::chrono::system_clock::time_point _SimStartTime; /** * @brief 当前仿真时间 */ - QDateTime _SimTime; + std::chrono::system_clock::time_point _SimTime; /** * @brief 时间管理器线程智能指针 */ diff --git a/XNCore/.vscode/settings.json b/XNCore/.vscode/settings.json index 2bc15f4..3cea849 100755 --- a/XNCore/.vscode/settings.json +++ b/XNCore/.vscode/settings.json @@ -78,6 +78,7 @@ "qlibrary": "cpp", "csignal": "cpp", "any": "cpp", - "unordered_set": "cpp" + "unordered_set": "cpp", + "fstream": "cpp" } } \ No newline at end of file diff --git a/XNCore/CMakeLists.txt b/XNCore/CMakeLists.txt index 39dc28f..ff0da83 100755 --- a/XNCore/CMakeLists.txt +++ b/XNCore/CMakeLists.txt @@ -41,6 +41,7 @@ add_library(XNCore SHARED XNTimeManager.cpp XNThread.h XNThread.cpp + XNThread_p.h XNThreadManager.h XNThreadManager_p.h XNThreadManager.cpp @@ -54,7 +55,6 @@ add_library(XNCore SHARED XNScenarioManager_p.h XNScenarioManager.cpp XNDDSManager.h - XNDDSManager_p.h XNDDSManager.cpp XNServiceManager.h XNServiceManager_p.h diff --git a/XNCore/XNBaseFrameObject.cpp b/XNCore/XNBaseFrameObject.cpp index 1fc6f79..907483f 100755 --- a/XNCore/XNBaseFrameObject.cpp +++ b/XNCore/XNBaseFrameObject.cpp @@ -1,8 +1,7 @@ #include "XNBaseFrameObject.h" #include "XNBaseFrameObject_p.h" -XNBaseFrameObject::XNBaseFrameObject(QObject *parent) - : XNObject(*new XNBaseFrameObjectPrivate(this), parent) +XNBaseFrameObject::XNBaseFrameObject() : XNObject(new XNBaseFrameObjectPrivate()) { } @@ -10,13 +9,24 @@ XNBaseFrameObject::~XNBaseFrameObject() { } -XNBaseFrameObject::XNBaseFrameObject(XNBaseFrameObjectPrivate &dd, QObject *parent) - : XNObject(dd, parent) +XNBaseFrameObject::XNBaseFrameObject(PrivateType *p) : XNObject(p) { } XNFrameObjectStatus XNBaseFrameObject::GetFrameObjectStatus() { - Q_D(XNBaseFrameObject); + T_D(); return d->_status; } + +XNFrameworkPtr XNBaseFrameObject::GetFramework() +{ + T_D(); + return d->_framework; +} + +void XNBaseFrameObject::SetFramework(XNFrameworkPtr framework) +{ + T_D(); + d->_framework = framework; +} diff --git a/XNCore/XNBaseFrameObject.h b/XNCore/XNBaseFrameObject.h index b9ac873..26c0f65 100755 --- a/XNCore/XNBaseFrameObject.h +++ b/XNCore/XNBaseFrameObject.h @@ -12,34 +12,29 @@ #include "XNObject.h" -class XNBaseFrameObjectPrivate; +struct XNBaseFrameObjectPrivate; /** * @brief 框架对象基类 */ class XNCORE_EXPORT XNBaseFrameObject : public XNObject { - /** - * @brief 宏定义,用于支持Qt的元对象系统 - */ - Q_OBJECT - /** * @brief 宏定义,用于禁用拷贝构造函数 */ - Q_DISABLE_COPY(XNBaseFrameObject) + XN_METATYPE(XNBaseFrameObject, XNObject) /** * @brief 宏定义,用于声明私有数据成员 */ - Q_DECLARE_PRIVATE(XNBaseFrameObject); + XN_DECLARE_PRIVATE(XNBaseFrameObject) public: /** * @brief 构造函数 * @param parent 父对象 */ - XNBaseFrameObject(QObject *parent = nullptr); + XNBaseFrameObject(); /** * @brief 析构函数 @@ -52,44 +47,34 @@ protected: * @param dd 私有数据成员 * @param parent 父对象 */ - XNBaseFrameObject(XNBaseFrameObjectPrivate &dd, QObject *parent = nullptr); - -signals: - /** - * @brief 初始化 - */ - void Initialize(); - - /** - * @brief 初始化失败 - */ - void InitializeFailed(); - - /** - * @brief 准备执行 - */ - void PrepareForExecute(); - - /** - * @brief 准备执行失败 - */ - void PrepareForExecuteFailed(); - -public slots: - /** - * @brief 初始化 - */ - virtual void OnInitialize() = 0; - - /** - * @brief 准备执行 - */ - virtual void OnPrepareForExecute() = 0; + XNBaseFrameObject(PrivateType *p); public: + /** + * @brief 初始化 + */ + virtual bool Initialize() = 0; + + /** + * @brief 准备执行 + */ + virtual bool PrepareForExecute() = 0; + /** * @brief 获取框架对象状态 * @return 框架对象状态 */ XNFrameObjectStatus GetFrameObjectStatus(); + + /** + * @brief 获取框架对象 + * @return 框架对象 + */ + XNFrameworkPtr GetFramework(); + + /** + * @brief 设置框架对象 + * @param framework 框架对象 + */ + void SetFramework(XNFrameworkPtr framework); }; diff --git a/XNCore/XNBaseFrameObject_p.h b/XNCore/XNBaseFrameObject_p.h index 6f36523..1177b7c 100755 --- a/XNCore/XNBaseFrameObject_p.h +++ b/XNCore/XNBaseFrameObject_p.h @@ -16,22 +16,13 @@ /** * @brief 框架对象基类的私有数据成员 */ -class XNBaseFrameObjectPrivate : public XNObjectPrivate -{ -public: - /** - * @brief 构造函数 - * @param q 框架对象基类指针 - */ - explicit XNBaseFrameObjectPrivate(XNBaseFrameObject *q) : XNObjectPrivate(q) {} - - /** - * @brief 宏定义,用于声明公有数据成员 - */ - Q_DECLARE_PUBLIC(XNBaseFrameObject) - +struct XNBaseFrameObjectPrivate : public XNObjectPrivate { /** * @brief 框架对象状态 */ XNFrameObjectStatus _status = XNFrameObjectStatus::NotReady; + /** + * @brief 框架对象 + */ + XNFrameworkPtr _framework; }; diff --git a/XNCore/XNCore_Function.cpp b/XNCore/XNCore_Function.cpp new file mode 100644 index 0000000..0106209 --- /dev/null +++ b/XNCore/XNCore_Function.cpp @@ -0,0 +1,10 @@ +#include "XNCore_global.h" + +XNTimePoint parseISOTime(const std::string &timeStr) +{ + std::tm tm = {}; + std::istringstream ss(timeStr); + ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S"); + auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm)); + return tp; +} \ No newline at end of file diff --git a/XNCore/XNCore_global.h b/XNCore/XNCore_global.h index 682f264..bc921ab 100755 --- a/XNCore/XNCore_global.h +++ b/XNCore/XNCore_global.h @@ -1,14 +1,13 @@ -#ifndef XNCORE_GLOBAL_H -#define XNCORE_GLOBAL_H - -#include +#pragma once #if defined(XNCORE_LIBRARY) -# define XNCORE_EXPORT Q_DECL_EXPORT +# define XNCORE_EXPORT __attribute__((visibility("default"))) #else -# define XNCORE_EXPORT Q_DECL_IMPORT +# define XNCORE_EXPORT __attribute__((visibility("default"))) #endif +#define FORCEINLINE __attribute__((always_inline)) + #ifdef __linux__ # include # include @@ -20,8 +19,34 @@ # include # include # include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif +#include +#include +#include +#include +#include +#include +#include +#include #define FAST_DDS_MACRO eprosima::fastdds::dds /** @@ -40,6 +65,9 @@ using XNCallBack = std::function; //DDS回调函数类型别名 using XNDDSCallBack = std::function; +//事件回调函数类型别名 +using XNEventCallback = std::function; + /** * @brief 纳秒睡眠相关时间结构体 * @details 用于线程睡眠时间控制 @@ -54,6 +82,17 @@ struct PERIOD_INFO { */ long period_ns; }; +/** + * @brief 系统时间点类型别名 + */ +using XNTimePoint = std::chrono::system_clock::time_point; + +/** + * @brief 将ISO格式的时间字符串转换为系统时间点 + * @param timeStr ISO格式的时间字符串 (YYYY-MM-DDTHH:mm:ss) + * @return 系统时间点 + */ +XNTimePoint parseISOTime(const std::string &timeStr); /** * @brief 系统运行状态枚举类 @@ -155,10 +194,63 @@ enum class XNFrameObjectStatus { Unknown }; -#define XN_DLL_INITIALIZE(ClassName) \ - extern "C" void Initial##ClassName() \ - { \ - qRegisterMetaType(#ClassName); \ - } +template +FORCEINLINE ToType XNStaticCastHelper(const FromType &from) +{ + return std::static_pointer_cast(from); +} -#endif // XNCORE_GLOBAL_H +template +FORCEINLINE ToType XNCastHelper(const FromType &from) +{ + return std::dynamic_pointer_cast(from); +} + +#define XN_CAST(from, to) XNStaticCastHelper(from) + +#define XN_THISPTR std::static_pointer_cast(shared_from_this()) + +#define XNCLASS_PTR_DECLARE(a) \ + using a##Ptr = std::shared_ptr; \ + using a##WPtr = std::weak_ptr; \ + using a##UPtr = std::unique_ptr; \ + using a##ConsPtr = std::shared_ptr; + +#define XNSTRUCT_PTR_DECLARE(a) \ + using a##Ptr = std::shared_ptr; \ + using a##WPtr = std::weak_ptr; \ + using a##UPtr = std::unique_ptr; \ + using a##ConsPtr = std::shared_ptr; + +#define XN_NOCOPYABLE(Class) \ +public: \ + using NoCopyable = Class; \ + \ +private: \ + Class(const Class &) = delete; \ + Class &operator=(const Class &) = delete; + +#define XN_DECLARE_PRIVATE(Class) \ + XN_NOCOPYABLE(Class) \ +protected: \ + friend class Class##Private; \ + inline Class##Private *GetPP() const \ + { \ + return reinterpret_cast(_Private_Ptr); \ + } \ + using PrivateType = Class##Private; + +#define T_D() PrivateType *const d = GetPP() + +struct XNNullClass { +}; + +#define XN_METATYPE_P(cls) \ +public: \ + using ThisType = cls; \ + using SuperType = XNNullClass; + +#define XN_METATYPE(cls, sup) \ +public: \ + using ThisType = cls; \ + using SuperType = sup; diff --git a/XNCore/XNDDSInterface.h b/XNCore/XNDDSInterface.h old mode 100755 new mode 100644 index 5b1f610..b884b45 --- a/XNCore/XNDDSInterface.h +++ b/XNCore/XNDDSInterface.h @@ -45,44 +45,6 @@ public: XNDDSInterface() = default; virtual ~XNDDSInterface() = default; - template - void getByteArray(eprosima::fastcdr::optional data, uint8_t *buffer, size_t bufferSize) - { - if (bufferSize < getTypeSize()) - return; - - if constexpr (std::is_arithmetic_v) { - if (data) { - std::memcpy(buffer, &data.value(), sizeof(T)); - } else { - T zero = 0; - std::memcpy(buffer, &zero, sizeof(T)); - } - } else if constexpr (is_std_array_v) { - if (data) { - getByteArrayFromStdArray(data.value(), buffer, bufferSize); - } else { - T zero = {}; - getByteArrayFromStdArray(zero, buffer, bufferSize); - } - } - } - - template - void getByteArrayFromStdArray(std::array data, uint8_t *buffer, size_t bufferSize) - { - if (bufferSize < getTypeSize() * N) - return; - - for (std::size_t i = 0; i < N; ++i) { - if constexpr (std::is_arithmetic_v) { - std::memcpy(buffer + i * getTypeSize(), &data[i], getTypeSize()); - } else { - getByteArrayFromStdArray(data[i], buffer + i * getTypeSize(), getTypeSize()); - } - } - } - void getUDPPackage(uint8_t *buffer, size_t bufferSize) { if (bufferSize < MAX_UDP_PACKET_SIZE) @@ -112,42 +74,6 @@ public: } } - template - std::string getString(eprosima::fastcdr::optional data) - { - if constexpr (std::is_arithmetic_v) { - if (data) { - return std::to_string(data.value()); - } else { - return std::to_string(0); - } - } else if constexpr (std::is_same_v) { - if (data) { - return getStringFromStdArray(data.value()); - } else { - T zero = {}; - return getStringFromStdArray(zero); - } - } - return std::string(); - } - - template - std::string getStringFromStdArray(std::array data) - { - std::stringstream ss; - for (std::size_t i = 0; i < N; ++i) { - if (i > 0) - ss << ","; - if constexpr (std::is_arithmetic_v) { - ss << data[i]; - } else { - ss << getStringFromStdArray(data[i]); - } - } - return ss.str(); - } - std::string getData(const std::string &varName) { int index1 = -1; @@ -221,6 +147,81 @@ public: return list2[index2]; } +protected: + template + void getByteArray(eprosima::fastcdr::optional data, uint8_t *buffer, size_t bufferSize) + { + if (bufferSize < getTypeSize()) + return; + + if constexpr (std::is_arithmetic_v) { + if (data) { + std::memcpy(buffer, &data.value(), sizeof(T)); + } else { + T zero = 0; + std::memcpy(buffer, &zero, sizeof(T)); + } + } else if constexpr (is_std_array_v) { + if (data) { + getByteArrayFromStdArray(data.value(), buffer, bufferSize); + } else { + T zero = {}; + getByteArrayFromStdArray(zero, buffer, bufferSize); + } + } + } + + template + void getByteArrayFromStdArray(std::array data, uint8_t *buffer, size_t bufferSize) + { + if (bufferSize < getTypeSize() * N) + return; + + for (std::size_t i = 0; i < N; ++i) { + if constexpr (std::is_arithmetic_v) { + std::memcpy(buffer + i * getTypeSize(), &data[i], getTypeSize()); + } else { + getByteArrayFromStdArray(data[i], buffer + i * getTypeSize(), getTypeSize()); + } + } + } + + template + std::string getString(eprosima::fastcdr::optional data) + { + if constexpr (std::is_arithmetic_v) { + if (data) { + return std::to_string(data.value()); + } else { + return std::to_string(0); + } + } else if constexpr (std::is_same_v) { + if (data) { + return getStringFromStdArray(data.value()); + } else { + T zero = {}; + return getStringFromStdArray(zero); + } + } + return std::string(); + } + + template + std::string getStringFromStdArray(std::array data) + { + std::stringstream ss; + for (std::size_t i = 0; i < N; ++i) { + if (i > 0) + ss << ","; + if constexpr (std::is_arithmetic_v) { + ss << data[i]; + } else { + ss << getStringFromStdArray(data[i]); + } + } + return ss.str(); + } + protected: struct ByteArrayFunc { std::function func; @@ -239,3 +240,47 @@ protected: getByteArrayFunction.push_back( \ {[this](uint8_t *buffer, size_t size) { getByteArray(data.NAME(), buffer, size); }, \ getTypeSize()}) + +#define ASSIGN_VALUE_GET(NAME) \ + if (data.NAME()) { \ + auto temp = data.NAME().value(); \ + if constexpr (std::is_arithmetic_v) { \ + model_data->NAME = temp; \ + } else if constexpr (std::is_std_array_v) { \ + size_t arraySize = std::tuple_size::value; \ + for (size_t i = 0; i < arraySize; ++i) { \ + if constexpr (std::is_arithmetic_v) { \ + model_data->NAME[i] = temp[i]; \ + } else if constexpr (std::is_std_array_v) { \ + size_t arraySize2 = std::tuple_size::value; \ + for (size_t j = 0; j < arraySize2; ++j) { \ + model_data->NAME[i][j] = temp[i][j]; \ + } \ + } \ + } \ + } \ + } + +#define ASSIGN_VALUE_SET(NAME) \ + if constexpr (std::is_arithmetic_v) { \ + data.NAME(model_data->NAME); \ + } else if constexpr (std::is_std_array_v) { \ + using thisType = typename decltype(data.NAME())::type; \ + thisType temp; \ + size_t arraySize1 = std::tuple_size::value; \ + using subType = thisType::value_type; \ + if constexpr (std::is_arithmetic_v) { \ + for (size_t i = 0; i < arraySize1; ++i) { \ + temp[i] = model_data->NAME[i]; \ + } \ + } else if constexpr (std::is_std_array_v) { \ + size_t arraySize2 = std::tuple_size::value; \ + std::array temp; \ + for (size_t i = 0; i < arraySize1; ++i) { \ + for (size_t j = 0; j < arraySize2; ++j) { \ + temp[i][j] = model_data->NAME[i][j]; \ + } \ + } \ + } \ + data.NAME(temp); \ + } diff --git a/XNCore/XNDDSManager.cpp b/XNCore/XNDDSManager.cpp index 10b4f4b..febf13a 100755 --- a/XNCore/XNDDSManager.cpp +++ b/XNCore/XNDDSManager.cpp @@ -1,45 +1,45 @@ #include "XNDDSManager.h" -#include "XNDDSManager_p.h" -XNDDSManager::XNDDSManager(QObject *parent) - : XNBaseFrameObject(*new XNDDSManagerPrivate(this), parent) +XNDDSManager::XNDDSManager() : XNBaseFrameObject(new XNDDSManagerPrivate()) { - setUniqueId(8); - setObjectName("XNDDSManager"); + SetUniqueId(8); + SetObjectName("XNDDSManager"); } XNDDSManager::~XNDDSManager() { } -XNDDSManager::XNDDSManager(XNDDSManagerPrivate &dd, QObject *parent) : XNBaseFrameObject(dd, parent) +XNDDSManager::XNDDSManager(PrivateType *p) : XNBaseFrameObject(p) { } -void XNDDSManager::OnInitialize() +bool XNDDSManager::Initialize() { - Q_D(XNDDSManager); + T_D(); + d->_status = XNFrameObjectStatus::Initialized; + d->participant_ = nullptr; + d->topics_.clear(); LOG_INFO("XNDDSManager Initialize Success!"); - d->_status = XNFrameObjectStatus::Initialized; - emit Initialize(); + return true; } -void XNDDSManager::OnPrepareForExecute() +bool XNDDSManager::PrepareForExecute() { - Q_D(XNDDSManager); + T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNDDSManager is prepared!"); - emit PrepareForExecute(); + return true; } -void XNDDSManager::SetDomainID(quint32 domainID) +void XNDDSManager::SetDomainID(uint32_t domainID) { - Q_D(XNDDSManager); + T_D(); FAST_DDS_MACRO::DomainParticipantQos participantQos; participantQos.name("XNDDSManager"); - participant_ = FAST_DDS_MACRO::DomainParticipantFactory::get_instance()->create_participant( + d->participant_ = FAST_DDS_MACRO::DomainParticipantFactory::get_instance()->create_participant( domainID, participantQos); - if (participant_ == nullptr) { + if (d->participant_ == nullptr) { LOG_ERROR("0x2130 Create DomainParticipant Failed!"); } } diff --git a/XNCore/XNDDSManager.h b/XNCore/XNDDSManager.h index b7274c1..216edbf 100755 --- a/XNCore/XNDDSManager.h +++ b/XNCore/XNDDSManager.h @@ -1,14 +1,6 @@ #pragma once #include "XNBaseFrameObject.h" - -#include -#include -#include -#include -#include -#include -#include -#include +#include "XNBaseFrameObject_p.h" struct PublisherInfo { FAST_DDS_MACRO::Publisher *publisher; @@ -22,8 +14,8 @@ struct SubscriberInfo { struct TopicInfo { FAST_DDS_MACRO::Topic *topic; - QMap publishers_; - QMap subscribers_; + std::map publishers_; + std::map subscribers_; }; template @@ -46,50 +38,54 @@ private: std::function callback_; }; -class XNDDSManagerPrivate; +struct XNDDSManagerPrivate : public XNBaseFrameObjectPrivate { + FAST_DDS_MACRO::DomainParticipant *participant_; + std::map topics_; + std::mutex mutex_; +}; class XNDDSManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNDDSManager) - Q_DISABLE_COPY(XNDDSManager) + XN_METATYPE(XNDDSManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNDDSManager) public: - explicit XNDDSManager(QObject *parent = nullptr); + XNDDSManager(); ~XNDDSManager(); protected: - XNDDSManager(XNDDSManagerPrivate &dd, QObject *parent = nullptr); + XNDDSManager(PrivateType *p); -public slots: - virtual void OnInitialize() override; +public: + virtual bool Initialize() override; - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; - void SetDomainID(quint32 domainID); + void SetDomainID(uint32_t domainID); public: template - FAST_DDS_MACRO::DataWriter *RegisterPublisher(const QString &topicName, quint32 publisherID) + FAST_DDS_MACRO::DataWriter *RegisterPublisher(const std::string &topicName, + uint32_t publisherID) { - std::lock_guard lock(mutex_); - if (!topics_.contains(topicName)) { - topics_[topicName] = TopicInfo(); - TopicInfo &tmp = topics_[topicName]; + T_D(); + std::lock_guard lock(d->mutex_); + if (d->topics_.find(topicName) == d->topics_.end()) { + d->topics_[topicName] = TopicInfo(); + TopicInfo &tmp = d->topics_[topicName]; FAST_DDS_MACRO::TypeSupport typeSupport(new T()); - typeSupport.register_type(participant_); - tmp.topic = - participant_->create_topic(topicName.toStdString(), typeSupport.get_type_name(), - FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); + typeSupport.register_type(d->participant_); + tmp.topic = d->participant_->create_topic(topicName, typeSupport.get_type_name(), + FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); if (tmp.topic == nullptr) { LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName); - topics_.remove(topicName); + d->topics_.erase(topicName); return nullptr; } } - TopicInfo &tmp = topics_[topicName]; + TopicInfo &tmp = d->topics_[topicName]; tmp.publishers_[publisherID] = PublisherInfo(); tmp.publishers_[publisherID].publisher = - participant_->create_publisher(FAST_DDS_MACRO::PUBLISHER_QOS_DEFAULT, nullptr); + d->participant_->create_publisher(FAST_DDS_MACRO::PUBLISHER_QOS_DEFAULT, nullptr); if (tmp.publishers_[publisherID].publisher == nullptr) { LOG_ERROR("0x2131 Create Publisher %1 for Topic %2 Failed!", publisherID, topicName); return nullptr; @@ -119,29 +115,28 @@ public: } template - void RegisterSubscriber(const QString &topicName, quint32 subscriberID, + void RegisterSubscriber(const std::string &topicName, uint32_t subscriberID, std::function fun) { - Q_D(XNDDSManager); - std::lock_guard lock(mutex_); - if (!topics_.contains(topicName)) { - topics_[topicName] = TopicInfo(); - TopicInfo &tmp = topics_[topicName]; + T_D(); + std::lock_guard lock(d->mutex_); + if (d->topics_.find(topicName) == d->topics_.end()) { + d->topics_[topicName] = TopicInfo(); + TopicInfo &tmp = d->topics_[topicName]; FAST_DDS_MACRO::TypeSupport typeSupport(new T()); - typeSupport.register_type(participant_); - tmp.topic = - participant_->create_topic(topicName.toStdString(), typeSupport.get_type_name(), - FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); + typeSupport.register_type(d->participant_); + tmp.topic = d->participant_->create_topic(topicName, typeSupport.get_type_name(), + FAST_DDS_MACRO::TOPIC_QOS_DEFAULT); if (tmp.topic == nullptr) { LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName); - topics_.remove(topicName); + d->topics_.erase(topicName); return; } } - TopicInfo &tmp = topics_[topicName]; + TopicInfo &tmp = d->topics_[topicName]; tmp.subscribers_[subscriberID] = SubscriberInfo(); tmp.subscribers_[subscriberID].subscriber = - participant_->create_subscriber(FAST_DDS_MACRO::SUBSCRIBER_QOS_DEFAULT, nullptr); + d->participant_->create_subscriber(FAST_DDS_MACRO::SUBSCRIBER_QOS_DEFAULT, nullptr); if (tmp.subscribers_[subscriberID].subscriber == nullptr) { LOG_ERROR("0x2135 Create Subscriber %1 for Topic %2 Failed!", subscriberID, topicName); } @@ -157,9 +152,4 @@ public: } LOG_INFO("0x2137 Create Subscriber %1 for Topic %2 Success!", subscriberID, topicName); } - -private: - FAST_DDS_MACRO::DomainParticipant *participant_; - QMap topics_; - std::mutex mutex_; }; diff --git a/XNCore/XNDDSManager_p.h b/XNCore/XNDDSManager_p.h deleted file mode 100755 index 2d7d158..0000000 --- a/XNCore/XNDDSManager_p.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "XNBaseFrameObject_p.h" - -#include -#include - -struct TopicInfo; - -class XNDDSManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNDDSManager) - - explicit XNDDSManagerPrivate(XNDDSManager *q) : XNBaseFrameObjectPrivate(q) {} -}; diff --git a/XNCore/XNEventManager.cpp b/XNCore/XNEventManager.cpp index e390bf4..d5ee44f 100755 --- a/XNCore/XNEventManager.cpp +++ b/XNCore/XNEventManager.cpp @@ -1,76 +1,47 @@ #include "XNEventManager.h" #include "XNEventManager_p.h" #include "XNFramework.h" +#include +#include // 构造函数 -XNEventManager::XNEventManager(QObject *parent) - : XNBaseFrameObject(*new XNEventManagerPrivate(this), parent) +XNEventManager::XNEventManager() : XNBaseFrameObject(new XNEventManagerPrivate()) { // 设置唯一标识符 - setUniqueId(7); + SetUniqueId(7); // 设置对象名称 - setObjectName("XNEventManager"); + SetObjectName("XNEventManager"); } // 析构函数 XNEventManager::~XNEventManager() { + T_D(); + d->running = false; + d->taskCond.notify_all(); + for (auto &thread : d->workerThreads) { + if (thread.joinable()) { + thread.join(); + } + } } // 保护构造函数实现 -XNEventManager::XNEventManager(XNEventManagerPrivate &dd, QObject *parent) - : XNBaseFrameObject(dd, parent) +XNEventManager::XNEventManager(PrivateType *p) : XNBaseFrameObject(p) { } -// 添加一个用于异步执行的任务类 -class EventTask : public QRunnable -{ -public: - EventTask(const QString &name, const QVariant &data, - std::function callback, XNEventManager *manager) - : eventName(name), eventData(data), eventCallback(callback), eventManager(manager) - { - setAutoDelete(true); - } - - void run() override - { - try { - eventCallback(eventData); - if (eventManager) { - QMetaObject::invokeMethod(eventManager, "EventProcessed", Qt::QueuedConnection, - Q_ARG(QString, eventName), Q_ARG(bool, true)); - } - } catch (const std::exception &e) { - LOG_ERROR( - QString("Async event handler exception for %1: %2").arg(eventName).arg(e.what())); - if (eventManager) { - QMetaObject::invokeMethod(eventManager, "EventProcessed", Qt::QueuedConnection, - Q_ARG(QString, eventName), Q_ARG(bool, false)); - } - } - } - -private: - QString eventName; - QVariant eventData; - std::function eventCallback; - XNEventManager *eventManager; -}; - // 修改注册事件处理器的实现 -int XNEventManager::RegisterEventHandler(const QString &eventName, - std::function callback, - quint32 objectId, bool async, XNEvent::Priority priority) +int XNEventManager::RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + uint32_t objectId, bool async, XNEvent::Priority priority) { - Q_D(XNEventManager); - if (eventName.isEmpty() || !callback) { + T_D(); + if (eventName.empty() || !callback) { LOG_WARNING("Invalid event name or callback!"); return -1; } - QMutexLocker locker(&d->eventMutex); + std::lock_guard locker(d->eventMutex); // 生成新的本地ID d->localIdCounter = (d->localIdCounter + 1) & 0xFFFF; @@ -88,94 +59,94 @@ int XNEventManager::RegisterEventHandler(const QString &eventName, int handlerId = handlerInfo.GetHandlerId(); // 添加处理器信息到事件列表 - d->eventHandlers[eventName].append(handlerInfo); + d->eventHandlers[eventName].push_back(handlerInfo); // 添加反向映射 d->handlerToEvent[handlerId] = eventName; - LOG_INFO( - QString("Registered %1 event handler for event: %2, handler ID: %3 (object: %4, local: %5)") - .arg(async ? "async" : "sync") - .arg(eventName) - .arg(handlerId) - .arg(objectId) - .arg(d->localIdCounter)); + LOG_INFO("Registered " + std::string(async ? "async" : "sync") + " event handler for event: " + + eventName + ", handler ID: " + std::to_string(handlerId) + " (object: " + + std::to_string(objectId) + ", local: " + std::to_string(d->localIdCounter) + ")"); return handlerId; } // 修改移除事件处理器的实现 -bool XNEventManager::RemoveEventHandler(const QString &eventName, int handlerId) +bool XNEventManager::RemoveEventHandler(const std::string &eventName, int handlerId) { - Q_D(XNEventManager); - QMutexLocker locker(&d->eventMutex); + T_D(); + std::lock_guard locker(d->eventMutex); // 如果指定了事件名称,先验证事件是否存在 - if (!eventName.isEmpty()) { - if (!d->eventHandlers.contains(eventName)) { - LOG_WARNING(QString("Event %1 not found!").arg(eventName)); + if (!eventName.empty()) { + auto it = d->eventHandlers.find(eventName); + if (it == d->eventHandlers.end()) { + LOG_WARNING("Event " + eventName + " not found!"); return false; } // 查找并移除指定的处理器 - auto &handlers = d->eventHandlers[eventName]; - for (auto it = handlers.begin(); it != handlers.end(); ++it) { - if (it->GetHandlerId() == handlerId) { - handlers.erase(it); - d->handlerToEvent.remove(handlerId); - LOG_INFO( - QString("Removed handler ID %1 from event: %2").arg(handlerId).arg(eventName)); + auto &handlers = it->second; + auto handlerIt = std::find_if( + handlers.begin(), handlers.end(), + [handlerId](const EventHandlerInfo &info) { return info.GetHandlerId() == handlerId; }); - // 如果事件没有处理器了,移除整个事件 - if (handlers.isEmpty()) { - d->eventHandlers.remove(eventName); - } - return true; + if (handlerIt != handlers.end()) { + handlers.erase(handlerIt); + d->handlerToEvent.erase(handlerId); + LOG_INFO("Removed handler ID " + std::to_string(handlerId) + + " from event: " + eventName); + + // 如果事件没有处理器了,移除整个事件 + if (handlers.empty()) { + d->eventHandlers.erase(it); } + return true; } - LOG_WARNING(QString("Handler ID %1 not found in event: %2").arg(handlerId).arg(eventName)); + LOG_WARNING("Handler ID " + std::to_string(handlerId) + + " not found in event: " + eventName); return false; } // 如果没有指定事件名称,使用反向映射查找 auto eventIt = d->handlerToEvent.find(handlerId); if (eventIt != d->handlerToEvent.end()) { - QString eventToRemove = eventIt.value(); - auto &handlers = d->eventHandlers[eventToRemove]; + std::string eventToRemove = eventIt->second; + auto &handlers = d->eventHandlers[eventToRemove]; - for (auto it = handlers.begin(); it != handlers.end(); ++it) { - if (it->GetHandlerId() == handlerId) { - handlers.erase(it); - d->handlerToEvent.remove(handlerId); - LOG_INFO(QString("Removed handler ID %1 from event: %2") - .arg(handlerId) - .arg(eventToRemove)); + auto handlerIt = std::find_if( + handlers.begin(), handlers.end(), + [handlerId](const EventHandlerInfo &info) { return info.GetHandlerId() == handlerId; }); - // 如果事件没有处理器了,移除整个事件 - if (handlers.isEmpty()) { - d->eventHandlers.remove(eventToRemove); - } - return true; + if (handlerIt != handlers.end()) { + handlers.erase(handlerIt); + d->handlerToEvent.erase(handlerId); + LOG_INFO("Removed handler ID " + std::to_string(handlerId) + + " from event: " + eventToRemove); + + // 如果事件没有处理器了,移除整个事件 + if (handlers.empty()) { + d->eventHandlers.erase(eventToRemove); } + return true; } } - LOG_WARNING(QString("Handler ID %1 not found!").arg(handlerId)); + LOG_WARNING("Handler ID " + std::to_string(handlerId) + " not found!"); return false; } // 修改触发事件的实现 -void XNEventManager::TriggerEvent(const QString &eventName, const QVariant &eventData, +void XNEventManager::TriggerEvent(const std::string &eventName, const std::any &eventData, bool forceAsync, XNEvent::Priority priority) { - Q_D(XNEventManager); - - QList handlers; + T_D(); + std::list handlers; { - QMutexLocker locker(&d->eventMutex); - if (!d->eventHandlers.contains(eventName)) { - //LOG_WARNING(QString("No handlers registered for event: %1").arg(eventName)); + std::lock_guard locker(d->eventMutex); + auto it = d->eventHandlers.find(eventName); + if (it == d->eventHandlers.end()) { return; } - handlers = d->eventHandlers[eventName]; + handlers = it->second; } for (const auto &handler : handlers) { @@ -186,54 +157,85 @@ void XNEventManager::TriggerEvent(const QString &eventName, const QVariant &even d->rtManager.addTask(task); } else { // 普通异步任务使用线程池 - d->normalThreadPool.start( - new EventTask(eventName, eventData, handler.callback, this)); + std::lock_guard lock(d->taskMutex); + d->taskQueue.push(new AsyncEventTask(eventName, eventData, handler.callback, this)); + d->taskCond.notify_one(); } } else { // 同步执行 try { handler.callback(eventData); - emit EventProcessed(eventName, true); + EventProcessed(eventName, true); } catch (const std::exception &e) { - LOG_ERROR(QString("Exception in handler %1 for event %2: %3") - .arg(handler.GetHandlerId()) - .arg(eventName) - .arg(e.what())); - emit EventProcessed(eventName, false); + LOG_ERROR("Exception in handler " + std::to_string(handler.GetHandlerId()) + + " for event " + eventName + ": " + e.what()); + EventProcessed(eventName, false); } } } - - //LOG_INFO(QString("Triggered event: %1 with %2 handlers").arg(eventName).arg(handlers.size())); } void XNEventManager::SetMaxThreadCount(int count) { - Q_D(XNEventManager); - d->threadPool.setMaxThreadCount(count); - LOG_INFO(QString("Set thread pool max thread count to %1").arg(count)); + T_D(); + std::lock_guard lock(d->taskMutex); + // 停止现有线程 + d->running = false; + d->taskCond.notify_all(); + for (auto &thread : d->workerThreads) { + if (thread.joinable()) { + thread.join(); + } + } + d->workerThreads.clear(); + + // 创建新线程 + d->running = true; + for (int i = 0; i < count; ++i) { + d->workerThreads.emplace_back([this, d]() { + while (d->running) { + BaseEventTask *task = nullptr; + { + std::unique_lock lock(d->taskMutex); + d->taskCond.wait(lock, + [this, d] { return !d->taskQueue.empty() || !d->running; }); + if (!d->running) { + break; + } + task = d->taskQueue.front(); + d->taskQueue.pop(); + } + if (task) { + task->execute(); + delete task; + } + } + }); + } + LOG_INFO("Set thread pool max thread count to " + std::to_string(count)); } int XNEventManager::GetMaxThreadCount() const { - Q_D(const XNEventManager); - return d->threadPool.maxThreadCount(); + T_D(); + std::lock_guard lock(d->taskMutex); + return d->workerThreads.size(); } void XNEventManager::WaitForAsyncEvents() { - Q_D(XNEventManager); - d->threadPool.waitForDone(); + T_D(); + std::unique_lock lock(d->taskMutex); + d->taskCond.wait(lock, [this, d] { return d->taskQueue.empty(); }); LOG_INFO("All async events have been processed"); } // 初始化事件管理器 -void XNEventManager::OnInitialize() +bool XNEventManager::Initialize() { - Q_D(XNEventManager); - + T_D(); // 配置普通线程池 - d->threadPool.setMaxThreadCount(QThread::idealThreadCount()); + SetMaxThreadCount(std::thread::hardware_concurrency()); // 配置实时线程池 SetRTThreadPoolConfig(2, // 最大线程数 @@ -242,32 +244,30 @@ void XNEventManager::OnInitialize() LOG_INFO("XNEventManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; - emit Initialize(); + return true; } // 准备执行 -void XNEventManager::OnPrepareForExecute() +bool XNEventManager::PrepareForExecute() { - Q_D(XNEventManager); - // 设置状态为就绪 + T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNEventManager is prepared!"); - // 发送准备完成信号 - emit PrepareForExecute(); + return true; } void XNEventManager::SetRTThreadPoolConfig(int maxThreads, int minPriority, int maxPriority) { - Q_D(XNEventManager); + T_D(); d->rtManager.stop(); - XNFramework *framework = qobject_cast(parent()); - if (framework == nullptr) { + XNFrameworkPtr framework = GetFramework(); + if (!framework) { LOG_WARNING("XNFramework is nullptr!"); return; } - quint32 cpuAffinity = framework->GetCpuAffinity(); + uint32_t cpuAffinity = framework->GetCpuAffinity(); // 找到最后一个可用的CPU int lastCpu = -1; @@ -281,8 +281,15 @@ void XNEventManager::SetRTThreadPoolConfig(int maxThreads, int minPriority, int LOG_WARNING("No available CPU found in affinity mask, using default CPU 1"); lastCpu = 1; } else { - LOG_INFO(QString("RT thread bound to CPU %1").arg(lastCpu)); + LOG_INFO("RT thread bound to CPU " + std::to_string(lastCpu)); } d->rtManager.start(maxThreads, maxPriority, lastCpu); } + +void XNEventManager::EventProcessed(const std::string &eventName, bool success) +{ + T_D(); + // 这里可以添加事件处理完成的回调逻辑 + LOG_INFO("Event " + eventName + " processed " + (success ? "successfully" : "with error")); +} diff --git a/XNCore/XNEventManager.h b/XNCore/XNEventManager.h index 4c5067c..4d046fd 100755 --- a/XNCore/XNEventManager.h +++ b/XNCore/XNEventManager.h @@ -1,6 +1,6 @@ #pragma once #include "XNBaseFrameObject.h" -#include + // 事件优先级定义 namespace XNEvent { @@ -11,19 +11,18 @@ enum class Priority { Low = 3 // 低优先级 }; } + // 前向声明私有类 -class XNEventManagerPrivate; +struct XNEventManagerPrivate; // 事件管理器类,继承自XNBaseFrameObject class XNEventManager : public XNBaseFrameObject { - Q_OBJECT // 启用Qt的元对象系统 - Q_DECLARE_PRIVATE(XNEventManager) // 声明私有实现类 - Q_DISABLE_COPY(XNEventManager) // 禁用拷贝构造和赋值操作 - - public : - // 构造函数,创建事件管理器实例 - explicit XNEventManager(QObject *parent = nullptr); + XN_METATYPE(XNEventManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNEventManager) +public: + // 构造函数,创建事件管理器实例 + XNEventManager(); // 析构函数 ~XNEventManager(); @@ -34,21 +33,20 @@ class XNEventManager : public XNBaseFrameObject // @param async: 是否异步处理该事件 // @param priority: 事件优先级 // @return: 返回处理器ID,失败返回-1 - int RegisterEventHandler(const QString &eventName, - std::function callback, quint32 objectId, - bool async = false, + int RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + uint32_t objectId, bool async = false, XNEvent::Priority priority = XNEvent::Priority::Normal); // 移除事件处理器 // @param eventName: 事件名称 // @param handlerId: 处理器ID // @return: 移除是否成功 - bool RemoveEventHandler(const QString &eventName, int handlerId); + bool RemoveEventHandler(const std::string &eventName, int handlerId); // 触发指定事件 // @param eventName: 要触发的事件名称 // @param eventData: 事件携带的数据 // @param forceAsync: 强制异步处理 // @param priority: 事件优先级 - void TriggerEvent(const QString &eventName, const QVariant &eventData = QVariant(), + void TriggerEvent(const std::string &eventName, const std::any &eventData = std::any(), bool forceAsync = false, XNEvent::Priority priority = XNEvent::Priority::Normal); @@ -64,17 +62,16 @@ class XNEventManager : public XNBaseFrameObject // 设置实时线程池参数 void SetRTThreadPoolConfig(int maxThreads, int minPriority, int maxPriority); + // 事件处理完成回调 + void EventProcessed(const std::string &eventName, bool success); + protected: // 保护构造函数,用于继承实现 - XNEventManager(XNEventManagerPrivate &dd, QObject *parent = nullptr); + XNEventManager(PrivateType *p); -public slots: +public: // 初始化事件管理器 - virtual void OnInitialize() override; + virtual bool Initialize() override; // 准备执行 - virtual void OnPrepareForExecute() override; - -signals: - // 事件处理完成信号 - void EventProcessed(const QString &eventName, bool success); + virtual bool PrepareForExecute() override; }; \ No newline at end of file diff --git a/XNCore/XNEventManager_p.h b/XNCore/XNEventManager_p.h index 7d38fd4..a381b4b 100755 --- a/XNCore/XNEventManager_p.h +++ b/XNCore/XNEventManager_p.h @@ -1,9 +1,6 @@ #pragma once #include "XNBaseFrameObject_p.h" #include "XNEventManager.h" -#include -#include -#include #include #include #include @@ -12,78 +9,130 @@ #include #include #include +#include +#include +#include +#include // 事件处理器信息结构 struct EventHandlerInfo { - std::function callback; // 回调函数 - quint32 objectId; // 对象ID - int localId; // 本地ID + std::function callback; // 回调函数 + uint32_t objectId; // 对象ID + uint32_t localId; // 本地ID bool isAsync; // 是否异步处理 XNEvent::Priority priority; // 事件优先级 - int threadPriority; // 线程优先级 + uint32_t threadPriority; // 线程优先级 // 获取全局处理器ID - int GetHandlerId() const { return (objectId << 16) | (localId & 0xFFFF); } + uint32_t GetHandlerId() const { return (objectId << 16) | (localId & 0xFFFF); } // 从全局处理器ID中提取对象ID - static quint32 GetObjectId(int handlerId) { return handlerId >> 16; } + static uint32_t GetObjectId(uint32_t handlerId) { return handlerId >> 16; } // 从全局处理器ID中提取本地ID - static int GetLocalId(int handlerId) { return handlerId & 0xFFFF; } + static uint32_t GetLocalId(uint32_t handlerId) { return handlerId & 0xFFFF; } }; // 事件任务基类 -class BaseEventTask : public QRunnable +class BaseEventTask { public: - BaseEventTask(const QString &name, const QVariant &data, - std::function callback, XNEventManager *manager) + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + BaseEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) : eventName(name), eventData(data), eventCallback(callback), eventManager(manager) { - setAutoDelete(true); } virtual ~BaseEventTask() = default; + /** + * @brief 执行任务 + */ + virtual void execute() = 0; + protected: - QString eventName; - QVariant eventData; - std::function eventCallback; + std::string eventName; + std::any eventData; + std::function eventCallback; XNEventManager *eventManager; }; -// 实时事件任务 -class RTEventTask +// 异步事件任务 +class AsyncEventTask : public BaseEventTask { public: - RTEventTask(const QString &name, const QVariant &data, - std::function callback, XNEventManager *manager) - : eventName(name), eventData(data), eventCallback(callback), eventManager(manager) + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + AsyncEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) + : BaseEventTask(name, data, callback, manager) { } - void execute() + /** + * @brief 执行任务 + */ + void execute() override { try { eventCallback(eventData); if (eventManager) { - QMetaObject::invokeMethod(eventManager, "EventProcessed", Qt::QueuedConnection, - Q_ARG(QString, eventName), Q_ARG(bool, true)); + eventManager->EventProcessed(eventName, true); } } catch (const std::exception &e) { - LOG_ERROR( - QString("RT event handler exception for %1: %2").arg(eventName).arg(e.what())); + LOG_ERROR("Async event handler exception for " + eventName + ": " + e.what()); if (eventManager) { - QMetaObject::invokeMethod(eventManager, "EventProcessed", Qt::QueuedConnection, - Q_ARG(QString, eventName), Q_ARG(bool, false)); + eventManager->EventProcessed(eventName, false); } } } +}; -private: - QString eventName; - QVariant eventData; - std::function eventCallback; - XNEventManager *eventManager; +// 实时事件任务 +class RTEventTask : public BaseEventTask +{ +public: + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + RTEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) + : BaseEventTask(name, data, callback, manager) + { + } + + /** + * @brief 执行任务 + */ + void execute() override + { + try { + eventCallback(eventData); + if (eventManager) { + eventManager->EventProcessed(eventName, true); + } + } catch (const std::exception &e) { + LOG_ERROR("RT event handler exception for " + eventName + ": " + e.what()); + if (eventManager) { + eventManager->EventProcessed(eventName, false); + } + } + } }; // 实时线程管理器 @@ -167,35 +216,27 @@ private: }; // 事件管理器的私有实现类 -class XNEventManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - // 声明公共接口类 - Q_DECLARE_PUBLIC(XNEventManager) - - // 构造函数,初始化私有实现 - explicit XNEventManagerPrivate(XNEventManager *q) : XNBaseFrameObjectPrivate(q) {} - +struct XNEventManagerPrivate : public XNBaseFrameObjectPrivate { // 存储事件及其对应的处理器信息列表 // key: 事件名称 // value: 该事件对应的所有处理器信息列表 - QMap> eventHandlers; + std::map> eventHandlers; // 处理器ID到事件名称的反向映射,用于快速查找 - QMap handlerToEvent; + std::map handlerToEvent; // 本地ID计数器 int localIdCounter = 0; // 互斥锁,用于保护事件处理器表的线程安全访问 - QMutex eventMutex; + std::mutex eventMutex; - // 线程池,用于异步执行事件处理器 - QThreadPool threadPool; - - // 实时线程池 - QThreadPool rtThreadPool; + // 线程池相关 + std::vector workerThreads; + std::queue taskQueue; + std::mutex taskMutex; + std::condition_variable taskCond; + bool running = true; RTThreadManager rtManager; - QThreadPool normalThreadPool; // 用于非实时任务 }; diff --git a/XNCore/XNFramework.cpp b/XNCore/XNFramework.cpp index 0199bac..df88825 100755 --- a/XNCore/XNFramework.cpp +++ b/XNCore/XNFramework.cpp @@ -9,130 +9,28 @@ #include "XNServiceManager.h" #include "XNEventManager.h" -XNFramework::XNFramework(QObject *parent) : XNObject(*new XNFrameworkPrivate(this), parent) +XNFramework::XNFramework() : XNObject(new XNFrameworkPrivate()) { - setObjectName("XNFramework"); - setUniqueId(1); - XNTimeManager *timeManager = new XNTimeManager(this); - XNThreadManager *threadManager = new XNThreadManager(this); - XNScenarioManager *scenarioManager = new XNScenarioManager(this); - XNDDSManager *ddsManager = new XNDDSManager(this); - XNModelManager *modelManager = new XNModelManager(this); - XNServiceManager *serviceManager = new XNServiceManager(this); - XNEventManager *eventManager = new XNEventManager(this); - - //链接各组件初始化信号槽,依次链接,回告完成 - connect(this, &XNFramework::Initialize, eventManager, &XNEventManager::OnInitialize); - connect(eventManager, &XNEventManager::Initialize, timeManager, &XNTimeManager::OnInitialize); - connect(timeManager, &XNTimeManager::Initialize, ddsManager, &XNDDSManager::OnInitialize); - connect(ddsManager, &XNDDSManager::Initialize, serviceManager, &XNServiceManager::OnInitialize); - connect(serviceManager, &XNServiceManager::Initialize, threadManager, - &XNThreadManager::OnInitialize); - connect(threadManager, &XNThreadManager::Initialize, modelManager, - &XNModelManager::OnInitialize); - connect(modelManager, &XNModelManager::Initialize, scenarioManager, - &XNScenarioManager::OnInitialize); - connect(modelManager, &XNModelManager::InitializeSuccess, this, - &XNFramework::OnInitializeSuccess); - - //连接各组件初始化失败信号到框架的槽 - connect(eventManager, &XNEventManager::InitializeFailed, this, - &XNFramework::OnInitializeFailed); - connect(timeManager, &XNTimeManager::InitializeFailed, this, &XNFramework::OnInitializeFailed); - connect(ddsManager, &XNDDSManager::InitializeFailed, this, &XNFramework::OnInitializeFailed); - connect(serviceManager, &XNServiceManager::InitializeFailed, this, - &XNFramework::OnInitializeFailed); - connect(threadManager, &XNThreadManager::InitializeFailed, this, - &XNFramework::OnInitializeFailed); - connect(modelManager, &XNModelManager::InitializeFailed, this, - &XNFramework::OnInitializeFailed); - connect(scenarioManager, &XNScenarioManager::InitializeFailed, this, - &XNFramework::OnInitializeFailed); - - //连接解析配置文件信号到框架的槽 - connect(scenarioManager, &XNScenarioManager::AnalyzeScenarioXmlFailed, this, - &XNFramework::OnAnalyzeScenarioXmlFailed); - connect(scenarioManager, &XNScenarioManager::AnalyzeScenarioXmlSuccess, this, - &XNFramework::OnAnalyzeScenarioXmlSuccess); - - //链接各组件准备执行信号槽 - connect(this, &XNFramework::PrepareForExecute, eventManager, - &XNEventManager::OnPrepareForExecute); - connect(eventManager, &XNEventManager::PrepareForExecute, timeManager, - &XNTimeManager::OnPrepareForExecute); - connect(timeManager, &XNTimeManager::PrepareForExecute, ddsManager, - &XNDDSManager::OnPrepareForExecute); - connect(ddsManager, &XNDDSManager::PrepareForExecute, serviceManager, - &XNServiceManager::OnPrepareForExecute); - connect(serviceManager, &XNServiceManager::PrepareForExecute, threadManager, - &XNThreadManager::OnPrepareForExecute); - connect(threadManager, &XNThreadManager::PrepareForExecute, modelManager, - &XNModelManager::OnPrepareForExecute); - connect(modelManager, &XNModelManager::PrepareForExecute, scenarioManager, - &XNScenarioManager::OnPrepareForExecute); - connect(modelManager, &XNModelManager::PrepareForExecuteSuccess, this, - &XNFramework::OnPrepareForExecuteSuccess); - - //连接准备执行失败的槽 - connect(eventManager, &XNEventManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - connect(timeManager, &XNTimeManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - connect(ddsManager, &XNDDSManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - connect(serviceManager, &XNServiceManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - connect(threadManager, &XNThreadManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - connect(modelManager, &XNModelManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - connect(scenarioManager, &XNScenarioManager::PrepareForExecuteFailed, this, - &XNFramework::OnPrepareForExecuteFailed); - - //threadManager的设置开始时间信号触发timeManager的设置开始时间槽 - connect(threadManager, &XNThreadManager::SetStartTime, timeManager, - &XNTimeManager::OnSetStartTime); - //framework的仿真控制信号触发timeManager的仿真控制槽 - connect(this, &XNFramework::SimControl, timeManager, &XNTimeManager::OnSimControl); - //timeManager的仿真控制信号触发threadManager的仿真控制槽 - connect(timeManager, &XNTimeManager::SimControl, threadManager, &XNThreadManager::OnSimControl); - //scenarioManager的分析场景XML信号触发framework的分析场景XML槽 - connect(this, &XNFramework::AnalyzeScenarioXml, scenarioManager, - &XNScenarioManager::AnalysisScenarioXml); - //scenarioManager的添加线程池信号触发threadManager的添加线程池槽 - connect(scenarioManager, &XNScenarioManager::AddThreadPool, threadManager, - &XNThreadManager::OnAddThreadPool); - //scenarioManager的加载模型信号触发modelManager的加载模型槽 - connect(scenarioManager, &XNScenarioManager::LoadModel, modelManager, - &XNModelManager::OnLoadModel); - //scenarioManager的加载服务信号触发serviceManager的加载服务槽 - connect(scenarioManager, &XNScenarioManager::LoadService, serviceManager, - &XNServiceManager::OnLoadService); - //scenarioManager的设置工作路径信号触发framework的设置工作路径槽 - connect(scenarioManager, &XNScenarioManager::SetWorkPath, this, &XNFramework::SetWorkPath); - //scenarioManager的设置模型路径信号触发framework的设置模型路径槽 - connect(scenarioManager, &XNScenarioManager::SetModelPath, this, &XNFramework::SetModelPath); - //scenarioManager的设置服务路径信号触发framework的设置服务路径槽 - connect(scenarioManager, &XNScenarioManager::SetServicePath, this, - &XNFramework::SetServicePath); - //scenarioManager的设置CPU亲和性信号触发framework的设置CPU亲和性槽 - connect(scenarioManager, &XNScenarioManager::SetCpuAffinity, this, - &XNFramework::SetCpuAffinity); - //scenarioManager的设置基频信号触发threadManager的设置基频槽 - connect(scenarioManager, &XNScenarioManager::SetBaseFreq, threadManager, - &XNThreadManager::OnSetBaseFreq); - //scenarioManager的设置基频信号触发modelManager的设置基频槽 - connect(scenarioManager, &XNScenarioManager::SetBaseFreq, modelManager, - &XNModelManager::OnSetBaseFreq); - //modelManager的注册函数信号触发threadManager的注册函数槽 - connect(modelManager, &XNModelManager::RegisterFunction, threadManager, - &XNThreadManager::OnRegisterFunction); - //scenarioManager的设置DDS域ID信号触发ddsManager的设置DDS域ID槽 - connect(scenarioManager, &XNScenarioManager::SetDomainID, ddsManager, - &XNDDSManager::SetDomainID); + SetObjectName("XNFramework"); + SetUniqueId(1); + T_D(); + d->timeManager = std::make_shared(); + d->threadManager = std::make_shared(); + d->scenarioManager = std::make_shared(); + d->ddsManager = std::make_shared(); + d->modelManager = std::make_shared(); + d->serviceManager = std::make_shared(); + d->eventManager = std::make_shared(); + d->ddsManager->SetFramework(XN_THISPTR); + d->timeManager->SetFramework(XN_THISPTR); + d->threadManager->SetFramework(XN_THISPTR); + d->scenarioManager->SetFramework(XN_THISPTR); + d->modelManager->SetFramework(XN_THISPTR); + d->serviceManager->SetFramework(XN_THISPTR); + d->eventManager->SetFramework(XN_THISPTR); } -XNFramework::XNFramework(XNFrameworkPrivate &dd, QObject *parent) : XNObject(dd, parent) +XNFramework::XNFramework(PrivateType *p) : XNObject(p) { } @@ -140,114 +38,196 @@ XNFramework::~XNFramework() { } -QString XNFramework::GetWorkPath() +std::string XNFramework::GetWorkPath() { - Q_D(XNFramework); + T_D(); return d->workPath; } -void XNFramework::SetWorkPath(const QString &workPath) +void XNFramework::SetWorkPath(const std::string &workPath) { - Q_D(XNFramework); + T_D(); d->workPath = workPath; } -QString XNFramework::GetModelPath() +std::string XNFramework::GetModelPath() { - Q_D(XNFramework); + T_D(); return d->modelPath; } -void XNFramework::SetModelPath(const QString &modelPath) +void XNFramework::SetModelPath(const std::string &modelPath) { - Q_D(XNFramework); + T_D(); d->modelPath = modelPath; } -QString XNFramework::GetServicePath() +std::string XNFramework::GetServicePath() { - Q_D(XNFramework); + T_D(); return d->servicePath; } -void XNFramework::SetServicePath(const QString &servicePath) +void XNFramework::SetServicePath(const std::string &servicePath) { - Q_D(XNFramework); + T_D(); d->servicePath = servicePath; } -quint32 XNFramework::GetCpuAffinity() +uint32_t XNFramework::GetCpuAffinity() { - Q_D(XNFramework); + T_D(); return d->uCpuAffinity; } -void XNFramework::SetCpuAffinity(quint32 cpuAffinity) +void XNFramework::SetCpuAffinity(uint32_t cpuAffinity) { - Q_D(XNFramework); + T_D(); d->uCpuAffinity = cpuAffinity; } -void XNFramework::OnInitialize() +void XNFramework::Initialize() { - Q_D(XNFramework); + T_D(); LOG_INFO("XNFramework Initialize ..."); - emit Initialize(); + bool ret = d->eventManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + ret = d->timeManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + ret = d->ddsManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + ret = d->serviceManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + ret = d->threadManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + ret = d->modelManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + ret = d->scenarioManager->Initialize(); + if (!ret) { + LOG_ERROR("XNFramework Initialize Failed!"); + return; + } + LOG_INFO("XNFramework Initialize Success!"); + LOG_INFO("XNFramework Analyze Scenario Xml ..."); + ret = d->scenarioManager->AnalysisScenarioXml(d->scenarioXml); + if (!ret) { + LOG_ERROR("XNFramework Analyze Scenario Xml Failed!"); + return; + } + LOG_INFO("XNFramework Analyze Scenario Xml Success!"); } -void XNFramework::OnPrepareForExecute() +void XNFramework::PrepareForExecute() { - Q_D(XNFramework); - emit PrepareForExecute(); + T_D(); + + bool ret = d->eventManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + ret = d->timeManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + ret = d->ddsManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + ret = d->serviceManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + ret = d->threadManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + ret = d->modelManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + ret = d->scenarioManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return; + } + LOG_INFO("XNCore is prepared for execute! Simulation will start soon..."); } -void XNFramework::SetScenarioXml(const QString &scenarioXml) +void XNFramework::SetScenarioXml(const std::string &scenarioXml) { - Q_D(XNFramework); + T_D(); d->scenarioXml = scenarioXml; } -void XNFramework::OnInitializeSuccess() +void XNFramework::SimControl(uint32_t objectId, SimControlCmd cmd) { - Q_D(XNFramework); - LOG_INFO("XNFramework Initialize Success!"); - LOG_INFO("XNFramework Analyze Scenario Xml ..."); - emit AnalyzeScenarioXml(d->scenarioXml); + T_D(); + d->timeManager->SimControl(objectId, cmd); + d->threadManager->SimControl(objectId, cmd); } -void XNFramework::OnInitializeFailed() +XNTimeManagerPtr XNFramework::GetTimeManager() { - LOG_INFO("XNFramework Initialize Failed!"); - emit InitializeSuccess(false); + T_D(); + return d->timeManager; } -void XNFramework::OnAnalyzeScenarioXmlSuccess() +XNThreadManagerPtr XNFramework::GetThreadManager() { - LOG_INFO("XNFramework Analyze Scenario Xml Success!"); - emit InitializeSuccess(true); + T_D(); + return d->threadManager; } -void XNFramework::OnAnalyzeScenarioXmlFailed() +XNScenarioManagerPtr XNFramework::GetScenarioManager() { - LOG_INFO("XNFramework Analyze Scenario Xml Failed!"); - emit InitializeSuccess(false); + T_D(); + return d->scenarioManager; } -void XNFramework::OnPrepareForExecuteSuccess() +XNDDSManagerPtr XNFramework::GetDDSManager() { - Q_D(XNFramework); - LOG_INFO("XNCore is prepared for execute! Simulation will start soon..."); - emit PrepareForExecuteSuccess(true); + T_D(); + return d->ddsManager; } -void XNFramework::OnPrepareForExecuteFailed() +XNEventManagerPtr XNFramework::GetEventManager() { - Q_D(XNFramework); - LOG_INFO("XNCore is failed to prepared for execute!"); - emit PrepareForExecuteSuccess(false); + T_D(); + return d->eventManager; } -void XNFramework::OnSimControl(quint32 objectId, SimControlCmd cmd) +XNModelManagerPtr XNFramework::GetModelManager() { - emit SimControl(objectId, cmd); + T_D(); + return d->modelManager; +} + +XNServiceManagerPtr XNFramework::GetServiceManager() +{ + T_D(); + return d->serviceManager; } diff --git a/XNCore/XNFramework.h b/XNCore/XNFramework.h index 2665e62..bf31993 100755 --- a/XNCore/XNFramework.h +++ b/XNCore/XNFramework.h @@ -12,195 +12,164 @@ #include "XNObject.h" -class XNFrameworkPrivate; +struct XNFrameworkPrivate; /** * @brief 框架类 */ class XNCORE_EXPORT XNFramework : public XNObject { - /** - * @brief 宏定义,用于支持Qt的元对象系统 - */ - Q_OBJECT - /** * @brief 宏定义,用于禁用拷贝构造函数 */ - Q_DISABLE_COPY(XNFramework) + XN_METATYPE(XNFramework, XNObject) /** * @brief 宏定义,用于声明私有数据成员 */ - Q_DECLARE_PRIVATE(XNFramework); - - /** - * @brief 宏定义,用于声明属性workPath - */ - Q_PROPERTY(QString workPath READ GetWorkPath WRITE SetWorkPath) - - /** - * @brief 宏定义,用于声明属性modelPath - */ - Q_PROPERTY(QString modelPath READ GetModelPath WRITE SetModelPath) - - /** - * @brief 宏定义,用于声明属性cpuAffinity - */ - Q_PROPERTY(quint32 cpuAffinity READ GetCpuAffinity WRITE SetCpuAffinity) - + XN_DECLARE_PRIVATE(XNFramework) public: /** * @brief 构造函数 * @param parent 父对象 */ - explicit XNFramework(QObject *parent = nullptr); + XNFramework(); /** * @brief 析构函数 */ virtual ~XNFramework(); +protected: + /** + * @brief 构造函数 + * @param p 私有数据成员 + */ + XNFramework(PrivateType *p); + +public: + /** + * @brief 获取DDS管理器 + * @return DDS管理器 + */ + XNDDSManagerPtr GetDDSManager(); + + /** + * @brief 获取事件管理器 + * @return 事件管理器 + */ + XNEventManagerPtr GetEventManager(); + + /** + * @brief 获取模型管理器 + * @return 模型管理器 + */ + XNModelManagerPtr GetModelManager(); + + /** + * @brief 获取场景管理器 + * @return 场景管理器 + */ + XNScenarioManagerPtr GetScenarioManager(); + + /** + * @brief 获取服务管理器 + * @return 服务管理器 + */ + XNServiceManagerPtr GetServiceManager(); + + /** + * @brief 获取线程管理器 + * @return 线程管理器 + */ + XNThreadManagerPtr GetThreadManager(); + + /** + * @brief 获取时间管理器 + * @return 时间管理器 + */ + XNTimeManagerPtr GetTimeManager(); + /** * @brief 获取工作路径 * @return 工作路径 */ - QString GetWorkPath(); + std::string GetWorkPath(); + + /** + * @brief 设置工作路径 + * @param workPath 工作路径 + */ + void SetWorkPath(const std::string &workPath); /** * @brief 获取模型库路径 * @return 模型库路径 */ - QString GetModelPath(); + std::string GetModelPath(); + + /** + * @brief 设置模型库路径 + * @param modelPath 模型库路径 + */ + void SetModelPath(const std::string &modelPath); /** * @brief 获取服务库路径 * @return 服务库路径 */ - QString GetServicePath(); + std::string GetServicePath(); + + /** + * @brief 设置服务库路径 + * @param servicePath 服务库路径 + */ + void SetServicePath(const std::string &servicePath); /** * @brief 获取CPU亲和性 * @return CPU亲和性 */ - quint32 GetCpuAffinity(); + uint32_t GetCpuAffinity(); + + /** + * @brief 设置CPU亲和性 + * @param cpuAffinity CPU亲和性 + */ + void SetCpuAffinity(uint32_t cpuAffinity); /** * @brief 设置场景XML * @param scenarioXml 场景XML */ - void SetScenarioXml(const QString &scenarioXml); - -signals: - /** - * @brief 初始化 - */ - void Initialize(); - - /** - * @brief 初始化成功 - */ - void InitializeSuccess(bool isSuccess); + void SetScenarioXml(const std::string &scenarioXml); /** * @brief 准备执行 */ void PrepareForExecute(); - /** - * @brief 准备执行成功 - */ - void PrepareForExecuteSuccess(bool isSuccess); - /** * @brief 分析场景XML * @param scenarioXml 场景XML */ - void AnalyzeScenarioXml(const QString &scenarioXml); + void AnalyzeScenarioXml(const std::string &scenarioXml); /** * @brief 仿真控制 * @param objectId 对象ID * @param cmd 命令 */ - void SimControl(quint32 objectId, SimControlCmd cmd); - -public slots: - /** - * @brief 设置工作路径 - * @param workPath 工作路径 - */ - void SetWorkPath(const QString &workPath); - - /** - * @brief 设置模型库路径 - * @param modelPath 模型库路径 - */ - void SetModelPath(const QString &modelPath); - - /** - * @brief 设置服务库路径 - * @param servicePath 服务库路径 - */ - void SetServicePath(const QString &servicePath); - - /** - * @brief 设置CPU亲和性 - * @param cpuAffinity CPU亲和性 - */ - void SetCpuAffinity(quint32 cpuAffinity); + void SimControl(uint32_t objectId, SimControlCmd cmd); /** * @brief 初始化 */ - void OnInitialize(); - - /** - * @brief 初始化成功 - */ - void OnInitializeSuccess(); - - /** - * @brief 初始化失败 - */ - void OnInitializeFailed(); - - /** - * @brief 解析配置文件成功 - */ - void OnAnalyzeScenarioXmlSuccess(); - - /** - * @brief 解析配置文件失败 - */ - void OnAnalyzeScenarioXmlFailed(); - - /** - * @brief 准备执行 - */ - void OnPrepareForExecute(); - - /** - * @brief 准备执行成功 - */ - void OnPrepareForExecuteSuccess(); - - /** - * @brief 准备执行失败 - */ - void OnPrepareForExecuteFailed(); + void Initialize(); /** * @brief 仿真控制 * @param cmd 命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); - -protected: - /** - * @brief 构造函数 - * @param dd 私有数据成员 - * @param parent 父对象 - */ - XNFramework(XNFrameworkPrivate &dd, QObject *parent = nullptr); + void OnSimControl(uint32_t objectId, SimControlCmd cmd); }; diff --git a/XNCore/XNFramework_p.h b/XNCore/XNFramework_p.h index 89058f6..cb27a74 100755 --- a/XNCore/XNFramework_p.h +++ b/XNCore/XNFramework_p.h @@ -16,43 +16,65 @@ /** * @brief 框架类的私有数据成员 */ -class XNFrameworkPrivate : public XNObjectPrivate -{ -public: - /** - * @brief 构造函数 - * @param q 框架类指针 - */ - explicit XNFrameworkPrivate(XNFramework *q) : XNObjectPrivate(q) {} +struct XNFrameworkPrivate : public XNObjectPrivate { /** - * @brief 宏定义,用于声明公有数据成员 + * @brief DDS管理器 */ - Q_DECLARE_PUBLIC(XNFramework) + XNDDSManagerPtr ddsManager; + + /** + * @brief 事件管理器 + */ + XNEventManagerPtr eventManager; + + /** + * @brief 模型管理器 + */ + XNModelManagerPtr modelManager; + + /** + * @brief 场景管理器 + */ + XNScenarioManagerPtr scenarioManager; + + /** + * @brief 服务管理器 + */ + XNServiceManagerPtr serviceManager; + + /** + * @brief 线程管理器 + */ + XNThreadManagerPtr threadManager; + + /** + * @brief 时间管理器 + */ + XNTimeManagerPtr timeManager; -private: /** * @brief 工作路径 */ - QString workPath; + std::string workPath; /** * @brief 模型路径 */ - QString modelPath; + std::string modelPath; /** * @brief 服务路径 */ - QString servicePath; + std::string servicePath; /** * @brief CPU亲和性 */ - quint32 uCpuAffinity; + uint32_t uCpuAffinity; /** * @brief 场景XML */ - QString scenarioXml; + std::string scenarioXml; }; diff --git a/XNCore/XNLogger.cpp b/XNCore/XNLogger.cpp index 136cab7..e754652 100755 --- a/XNCore/XNLogger.cpp +++ b/XNCore/XNLogger.cpp @@ -4,39 +4,51 @@ XNLogger::XNLogger() : consoleOutputEnabled{true, true, true, true}, fileOutputEnabled{true, true, true, true} { // 获取当前工作目录 - QString currentDir = QDir::currentPath(); - QString logDirPath = currentDir + "/log"; + std::filesystem::path currentDir = std::filesystem::current_path(); + std::filesystem::path logDirPath = currentDir / "log"; // 创建 log 文件夹 - QDir logDir; - if (!logDir.exists(logDirPath)) { - logDir.mkpath(logDirPath); + if (!std::filesystem::exists(logDirPath)) { + std::filesystem::create_directories(logDirPath); } // 创建以当前日期和时间命名的日志文件 - QString logFileName = - QString("log_%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss")); - logFile.setFileName(logDirPath + "/" + logFileName); + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + std::stringstream ss; + ss << std::put_time(std::localtime(&time), "%Y%m%d_%H%M%S"); + std::string logFileName = "log_" + ss.str() + ".log"; - logFile.open(QIODevice::Append | QIODevice::Text); + logFilePath = (logDirPath / logFileName).string(); + logFile.open(logFilePath, std::ios::app); } XNLogger::~XNLogger() { - if (logFile.isOpen()) { + if (logFile.is_open()) { logFile.close(); } } -void XNLogger::log(LogLevel level, const QString &message) +std::string XNLogger::getCurrentTimeString() const { - QMutexLocker locker(&mutex); - QString logMessage = QString("[%1] [%2] %3") - .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz")) - .arg(logLevelToString(level)) - .arg(message); + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; - QString coloredMessage; + std::stringstream ss; + ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S"); + ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); + return ss.str(); +} + +void XNLogger::log(LogLevel level, const std::string &message) +{ + std::lock_guard locker(mutex); + std::string logMessage = + "[" + getCurrentTimeString() + "] [" + logLevelToString(level) + "] " + message; + + std::string coloredMessage; // 根据日志等级设置颜色 switch (level) { @@ -61,19 +73,18 @@ void XNLogger::log(LogLevel level, const QString &message) if (consoleOutputEnabled[level]) { if (level == Time) { // 如果是时间日志,则不换行,回退到该行开始 - QTextStream(stdout) << coloredMessage << "\r"; + std::cout << coloredMessage << "\r" << std::flush; } else { - QTextStream(stdout) << coloredMessage << "\n"; + std::cout << coloredMessage << std::endl; } } // 文件输出 - if (fileOutputEnabled[level] && logFile.isOpen()) { - QTextStream fileStream(&logFile); + if (fileOutputEnabled[level] && logFile.is_open()) { if (level == Time) { - fileStream << logMessage << "\r"; + logFile << logMessage << "\r" << std::flush; } else { - fileStream << logMessage << "\n"; + logFile << logMessage << std::endl; } } } @@ -88,7 +99,7 @@ void XNLogger::enableFileOutput(LogLevel level, bool enable) fileOutputEnabled[level] = enable; } -QString XNLogger::logLevelToString(LogLevel level) const +std::string XNLogger::logLevelToString(LogLevel level) const { switch (level) { case Debug: diff --git a/XNCore/XNLogger.h b/XNCore/XNLogger.h index 149bfc7..0165e28 100755 --- a/XNCore/XNLogger.h +++ b/XNCore/XNLogger.h @@ -9,13 +9,15 @@ * */ #pragma once -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include +#include +#include +#include /** * @brief 日志类 @@ -34,7 +36,6 @@ public: */ static XNLogger &instance() { - // 懒汉式单例,C++11 及以上版本的标准保证了局部静态变量的初始化是线程安全的 static XNLogger instance; return instance; } @@ -44,7 +45,7 @@ public: * @param level 日志等级 * @param message 日志消息 */ - void log(LogLevel level, const QString &message); + void log(LogLevel level, const std::string &message); /** * @brief 启用控制台输出 @@ -64,7 +65,7 @@ private: /** * @brief 构造函数 */ - XNLogger(); // 默认构造函数 + XNLogger(); /** * @brief 析构函数 @@ -74,17 +75,17 @@ private: /** * @brief 禁止拷贝构造 */ - XNLogger(const XNLogger &) = delete; // 禁止拷贝构造 + XNLogger(const XNLogger &) = delete; /** * @brief 禁止赋值 */ - XNLogger &operator=(const XNLogger &) = delete; // 禁止赋值 + XNLogger &operator=(const XNLogger &) = delete; /** * @brief 日志文件路径 */ - QString logFilePath; + std::string logFilePath; /** * @brief 控制台输出控制 @@ -99,44 +100,50 @@ private: /** * @brief 日志文件 */ - QFile logFile; + std::ofstream logFile; /** * @brief 互斥锁 */ - QMutex mutex; + std::mutex mutex; /** * @brief 日志等级转换为字符串 * @param level 日志等级 * @return 日志等级字符串 */ - QString logLevelToString(LogLevel level) const; + std::string logLevelToString(LogLevel level) const; + + /** + * @brief 获取当前时间字符串 + * @return 格式化的时间字符串 + */ + std::string getCurrentTimeString() const; /** * @brief 控制台输出字体恢复颜色常量 */ - const QString COLOR_RESET = "\033[0m"; + const std::string COLOR_RESET = "\033[0m"; /** * @brief 调试颜色常量 */ - const QString COLOR_DEBUG = "\033[34m"; // 蓝色 + const std::string COLOR_DEBUG = "\033[34m"; // 蓝色 /** * @brief 信息颜色常量 */ - const QString COLOR_INFO = "\033[32m"; // 绿色 + const std::string COLOR_INFO = "\033[32m"; // 绿色 /** * @brief 警告颜色常量 */ - const QString COLOR_WARNING = "\033[33m"; // 黄色 + const std::string COLOR_WARNING = "\033[33m"; // 黄色 /** * @brief 错误颜色常量 */ - const QString COLOR_ERROR = "\033[31m"; // 红色 + const std::string COLOR_ERROR = "\033[31m"; // 红色 }; /** @@ -154,9 +161,9 @@ public: */ template inline static typename std::enable_if<(sizeof...(Args) > 0), void>::type - log(XNLogger::LogLevel level, const QString &message, Args... args) + log(XNLogger::LogLevel level, const std::string &message, Args... args) { - QString formattedMessage = formatMessage(message, args...); + std::string formattedMessage = formatMessage(message, args...); XNLogger::instance().log(level, formattedMessage); } @@ -165,7 +172,7 @@ public: * @param level 日志等级 * @param message 日志消息 */ - inline static void log(XNLogger::LogLevel level, const QString &message) + inline static void log(XNLogger::LogLevel level, const std::string &message) { XNLogger::instance().log(level, message); } @@ -173,27 +180,44 @@ public: private: // 辅助函数,用于格式化消息 template - static QString convertToString(const T &arg) + static std::string convertToString(const T &arg) { if constexpr (std::is_arithmetic::value) { - return QString::number(arg); // 处理数值类型 + return std::to_string(arg); // 处理数值类型 } else { - return arg; + return std::string(arg); } } // 递归变参函数,用于处理多个参数 template - static QString formatMessage(const QString &message, T arg, Args... args) + static std::string formatMessage(const std::string &message, T arg, Args... args) { - return formatMessage(message.arg(convertToString(arg)), args...); // 递归调用 + // 查找下一个参数占位符 + std::string result = message; + size_t paramIndex = 0; + size_t pos = 0; + + // 找到当前参数对应的占位符 + while (true) { + std::string placeholder = "%" + std::to_string(paramIndex + 1); + pos = result.find(placeholder); + if (pos != std::string::npos) { + // 替换占位符,使用placeholder的长度 + result.replace(pos, placeholder.length(), convertToString(arg)); + break; + } + paramIndex++; + if (paramIndex > 100) { // 防止无限循环 + return result; + } + } + + return formatMessage(result, args...); } // 基础情况 - static QString formatMessage(const QString &message) - { - return message; // 处理没有参数的情况 - } + static std::string formatMessage(const std::string &message) { return message; } }; /** diff --git a/XNCore/XNModelManager.cpp b/XNCore/XNModelManager.cpp index 8f2e9d5..9596991 100755 --- a/XNCore/XNModelManager.cpp +++ b/XNCore/XNModelManager.cpp @@ -11,17 +11,15 @@ #include "XNModelManager.h" #include "XNModelManager_p.h" #include "XNModelObject.h" -#include -#include -#include +#include "XNFramework.h" +#include "XNThreadManager.h" // 构造函数 -XNModelManager::XNModelManager(QObject *parent) - : XNBaseFrameObject(*new XNModelManagerPrivate(this), parent) +XNModelManager::XNModelManager() : XNBaseFrameObject(new XNModelManagerPrivate()) { - setUniqueId(6); - setObjectName("XNModelManager"); - Q_D(XNModelManager); + SetUniqueId(6); + SetObjectName("XNModelManager"); + T_D(); d->ModelIDAssigned.resize(10000, false); } @@ -30,103 +28,93 @@ XNModelManager::~XNModelManager() { } -XNModelManager::XNModelManager(XNModelManagerPrivate &dd, QObject *parent) - : XNBaseFrameObject(dd, parent) +XNModelManager::XNModelManager(PrivateType *p) : XNBaseFrameObject(p) { - Q_D(XNModelManager); + T_D(); d->ModelIDAssigned.resize(10000, false); } // 运行前最后准备 -void XNModelManager::OnPrepareForExecute() +bool XNModelManager::PrepareForExecute() { - Q_D(XNModelManager); - emit PrepareForExecute(); + T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNModelManager is prepared!"); - emit PrepareForExecuteSuccess(); + return true; } -void XNModelManager::OnInitialize() +bool XNModelManager::Initialize() { - Q_D(XNModelManager); + T_D(); LOG_INFO("XNModelManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; - emit InitializeSuccess(); + return true; } -void XNModelManager::OnLoadModel(const QString &modelPath, const QString &className) +void XNModelManager::LoadModel(const std::string &modelPath, const std::string &className, + uint32_t initialType, uint32_t threadID) { - Q_D(XNModelManager); - QLibrary lib(modelPath); - if (lib.load()) { - typedef void (*InitialModelFunc)(); - QString initialModelName = "Initial" + className; - InitialModelFunc initialModel = - (InitialModelFunc)lib.resolve(initialModelName.toUtf8().constData()); + T_D(); + void *handle = dlopen(modelPath.c_str(), RTLD_LAZY); + if (handle) { + typedef XNModelObjectPtr (*InitialModelFunc)(); + std::string initialModelName = "Initial" + className; + InitialModelFunc initialModel = (InitialModelFunc)dlsym(handle, initialModelName.c_str()); if (initialModel) { - initialModel(); - QMetaType metaType = QMetaType::fromName(className.toUtf8().constData()); - if (metaType.isValid()) { - QObject *obj = static_cast(metaType.create()); - if (obj) { - XNModelObject *model = qobject_cast(obj); - if (model) { - quint32 modelID = RegisterModel(); - if (modelID == 0) { - LOG_WARNING("0x2174 Assign Model ID Failed, Model ID is used up!"); - delete obj; - return; - } - model->setParent(this); - model->setObjectName(className); - model->setUniqueId(modelID); - model->SetBaseFreq(d->dBaseFreq); - QString configFilePath = - QFileInfo(modelPath).absolutePath() + "/" + className + ".mcfg"; - model->SetXmlPath(configFilePath); - connect(model, &XNModelObject::RegisterFunction, this, - &XNModelManager::OnRegisterFunction); - connect(this, &XNModelManager::PrepareForExecute, model, - &XNModelObject::OnPrepareForExecute); - model->OnInitialize(); - } else { - LOG_WARNING("0x2175 Model %1 Instantiation Failed, Not a subclass of " - "XNModelObject!", - className); - delete obj; - return; - } - } else { - LOG_WARNING("0x2176 Model %1 Instantiation Failed, Not a subclass of QObject!", - className); - delete obj; + XNModelObjectPtr model = initialModel(); + if (model) { + uint32_t modelID = RegisterModel(); + if (modelID == 0) { + LOG_WARNING("0x2174 Assign Model ID Failed, Model ID is used up!"); + dlclose(handle); return; } + model->SetUniqueId(modelID); + model->SetObjectName(className); + model->SetFramework(GetFramework()); + + // 使用std::filesystem处理路径 + std::filesystem::path configPath = + std::filesystem::path(modelPath).parent_path() / (className + ".mcfg"); + model->SetXmlPath(configPath.string()); + + // 注册模型到管理器 + d->ModelMap[modelID] = model; + + // 初始化模型 + model->Initialize(initialType, threadID); + + // 注册到线程管理器 + if (threadID != 0) { + auto framework = GetFramework(); + if (framework) { + framework->GetThreadManager()->RegisterFunction( + modelID, std::bind(&XNModelObject::StepUpdate, model.get()), threadID, + 0, 0, 0); + } + } } else { - LOG_WARNING("0x2173 Model %1 Not found in dynamic link library %2!", className, - modelPath); + LOG_WARNING("0x2173 Model %s Not found in dynamic link library %s!", + className.c_str(), modelPath.c_str()); + dlclose(handle); + return; } } else { - LOG_WARNING("0x2177 InitialModel function not found in dynamic link library %2!", - modelPath); + LOG_WARNING("0x2177 InitialModel function not found in dynamic link library %s!", + modelPath.c_str()); + dlclose(handle); + return; } } else { - LOG_WARNING("0x2172 Model %1 Dynamic link library loading failed! Error: %2", className, - lib.errorString()); + LOG_WARNING("0x2172 Model %s Dynamic link library loading failed! Error: %s", + className.c_str(), dlerror()); } } -void XNModelManager::OnSetBaseFreq(const double &dBaseFreq) -{ - Q_D(XNModelManager); - d->dBaseFreq = dBaseFreq; -} - // 模型注册 -quint32 XNModelManager::RegisterModel() +uint32_t XNModelManager::RegisterModel() { - Q_D(XNModelManager); + T_D(); // 从10000~19999的编号中分配ID for (int i = 0; i < 10000; i++) { if (d->ModelIDAssigned[i]) @@ -140,29 +128,32 @@ quint32 XNModelManager::RegisterModel() } // 获取模型指针 -XNModelObject *XNModelManager::GetModel(quint32 modelID) +XNModelObjectPtr XNModelManager::GetModel(uint32_t modelID) { - Q_D(XNModelManager); + T_D(); if (d->ModelIDAssigned[modelID - 10000]) { - QList modelList = findChildren(); - for (auto &model : modelList) { - if (model->getUniqueId() == modelID) - return model; + auto model = d->ModelMap.find(modelID); + if (model != d->ModelMap.end()) { + return model->second; } return nullptr; } else return nullptr; } -void XNModelManager::OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, - quint32 RunPos, quint32 RunPriorty) +void XNModelManager::RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, + uint32_t freqGroup, uint32_t RunPos, uint32_t RunPriorty) { - Q_D(XNModelManager); + T_D(); if (d->ModelIDAssigned[id - 10000]) { - emit RegisterFunction(id, fun, freqGroup, RunPos, RunPriorty); + auto framework = GetFramework(); + if (framework) { + framework->GetThreadManager()->RegisterFunction(id, fun, threadID, freqGroup, RunPos, + RunPriorty); + } } else { LOG_WARNING( "0x2177 Submission of periodic function was rejected, model ID %1 is not registered!", id); } -} +} \ No newline at end of file diff --git a/XNCore/XNModelManager.h b/XNCore/XNModelManager.h index bcbd0f4..4c030b6 100755 --- a/XNCore/XNModelManager.h +++ b/XNCore/XNModelManager.h @@ -12,7 +12,9 @@ #include "XNBaseFrameObject.h" class XNModelObject; -class XNModelManagerPrivate; +XNCLASS_PTR_DECLARE(XNModelObject) + +struct XNModelManagerPrivate; /** * @brief 模型管理器类 @@ -20,18 +22,14 @@ class XNModelManagerPrivate; */ class XNModelManager : public XNBaseFrameObject { - /** - * @brief 使用禁止复制类宏定义自身禁止复制 - */ - Q_OBJECT - Q_DECLARE_PRIVATE(XNModelManager) - Q_DISABLE_COPY(XNModelManager) + XN_METATYPE(XNModelManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNModelManager) public: /** * @brief 模型管理器类默认构造函数 */ - explicit XNModelManager(QObject *parent = nullptr); + XNModelManager(); /** * @brief 模型管理器类默认析构函数 @@ -44,20 +42,20 @@ protected: * @param p:私有结构体指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNModelManager(XNModelManagerPrivate &dd, QObject *parent = nullptr); + XNModelManager(PrivateType *p); -public slots: +public: /** * @brief 系统开始运行前的最后准备工作 * @details 系统运行前模型管理器做最后处理的接口 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 初始化模型管理器 * @details 模型管理器的初始化接口 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 加载模型 @@ -65,31 +63,23 @@ public slots: * @param className: QString类型,模型类名 * @details 加载模型 */ - void OnLoadModel(const QString &modelPath, const QString &className); + void LoadModel(const std::string &modelPath, const std::string &className, uint32_t initialType, + uint32_t threadID); - /** - * @brief 设置仿真系统运行基频 - * @param dBaseFreq: double类型,频率值,单位Hz - * @details 仿真系统所有线程以此基频的 1 或 1/2 或 1/4 或 1/8 或 1/16 或 1/32 倍运行 - */ - void OnSetBaseFreq(const double &dBaseFreq); - -public: /** * @brief 注册模型信息 * @return UINT32: 模型的全局唯一ID * @details 模型通过此接口注册自身,并获取自身全局唯一ID */ - quint32 RegisterModel(); + uint32_t RegisterModel(); /** * @brief 获取模型指针 * @param modelID: UINT32类型,模型全局唯一ID * @return XNModelObjectPtr: 模型基类指针 */ - XNModelObject *GetModel(quint32 modelID); + XNModelObjectPtr GetModel(uint32_t modelID); -public slots: /** * @brief 注册模型函数 * @param ModelID: UINT32类型,模型全局唯一ID @@ -98,22 +88,6 @@ public slots: * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) * @param RunPriorty: UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 */ - void OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); - -signals: - /** - * @brief 注册函数信号 - * @param id: UINT32类型,模型全局唯一ID - * @param fun: 函数指针 - * @param freqGroup: UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 - * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) - * @param RunPriorty: UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 - */ - void RegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); - - void InitializeSuccess(); - - void PrepareForExecuteSuccess(); + void RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, uint32_t freqGroup, + uint32_t RunPos, uint32_t RunPriorty); }; \ No newline at end of file diff --git a/XNCore/XNModelManager_p.h b/XNCore/XNModelManager_p.h index b7f04d6..ea7b447 100755 --- a/XNCore/XNModelManager_p.h +++ b/XNCore/XNModelManager_p.h @@ -1,25 +1,17 @@ #pragma once #include "XNBaseFrameObject_p.h" -#include -#include - -class XNModelManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNModelManager) - - explicit XNModelManagerPrivate(XNModelManager *q) : XNBaseFrameObjectPrivate(q) {} +struct XNModelManagerPrivate : public XNBaseFrameObjectPrivate { + XNFrameworkPtr framework; /** * @brief 模型ID库 * @details 所有模型已用ID的存储库 */ - QVector ModelIDAssigned; - + std::vector ModelIDAssigned; /** - * @brief 仿真系统运行基频 - * @details 仿真系统所有线程以此基频的 1 或 1/2 或 1/4 或 1/8 或 1/16 或 1/32 倍运行 + * @brief 模型ID与模型指针的映射表 + * @details 所有模型ID与模型指针的映射表 */ - double dBaseFreq; + std::map ModelMap; }; diff --git a/XNCore/XNModelObject.cpp b/XNCore/XNModelObject.cpp index cab5194..74831ba 100755 --- a/XNCore/XNModelObject.cpp +++ b/XNCore/XNModelObject.cpp @@ -15,10 +15,9 @@ #include "XNModelManager.h" #include "XNDDSManager.h" #include "XNIDL/XNSimStatusPubSubTypes.hpp" -#include // 默认构造函数 -XNModelObject::XNModelObject(QObject *parent) : XNObject(*new XNModelObjectPrivate(this), parent) +XNModelObject::XNModelObject() : XNObject(new XNModelObjectPrivate()) { } @@ -27,184 +26,209 @@ XNModelObject::~XNModelObject() { } -XNModelObject::XNModelObject(XNModelObjectPrivate &dd, QObject *parent) : XNObject(dd, parent) +XNModelObject::XNModelObject(PrivateType *p) : XNObject(p) { } // 获取模型描述 -const QString &XNModelObject::GetDescription() +const std::string &XNModelObject::GetDescription() { - Q_D(XNModelObject); + T_D(); return d->_sDescription; } // 设置模型描述 -void XNModelObject::SetDescription(const QString &sDescription) +void XNModelObject::SetDescription(const std::string &sDescription) { - Q_D(XNModelObject); + T_D(); d->_sDescription = sDescription; } // 获取作者 -const QString &XNModelObject::GetAuthor() +const std::string &XNModelObject::GetAuthor() { - Q_D(XNModelObject); + T_D(); return d->_sAuthor; } // 设置作者 -void XNModelObject::SetAuthor(const QString &sAuthor) +void XNModelObject::SetAuthor(const std::string &sAuthor) { - Q_D(XNModelObject); + T_D(); d->_sAuthor = sAuthor; } // 获取模型配置文件路径 -const QString &XNModelObject::GetXmlPath() +const std::string &XNModelObject::GetXmlPath() { - Q_D(XNModelObject); + T_D(); return d->_sXmlPath; } // 设置模型配置文件路径 -void XNModelObject::SetXmlPath(const QString &sXmlPath) +void XNModelObject::SetXmlPath(const std::string &sXmlPath) { - Q_D(XNModelObject); + T_D(); d->_sXmlPath = sXmlPath; } // 获取模型创建时间 -const QDateTime &XNModelObject::GetCreateTime() +const XNTimePoint &XNModelObject::GetCreateTime() { - Q_D(XNModelObject); + T_D(); return d->_cCreatTime; } // 设置模型创建时间 -void XNModelObject::SetCreateTime(const QDateTime &cTime) +void XNModelObject::SetCreateTime(const XNTimePoint &cTime) { - Q_D(XNModelObject); + T_D(); d->_cCreatTime = cTime; } // 获取模型修改时间 -const QDateTime &XNModelObject::GetChangeTime() +const XNTimePoint &XNModelObject::GetChangeTime() { - Q_D(XNModelObject); + T_D(); return d->_cChangeTime; } // 设置模型修改时间 -void XNModelObject::SetChangeTime(const QDateTime &cTime) +void XNModelObject::SetChangeTime(const XNTimePoint &cTime) { - Q_D(XNModelObject); + T_D(); d->_cChangeTime = cTime; } // 获取模型版本号 -const QString &XNModelObject::GetVersion() +const std::string &XNModelObject::GetVersion() { - Q_D(XNModelObject); + T_D(); return d->_sVersion; } // 设置模型版本号 -void XNModelObject::SetVersion(const QString &sVersion) +void XNModelObject::SetVersion(const std::string &sVersion) { - Q_D(XNModelObject); + T_D(); d->_sVersion = sVersion; } -void XNModelObject::SetBaseFreq(const double &dBaseFreq) -{ - Q_D(XNModelObject); - d->_setFreq = dBaseFreq; -} - // 初始化函数 -void XNModelObject::OnInitialize() +void XNModelObject::Initialize(uint32_t initialType, uint32_t threadID) { // 先尝试调取动态库 - Q_D(XNModelObject); - // 读取配置文件,设置循环执行函数 - QFile file(GetXmlPath()); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LOG_WARNING("0x2161 Failed to open the model configuration file: %1!", GetXmlPath()); - return; - } - QDomDocument doc; - doc.setContent(&file); - QDomElement rootNode = doc.documentElement(); - // 读取配置文件的模型参数 - QString modelName = rootNode.firstChildElement("Name").text(); - if (modelName != objectName()) { - LOG_WARNING("0x2162 The model name in the configuration file of model %1 is not consistent " - "with the model name in the configuration file of model %2!", - objectName(), modelName); - return; - } - d->_sDescription = rootNode.firstChildElement("Description").text(); - d->_sAuthor = rootNode.firstChildElement("Author").text(); - d->_sVersion = rootNode.firstChildElement("Version").text(); - d->_cCreatTime = - QDateTime::fromString(rootNode.firstChildElement("CreateTime").text(), Qt::ISODate); - d->_cChangeTime = - QDateTime::fromString(rootNode.firstChildElement("ChangeTime").text(), Qt::ISODate); - QString funcNode = rootNode.firstChildElement("Node").text(); - d->_runPriority = rootNode.firstChildElement("Priority").text().toInt(); - // 检查运行节点是否是 "x-x" 形式 - quint32 tmp = funcNode.indexOf('-'); - if (tmp <= 0) { - LOG_WARNING("0x2162 The value of the run node attribute in the configuration file of model " - "%1 is not in the x-x format, registration not executed!", - objectName()); - } - d->_runFreq = funcNode.left(tmp).toInt(); - d->_setFreq = d->_setFreq / pow(2.0, d->_runFreq); - d->_runNode = funcNode.right(funcNode.length() - tmp - 1).toInt(); - // 注册周期性函数 - emit RegisterFunction(getUniqueId(), std::bind(&XNModelObject::StepUpdate, this), d->_runFreq, - d->_runNode, d->_runPriority); - // 加载动态库 - QString mathlib = rootNode.firstChildElement("MathLib").text(); - if (mathlib.size() != 0) { - d->_sLibPath = QFileInfo(GetXmlPath()).absolutePath() + "/" + mathlib; - d->_dynamicLib = new QLibrary(d->_sLibPath); - if (d->_dynamicLib->load()) { // 动态库加载成功 - LOG_INFO("0x2163 Model %1 loaded algorithm dynamic library %2 successfully!", - objectName(), d->_sLibPath); - } else { - LOG_WARNING( - "0x2160 Model %1 failed to find algorithm dynamic library %2, will not call " - "algorithm!", - objectName(), d->_sLibPath); - delete d->_dynamicLib; - d->_dynamicLib = nullptr; + T_D(); + if (initialType == 0) { + // 读取配置文件,设置循环执行函数 + std::ifstream file(GetXmlPath()); + if (!file.is_open()) { + LOG_WARNING("0x2161 Failed to open the model configuration file: %1!", GetXmlPath()); + return; + } + tinyxml2::XMLDocument doc; + doc.LoadFile(GetXmlPath().c_str()); + tinyxml2::XMLElement *rootNode = doc.FirstChildElement("Model"); + if (!rootNode) { + LOG_WARNING("0x2161 Failed to parse model configuration file: %1!", GetXmlPath()); + return; + } + // 读取配置文件的模型参数 + const char *modelName = rootNode->FirstChildElement("Name")->GetText(); + if (!modelName || std::string(modelName) != GetObjectName()) { + LOG_WARNING( + "0x2162 The model name in the configuration file of model %1 is not consistent " + "with the model name in the configuration file of model %2!", + GetObjectName(), modelName ? modelName : "null"); + return; + } + d->_sDescription = rootNode->FirstChildElement("Description")->GetText(); + d->_sAuthor = rootNode->FirstChildElement("Author")->GetText(); + d->_sVersion = rootNode->FirstChildElement("Version")->GetText(); + + // 使用标准C++时间处理 + std::string createTimeStr = rootNode->FirstChildElement("CreateTime")->GetText(); + std::string changeTimeStr = rootNode->FirstChildElement("ChangeTime")->GetText(); + d->_cCreatTime = parseISOTime(createTimeStr); + d->_cChangeTime = parseISOTime(changeTimeStr); + + std::string funcNode = rootNode->FirstChildElement("Node")->GetText(); + d->_runPriority = std::stoi(rootNode->FirstChildElement("Priority")->GetText()); + + // 检查运行节点是否是 "x-x" 形式 + size_t tmp = funcNode.find('-'); + if (tmp == std::string::npos || tmp == 0) { + LOG_WARNING( + "0x2162 The value of the run node attribute in the configuration file of model " + "%1 is not in the x-x format, registration not executed!", + GetObjectName()); + return; + } + + // 使用标准C++字符串处理 + d->_runFreq = std::stoi(funcNode.substr(0, tmp)); + d->_setFreq = d->_setFreq / std::pow(2.0, d->_runFreq); + d->_runNode = std::stoi(funcNode.substr(tmp + 1)); + + // 注册周期性函数 + auto framework = GetFramework(); + if (framework) { + auto threadManager = framework->GetThreadManager(); + if (threadManager) { + threadManager->RegisterFunction( + GetUniqueId(), std::bind(&XNModelObject::StepUpdate, this), threadID, + d->_runFreq, d->_runNode, d->_runPriority); + } + } + + // 加载动态库 + const char *mathlib = rootNode->FirstChildElement("MathLib")->GetText(); + if (mathlib && strlen(mathlib) > 0) { + // 使用标准C++文件路径处理 + std::filesystem::path xmlPath(GetXmlPath()); + d->_sLibPath = xmlPath.parent_path().string() + "/" + mathlib; + + // 使用标准C++动态库加载 + d->_dynamicLib = dlopen(d->_sLibPath.c_str(), RTLD_LAZY); + if (d->_dynamicLib) { // 动态库加载成功 + LOG_INFO("0x2163 Model %1 loaded algorithm dynamic library %2 successfully!", + GetObjectName(), d->_sLibPath); + } else { + LOG_WARNING( + "0x2160 Model %1 failed to find algorithm dynamic library %2, will not call " + "algorithm!", + GetObjectName(), d->_sLibPath); + d->_dynamicLib = nullptr; + } + } + + // 处理指令列表 + tinyxml2::XMLElement *nodeCmds = rootNode->FirstChildElement("CommandList"); + if (nodeCmds) { + for (tinyxml2::XMLElement *nodeCmd = nodeCmds->FirstChildElement("Command"); + nodeCmd != nullptr; nodeCmd = nodeCmd->NextSiblingElement("Command")) { + const char *cmdName = nodeCmd->Attribute("Name"); + const char *cmdDescription = nodeCmd->Attribute("Description"); + const char *cmdCall = nodeCmd->Attribute("Call"); + // TODO: 处理命令列表 + } } - } - // TODO 指令列表 - QDomElement nodeCmds = rootNode.firstChildElement("CommandList"); - for (QDomElement nodeCmd = nodeCmds.firstChildElement("Command"); !nodeCmd.isNull(); - nodeCmd = nodeCmd.nextSiblingElement("Command")) { - QString cmdName = nodeCmd.attribute("Name"); - QString cmdDescription = nodeCmd.attribute("Description"); - QString cmdCall = nodeCmd.attribute("Call"); } } // 单步执行函数 void XNModelObject::StepUpdate() { - Q_D(XNModelObject); - quint32 setFreq = d->_setFreq < 1.0 ? 1 : (quint32)d->_setFreq; - if (d->_dataWriters.contains("XNSim::XNSimStatus::XNModelStatus") + T_D(); + uint32_t setFreq = d->_setFreq < 1.0 ? 1 : (uint32_t)d->_setFreq; + if (d->_dataWriters.find("XNSim::XNSimStatus::XNModelStatus") != d->_dataWriters.end() && d->_dataWriters["XNSim::XNSimStatus::XNModelStatus"] != nullptr && d->_runCnt > 0 && d->_runCnt % setFreq == 0) { XNSim::XNSimStatus::XNModelStatus modelStatus; - modelStatus.XNModelName(objectName().toStdString()); - modelStatus.XNModelID(getUniqueId()); + modelStatus.XNModelName(GetObjectName()); + modelStatus.XNModelID(GetUniqueId()); modelStatus.XNModelSt(1); - modelStatus.XNModelThID(pthread_self()); + modelStatus.XNModelThID(d->_threadID); modelStatus.XNModelNode(d->_runNode); modelStatus.XNModelPro(d->_runPriority); modelStatus.XNModelRunCnt(d->_runCnt); @@ -216,15 +240,15 @@ void XNModelObject::StepUpdate() modelStatus.XNMdlSetFreq(d->_setFreq); d->_dataWriters["XNSim::XNSimStatus::XNModelStatus"]->write(&modelStatus); d->_lastRunTime = now; - LOG_DEBUG("Model: %1 Write DDS!", objectName()); + LOG_DEBUG("Model: %1 Write DDS!", GetObjectName()); } d->_runCnt++; } // 运行前最后准备函数 -void XNModelObject::OnPrepareForExecute() +void XNModelObject::PrepareForExecute() { - Q_D(XNModelObject); + T_D(); d->_runCnt = 0; // 注册DDS RegisterDDSParticipant(); @@ -233,49 +257,53 @@ void XNModelObject::OnPrepareForExecute() void XNModelObject::RegisterDDSParticipant() { - Q_D(XNModelObject); - XNModelManager *modelManager = qobject_cast(parent()); - if (modelManager == nullptr) + T_D(); + auto framework = GetFramework(); + if (framework == nullptr) { + LOG_WARNING("Failed to get Framework!"); return; - XNDDSManager *ddsManager = modelManager->parent()->findChild(); - if (ddsManager == nullptr) + } + auto ddsManager = framework->GetDDSManager(); + if (ddsManager == nullptr) { + LOG_WARNING("Failed to get DDSManager!"); return; - quint32 MyID = getUniqueId(); + } + uint32_t MyID = GetUniqueId(); XN_PUBLISHTOPIC(XNSim::XNSimStatus::XNModelStatus); } -int XNModelObject::RegisterEventHandler(const QString &eventName, - std::function callback, bool async, +int XNModelObject::RegisterEventHandler(const std::string &eventName, + std::function callback, bool async, XNEvent::Priority priority) { // 获取事件管理器 - XNModelManager *modelManager = qobject_cast(parent()); - if (modelManager == nullptr) { - LOG_WARNING("Failed to get ModelManager!"); + auto framework = GetFramework(); + if (framework == nullptr) { + LOG_WARNING("Failed to get Framework!"); return -1; } - XNEventManager *eventManager = modelManager->parent()->findChild(); + XNEventManagerPtr eventManager = framework->GetEventManager(); if (eventManager == nullptr) { LOG_WARNING("Failed to get EventManager!"); return -1; } // 注册事件处理器 - return eventManager->RegisterEventHandler(eventName, callback, getUniqueId(), async, priority); + return eventManager->RegisterEventHandler(eventName, callback, GetUniqueId(), async, priority); } -void XNModelObject::TriggerEvent(const QString &eventName, const QVariant &eventData, +void XNModelObject::TriggerEvent(const std::string &eventName, const std::any &eventData, bool forceAsync, XNEvent::Priority priority) { // 获取事件管理器 - XNModelManager *modelManager = qobject_cast(parent()); - if (modelManager == nullptr) { - LOG_WARNING("Failed to get ModelManager!"); + auto framework = GetFramework(); + if (framework == nullptr) { + LOG_WARNING("Failed to get Framework!"); return; } - XNEventManager *eventManager = modelManager->parent()->findChild(); + XNEventManagerPtr eventManager = framework->GetEventManager(); if (eventManager == nullptr) { LOG_WARNING("Failed to get EventManager!"); return; diff --git a/XNCore/XNModelObject.h b/XNCore/XNModelObject.h index 9d988eb..eb1a203 100755 --- a/XNCore/XNModelObject.h +++ b/XNCore/XNModelObject.h @@ -12,7 +12,7 @@ #include "XNObject.h" #include "XNEventManager.h" -class XNModelObjectPrivate; +struct XNModelObjectPrivate; /** * @brief 模型基类 @@ -20,22 +20,14 @@ class XNModelObjectPrivate; */ class XNModelObject : public XNObject { - Q_OBJECT - Q_DISABLE_COPY(XNModelObject) - Q_DECLARE_PRIVATE(XNModelObject) - - Q_PROPERTY(QString description READ GetDescription WRITE SetDescription) - Q_PROPERTY(QString author READ GetAuthor WRITE SetAuthor) - Q_PROPERTY(QString xmlPath READ GetXmlPath WRITE SetXmlPath) - Q_PROPERTY(QDateTime createTime READ GetCreateTime WRITE SetCreateTime) - Q_PROPERTY(QDateTime changeTime READ GetChangeTime WRITE SetChangeTime) - Q_PROPERTY(QString version READ GetVersion WRITE SetVersion) + XN_METATYPE(XNModelObject, XNObject) + XN_DECLARE_PRIVATE(XNModelObject) public: /** * @brief 模型基类默认构造函数 */ - XNModelObject(QObject *parent = nullptr); + XNModelObject(); /** * @brief 模型基类默认析构函数 @@ -45,89 +37,89 @@ public: protected: /** * @brief 模型基类带参构造函数 - * @param dd:XNModelObjectPrivate类型,私有结构体指针 - * @param parent:QObject类型,父对象指针 + * @param p:XNModelObjectPrivate类型,私有结构体指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNModelObject(XNModelObjectPrivate &dd, QObject *parent = nullptr); + XNModelObject(PrivateType *p); + +public: + void SetFramework(XNFrameworkPtr framework); + +protected: + XNFrameworkPtr GetFramework() const; public: /** * @brief 获取模型描述 * @return const QString&:模型描述 */ - const QString &GetDescription(); + const std::string &GetDescription(); /** * @brief 设置模型描述 * @param sDescription:QString类型,模型描述 */ - void SetDescription(const QString &sDescription); + void SetDescription(const std::string &sDescription); /** * @brief 获取作者 * @return const QString&: 作者 */ - const QString &GetAuthor(); + const std::string &GetAuthor(); /** * @brief 设置作者 * @param sAuthor: QString类型,作者 */ - void SetAuthor(const QString &sAuthor); + void SetAuthor(const std::string &sAuthor); /** * @brief 获取模型配置文件路径 * @return const QString&: 模型配置文件路径 */ - const QString &GetXmlPath(); + const std::string &GetXmlPath(); /** * @brief 设置模型配置文件路径 * @param sXmlPath:QString类型,模型配置文件路径 */ - void SetXmlPath(const QString &sXmlPath); + void SetXmlPath(const std::string &sXmlPath); /** * @brief 获取模型创建时间 - * @return const QDateTime&:模型创建时间 + * @return const XNTimePoint&:模型创建时间 */ - const QDateTime &GetCreateTime(); + const XNTimePoint &GetCreateTime(); /** * @brief 设置模型创建时间 - * @param cTime: QDateTime类型,模型创建时间 + * @param cTime: XNTimePoint类型,模型创建时间 */ - void SetCreateTime(const QDateTime &cTime); + void SetCreateTime(const XNTimePoint &cTime); /** * @brief 获取模型修改时间 - * @return const QDateTime&:模型修改时间 + * @return const XNTimePoint&:模型修改时间 */ - const QDateTime &GetChangeTime(); + const XNTimePoint &GetChangeTime(); /** * @brief 设置模型修改时间 - * @param cTime: QDateTime类型,模型修改时间 + * @param cTime: XNTimePoint类型,模型修改时间 */ - void SetChangeTime(const QDateTime &cTime); + void SetChangeTime(const XNTimePoint &cTime); /** * @brief 获取模型版本号 * @return const XNString&: 模型版本号 */ - const QString &GetVersion(); - /** - * @brief 设置模型版本号 - * @param sVersion: QString类型,模型版本号 - */ - void SetVersion(const QString &sVersion); + const std::string &GetVersion(); /** - * @brief 设置仿真系统运行基频 - * @param dBaseFreq: double类型,频率值,单位Hz + * @brief 设置模型版本号 + * @param sVersion: std::string类型,模型版本号 */ - void SetBaseFreq(const double &dBaseFreq); + void SetVersion(const std::string &sVersion); /** * @brief 单步执行函数 @@ -142,8 +134,8 @@ public: * @param async: 是否异步处理 * @return: 返回处理器ID,失败返回-1 */ - int RegisterEventHandler(const QString &eventName, - std::function callback, bool async = false, + int RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + bool async = false, XNEvent::Priority priority = XNEvent::Priority::Normal); /** @@ -152,7 +144,7 @@ public: * @param eventData: 事件携带的数据 * @param forceAsync: 强制异步处理 */ - void TriggerEvent(const QString &eventName, const QVariant &eventData = QVariant(), + void TriggerEvent(const std::string &eventName, const std::any &eventData = std::any(), bool forceAsync = false, XNEvent::Priority priority = XNEvent::Priority::Normal); @@ -162,8 +154,7 @@ public: * @param callback: 事件处理回调函数 * @return: 返回处理器ID,失败返回-1 */ - int RegisterRTEventHandler(const QString &eventName, - std::function callback) + int RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback) { return RegisterEventHandler(eventName, callback, true, XNEvent::Priority::RealTime); } @@ -173,37 +164,23 @@ public: * @param eventName: 要触发的事件名称 * @param eventData: 事件携带的数据 */ - void TriggerRTEvent(const QString &eventName, const QVariant &eventData = QVariant()) + void TriggerRTEvent(const std::string &eventName, const std::any &eventData = std::any()) { TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); } -signals: - /** - * @brief 注册周期性执行的函数 - * @param id: quint32类型,模型ID - * @param fun: QFunctionPointer类型,需要提交的函数的包装 - * @param freqGroup:UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 - * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) - * @param RunPriorty:INT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 - * @details 向线程管理器添加要周期性执行的函数 - */ - void RegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); - -public slots: /** * @brief 初始化函数 * @details * 模型的初始化函数接口,子类继承时要调用父类初始化接口,或在此函数中使用AddMyFunction方法注册需要被线程调用的函数 */ - virtual void OnInitialize(); + virtual void Initialize(uint32_t initialType, uint32_t threadID); /** * @brief 仿真系统运行前做最后处理 * @details 系统运行前模型做最后处理的接口 */ - virtual void OnPrepareForExecute(); + virtual void PrepareForExecute(); public: virtual void RegisterDDSParticipant(); @@ -218,11 +195,11 @@ public: { \ XNModelObject::RegisterDDSParticipant(); \ Q_D(class); \ - XNModelManager *modelManager = qobject_cast(parent()); \ - if (modelManager == nullptr) \ + auto framework = GetFramework(); \ + if (!framework) \ return; \ - XNDDSManager *ddsManager = modelManager->parent()->findChild(); \ - if (ddsManager == nullptr) \ + XNDDSManagerPtr ddsManager = framework->GetDDSManager(); \ + if (!ddsManager) \ return; \ quint32 MyID = getUniqueId(); @@ -233,4 +210,11 @@ public: ddsManager->RegisterSubscriber( \ #topic, MyID, std::bind(fun, this, std::placeholders::_1)); -#define XN_REGISTER_PARTICIPANT_END(class) } \ No newline at end of file +#define XN_REGISTER_PARTICIPANT_END(class) } + +#define XN_MODEL_INITIALIZE(ClassName) \ + extern "C" XNModelObjectPtr Initial##ClassName() \ + { \ + ClassNamePtr obj = std::make_shared(); \ + return obj; \ + } diff --git a/XNCore/XNModelObject_p.h b/XNCore/XNModelObject_p.h index e562d83..6374413 100755 --- a/XNCore/XNModelObject_p.h +++ b/XNCore/XNModelObject_p.h @@ -10,62 +10,49 @@ */ #pragma once #include "XNObject_p.h" -#include -#include -#include -#include /** * @brief 模型基类私有结构体 */ -class XNModelObjectPrivate : public XNObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNModelObject) - - /** - * @brief 构造函数 - * @param q 模型基类指针 - */ - explicit XNModelObjectPrivate(XNModelObject *q) : XNObjectPrivate(q) {} - +struct XNModelObjectPrivate : public XNObjectPrivate { + XNFrameworkPtr _framework; /** * @brief 模型描述 */ - QString _sDescription; + std::string _sDescription; /** * @brief 模型作者 */ - QString _sAuthor; + std::string _sAuthor; /** * @brief 模型配置文件路径 */ - QString _sXmlPath; + std::string _sXmlPath; /** * @brief 数据包模型动态库路径 */ - QString _sLibPath; + std::string _sLibPath; /** * @brief 模型创建时间 */ - QDateTime _cCreatTime; + XNTimePoint _cCreatTime; /** * @brief 模型修改时间 */ - QDateTime _cChangeTime; + XNTimePoint _cChangeTime; /** * @brief 模型版本号 */ - QString _sVersion; + std::string _sVersion; /** * @brief 数据包模型动态库句柄 */ - QLibrary *_dynamicLib = nullptr; + void *_dynamicLib = nullptr; /** * @brief 发布者信息 */ - QHash _dataWriters; + std::unordered_map _dataWriters; /** * @brief 模型运行时间 @@ -75,25 +62,30 @@ public: /** * @brief 模型运行次数 */ - quint64 _runCnt; + uint64_t _runCnt; /** * @brief 模型运行频率 */ - quint32 _runFreq; + uint32_t _runFreq; /** * @brief 模型运行节点 */ - quint32 _runNode; + uint32_t _runNode; /** * @brief 模型运行优先级 */ - quint32 _runPriority; + uint32_t _runPriority; /** * @brief 模型设置频率 */ double _setFreq; + + /** + * @brief 模型线程ID + */ + uint32_t _threadID; }; diff --git a/XNCore/XNObject.cpp b/XNCore/XNObject.cpp index ceb7914..6caacfa 100755 --- a/XNCore/XNObject.cpp +++ b/XNCore/XNObject.cpp @@ -1,28 +1,45 @@ #include "XNObject.h" #include "XNObject_p.h" -XNObject::XNObject(QObject *parent) : QObject(parent), d_ptr(new XNObjectPrivate(this)) +XNObject::XNObject() : _Private_Ptr(new XNObjectPrivate()) { + _Private_Ptr->_Public_Ptr = this; } -XNObject::XNObject(XNObjectPrivate &dd, QObject *parent) : QObject(parent), d_ptr(&dd) +XNObject::XNObject(PrivateType *p) : _Private_Ptr(p) { + _Private_Ptr->_Public_Ptr = this; } XNObject::~XNObject() { - Q_D(XNObject); - delete d; + if (_Private_Ptr) { + delete _Private_Ptr; + } + _Private_Ptr = nullptr; } -quint32 XNObject::getUniqueId() +XNObjectPrivate::~XNObjectPrivate() { - Q_D(XNObject); - return d->uUniqueID; + _Public_Ptr = nullptr; } -void XNObject::setUniqueId(const quint32 &uniqueId) +uint32_t XNObject::GetUniqueId() { - Q_D(XNObject); - d->uUniqueID = uniqueId; + return _Private_Ptr->uUniqueID; +} + +void XNObject::SetUniqueId(const uint32_t &uniqueId) +{ + _Private_Ptr->uUniqueID = uniqueId; +} + +const std::string &XNObject::GetObjectName() +{ + return _Private_Ptr->sObjectName; +} + +void XNObject::SetObjectName(const std::string &name) +{ + _Private_Ptr->sObjectName = name; } diff --git a/XNCore/XNObject.h b/XNCore/XNObject.h index d34afe8..5c29f1d 100755 --- a/XNCore/XNObject.h +++ b/XNCore/XNObject.h @@ -10,75 +10,83 @@ */ #pragma once -#include -#include -#include - #include "XNCore_global.h" #include "XNLogger.h" -class XNObjectPrivate; +struct XNObjectPrivate; /** * @brief 基础对象类 */ -class XNCORE_EXPORT XNObject : public QObject +class XNCORE_EXPORT XNObject : public std::enable_shared_from_this { + XN_METATYPE_P(XNObject) + XN_NOCOPYABLE(XNObject) +protected: + using PrivateType = XNObjectPrivate; /** - * @brief 宏定义,用于支持Qt的元对象系统 + * @brief 私有数据成员 */ - Q_OBJECT - - /** - * @brief 宏定义,用于禁用拷贝构造函数 - */ - Q_DISABLE_COPY(XNObject) - - /** - * @brief 宏定义,用于声明私有数据成员 - */ - Q_DECLARE_PRIVATE(XNObject) - - /** - * @brief 宏定义,用于声明属性uniqueId - */ - Q_PROPERTY(quint32 UniqueId READ getUniqueId WRITE setUniqueId) + PrivateType *_Private_Ptr; public: /** * @brief 构造函数 - * @param parent 父对象 */ - explicit XNObject(QObject *parent = nullptr); + XNObject(); /** * @brief 析构函数 */ virtual ~XNObject(); +protected: + /** + * @brief 构造函数 + * @param p 私有数据成员 + */ + XNObject(PrivateType *p); + +public: /** * @brief 获取唯一ID * @return 唯一ID */ - quint32 getUniqueId(); + uint32_t GetUniqueId(); /** * @brief 设置唯一ID * @param uniqueId 唯一ID */ - void setUniqueId(const quint32 &uniqueId); + void SetUniqueId(const uint32_t &uniqueId); -protected: /** - * @brief 构造函数 - * @param dd 私有数据成员 - * @param parent 父对象 + * @brief 获取对象名称 + * @return 对象名称 */ - XNObject(XNObjectPrivate &dd, QObject *parent = nullptr); + const std::string &GetObjectName(); -protected: /** - * @brief 私有数据成员 + * @brief 设置对象名称 + * @param name 对象名称 */ - XNObjectPrivate *d_ptr; + void SetObjectName(const std::string &name); }; + +class XNFramework; +class XNDDSManager; +class XNEventManager; +class XNModelManager; +class XNScenarioManager; +class XNServiceManager; +class XNThreadManager; +class XNTimeManager; + +XNCLASS_PTR_DECLARE(XNFramework) +XNCLASS_PTR_DECLARE(XNDDSManager) +XNCLASS_PTR_DECLARE(XNEventManager) +XNCLASS_PTR_DECLARE(XNModelManager) +XNCLASS_PTR_DECLARE(XNScenarioManager) +XNCLASS_PTR_DECLARE(XNServiceManager) +XNCLASS_PTR_DECLARE(XNThreadManager) +XNCLASS_PTR_DECLARE(XNTimeManager) \ No newline at end of file diff --git a/XNCore/XNObject_p.h b/XNCore/XNObject_p.h index 1837b73..ee9ae44 100755 --- a/XNCore/XNObject_p.h +++ b/XNCore/XNObject_p.h @@ -15,28 +15,20 @@ /** * @brief 基础对象类的私有数据成员 */ -class XNObjectPrivate -{ -public: - /** - * @brief 宏定义,用于声明公有数据成员 - */ - Q_DECLARE_PUBLIC(XNObject) - - /** - * @brief 构造函数 - * @param q 基础对象类指针 - */ - explicit XNObjectPrivate(XNObject *q) : q_ptr(q) {} - +struct XNObjectPrivate { + virtual ~XNObjectPrivate(); /** * @brief 基础对象类指针 */ - XNObject *q_ptr; + XNObject *_Public_Ptr; -private: /** * @brief 唯一ID */ - quint32 uUniqueID; + uint32_t uUniqueID; + + /** + * @brief 对象名称 + */ + std::string sObjectName; }; diff --git a/XNCore/XNScenarioManager.cpp b/XNCore/XNScenarioManager.cpp index 15f786e..a8547b5 100755 --- a/XNCore/XNScenarioManager.cpp +++ b/XNCore/XNScenarioManager.cpp @@ -11,180 +11,192 @@ #include "XNScenarioManager.h" #include "XNScenarioManager_p.h" #include "XNFramework.h" +#include "XNDDSManager.h" +#include "XNThreadManager.h" +#include "XNModelManager.h" +#include "XNServiceManager.h" +#include +#include +#include +#include // 默认构造函数 -XNScenarioManager::XNScenarioManager(QObject *parent) - : XNBaseFrameObject(*new XNScenarioManagerPrivate(this), parent) +XNScenarioManager::XNScenarioManager() : XNBaseFrameObject(new XNScenarioManagerPrivate()) { - setUniqueId(5); - setObjectName("XNScenarioManager"); + SetUniqueId(5); + SetObjectName("XNScenarioManager"); } XNScenarioManager::~XNScenarioManager() { } -XNScenarioManager::XNScenarioManager(XNScenarioManagerPrivate &dd, QObject *parent) - : XNBaseFrameObject(dd, parent) +XNScenarioManager::XNScenarioManager(PrivateType *p) : XNBaseFrameObject(p) { } // 获取运行环境名称 -const QString &XNScenarioManager::GetSimName() +const std::string &XNScenarioManager::GetSimName() { - Q_D(const XNScenarioManager); + T_D(); return d->_ScenarioName; } // 设置运行环境名称 -void XNScenarioManager::SetSimName(QString &simName) +void XNScenarioManager::SetSimName(const std::string &simName) { - Q_D(XNScenarioManager); + T_D(); d->_ScenarioName = simName; } -// 获取运行环境开始时间 -const QDateTime &XNScenarioManager::GetSimStartTime() -{ - Q_D(XNScenarioManager); - return d->_SimStartTime; -} - -// 设置运行环境开始时间 -void XNScenarioManager::SetSimStartTime(QDateTime &startTime) -{ - Q_D(XNScenarioManager); - d->_SimStartTime = startTime; -} - // 初始化 -void XNScenarioManager::OnInitialize() +bool XNScenarioManager::Initialize() { - Q_D(XNScenarioManager); + T_D(); LOG_INFO("XNScenarioManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; - emit Initialize(); + return true; } -void XNScenarioManager::OnPrepareForExecute() +bool XNScenarioManager::PrepareForExecute() { - Q_D(XNScenarioManager); + T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNScenarioManager is prepared!"); - emit PrepareForExecute(); + return true; +} + +// 辅助函数:分割字符串 +std::vector split(const std::string &str, const std::string &delim) +{ + std::vector tokens; + size_t prev = 0, pos = 0; + do { + pos = str.find(delim, prev); + if (pos == std::string::npos) + pos = str.length(); + std::string token = str.substr(prev, pos - prev); + if (!token.empty()) + tokens.push_back(token); + prev = pos + delim.length(); + } while (pos < str.length() && prev < str.length()); + return tokens; +} + +// 辅助函数:获取文件名(不含扩展名) +std::string getFileNameWithoutExt(const std::string &path) +{ + size_t lastDot = path.find_last_of('.'); + if (lastDot != std::string::npos) { + return path.substr(0, lastDot); + } + return path; } // 运行环境配置文件解析 -void XNScenarioManager::AnalysisScenarioXml(const QString &XmlPath) +bool XNScenarioManager::AnalysisScenarioXml(const std::string &XmlPath) { - Q_D(XNScenarioManager); - QFile file(XmlPath); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LOG_ERROR("0x2100 打开运行环境描述文件: %1出错,错误信息: %2", XmlPath, - file.errorString()); - emit AnalyzeScenarioXmlFailed(); - return; + T_D(); + std::ifstream file(XmlPath); + if (!file.is_open()) { + LOG_ERROR("0x2100 打开运行环境描述文件: %1出错,错误信息: %2", XmlPath, strerror(errno)); + return false; } - QDomDocument doc; - if (!doc.setContent(&file)) { + tinyxml2::XMLDocument doc; + if (doc.LoadFile(XmlPath.c_str()) != tinyxml2::XML_SUCCESS) { LOG_ERROR("0x2100 解析XML文件: %1 失败", XmlPath); file.close(); - emit AnalyzeScenarioXmlFailed(); - return; + return false; } - QDomElement root = doc.documentElement(); + tinyxml2::XMLElement *root = doc.FirstChildElement("Scenario"); // 读取环境信息 - QDomElement envInfo = root.firstChildElement("Environment"); - QString OSName = envInfo.attribute("OSName"); - QString version = envInfo.attribute("Version"); - QString kernel = envInfo.attribute("RTXVersion"); - double basefreq = envInfo.attribute("BaseFrequency").toDouble(); - emit SetBaseFreq(basefreq); + tinyxml2::XMLElement *envInfo = root->FirstChildElement("Environment"); + std::string OSName = envInfo->Attribute("OSName"); + std::string version = envInfo->Attribute("Version"); + std::string kernel = envInfo->Attribute("RTXVersion"); // 设置工作目录 - QString rootPath = envInfo.attribute("WorkPath"); - emit SetWorkPath(rootPath); + std::string rootPath = envInfo->Attribute("WorkPath"); + GetFramework()->SetWorkPath(rootPath); // 设置模型库目录 - QString modelPath = rootPath + envInfo.attribute("ModelsPath"); - emit SetModelPath(modelPath); + std::string modelPath = rootPath + envInfo->Attribute("ModelsPath"); + GetFramework()->SetModelPath(modelPath); // 设置服务库目录 - QString servicePath = rootPath + envInfo.attribute("ServicesPath"); - emit SetServicePath(servicePath); - quint32 domainID = envInfo.attribute("DomainID").toUInt(); - emit SetDomainID(domainID); + std::string servicePath = rootPath + envInfo->Attribute("ServicesPath"); + GetFramework()->SetServicePath(servicePath); + // 设置域ID + uint32_t domainID = std::stoul(envInfo->Attribute("DomainID")); + GetFramework()->GetDDSManager()->SetDomainID(domainID); // 读取CPU亲和性 - QString cpuAff = envInfo.attribute("CPUAffinity"); - QStringList cpuAffList = cpuAff.split(","); + std::string cpuAff = envInfo->Attribute("CPUAffinity"); + std::vector cpuAffList = split(cpuAff, ","); //读取服务列表 - QDomElement serviceList = root.firstChildElement("ServicesList"); - for (int i = 0; i < serviceList.elementsByTagName("Service").count(); i++) { - QDomElement service = serviceList.elementsByTagName("Service").at(i).toElement(); - QString serviceName = service.attribute("Name"); - QString libName = service.attribute("ClassName"); - libName = libName.left(libName.lastIndexOf('.')); - QString dynamicLibName = servicePath + "lib" + libName + ".so"; - // 加载动态库 - emit LoadService(dynamicLibName, libName); + tinyxml2::XMLElement *serviceList = root->FirstChildElement("ServicesList"); + if (serviceList) { + tinyxml2::XMLElement *service = serviceList->FirstChildElement("Service"); + while (service) { + std::string serviceName = service->Attribute("Name"); + std::string libName = service->Attribute("ClassName"); + libName = getFileNameWithoutExt(libName); + std::string dynamicLibName = servicePath + "lib" + libName + ".so"; + // 加载动态库 + GetFramework()->GetServiceManager()->LoadService(dynamicLibName, libName, 0); + service = service->NextSiblingElement("Service"); + } } - // 默认按CAE模式,创建5个线程 - // emit AddThreadPool("100Hz thread", FreqLevel::BaseFreq, 99, 1, 1.0E9 / basefreq); - // emit AddThreadPool("50Hz thread", FreqLevel::BaseFreq, 89, 1, 1.0E9 / basefreq); - // emit AddThreadPool("25Hz thread", FreqLevel::BaseFreq, 79, 1, 1.0E9 / basefreq); - // emit AddThreadPool("12.5Hz thread", FreqLevel::BaseFreq, 69, 1, 1.0E9 / basefreq); - // emit AddThreadPool("6.25Hz thread", FreqLevel::BaseFreq, 59, 1, 1.0E9 / basefreq); // 读取模型分组 - for (int i = 0; i < root.elementsByTagName("ModelGroup").count(); i++) { - // 读取模型分组信息 - QDomElement modelGroup = root.elementsByTagName("ModelGroup").at(i).toElement(); + tinyxml2::XMLElement *modelGroup = root->FirstChildElement("ModelGroup"); + while (modelGroup) { // 读取模型分组名称 - QString modelGroupName = modelGroup.attribute("Name"); + std::string modelGroupName = modelGroup->Attribute("Name"); // 读取模型分组频率 - int modelGroupFreq = modelGroup.attribute("FreqGroup").toInt(); - if (modelGroupFreq > 5 || modelGroupFreq < 0) { - LOG_ERROR("0x2100 模型分组频率设置错误,频率值:%1", modelGroupFreq); - emit AnalyzeScenarioXmlFailed(); - return; - } + double modelGroupFreq = std::stod(modelGroup->Attribute("Freq")); // 读取模型分组优先级 - int modelGroupPriority = modelGroup.attribute("Priority").toInt(); + int modelGroupPriority = std::stoi(modelGroup->Attribute("Priority")); if (modelGroupPriority > 99 || modelGroupPriority < 0) { - LOG_ERROR("0x2100 模型分组优先级设置错误,优先级值:%1", modelGroupPriority); - emit AnalyzeScenarioXmlFailed(); - return; + LOG_ERROR("0x2100 模型分组优先级设置错误,优先级值:%d", modelGroupPriority); + return false; } // 读取模型分组CPU亲和性 - QString modelGroupCPUAff = modelGroup.attribute("CPUAff"); - QStringList modelGroupCPUAffList = modelGroupCPUAff.split(","); - for (int j = 0; j < modelGroupCPUAffList.count(); j++) { - if (!cpuAffList.contains(modelGroupCPUAffList.at(j))) { - LOG_ERROR("0x2100 模型分组CPU亲和性设置错误,CPU亲和性值:%1,进程CPU亲和性值:%2", - modelGroupCPUAffList.at(j), cpuAff); - emit AnalyzeScenarioXmlFailed(); - return; + std::string modelGroupCPUAff = modelGroup->Attribute("CPUAff"); + std::vector modelGroupCPUAffList = split(modelGroupCPUAff, ","); + + // 验证CPU亲和性 + for (const auto &cpu : modelGroupCPUAffList) { + if (std::find(cpuAffList.begin(), cpuAffList.end(), cpu) == cpuAffList.end()) { + LOG_ERROR("0x2100 模型分组CPU亲和性设置错误,CPU亲和性值:%s,进程CPU亲和性值:%s", + cpu.c_str(), cpuAff.c_str()); + return false; } } + int ThreadCpuAffinity = 0; - for (int j = 0; j < modelGroupCPUAffList.count(); j++) { - ThreadCpuAffinity |= 1 << cpuAffList.indexOf(modelGroupCPUAffList.at(j)); + for (const auto &cpu : modelGroupCPUAffList) { + auto it = std::find(cpuAffList.begin(), cpuAffList.end(), cpu); + if (it != cpuAffList.end()) { + ThreadCpuAffinity |= 1 << std::distance(cpuAffList.begin(), it); + } } - emit AddThreadPool(modelGroupName, (FreqLevel)modelGroupFreq, modelGroupPriority, - ThreadCpuAffinity, (1.0E9 / basefreq) * pow(2.0, modelGroupFreq)); + // 添加线程池 + uint32_t threadID = GetFramework()->GetThreadManager()->AddThreadPool( + modelGroupName, modelGroupFreq, modelGroupPriority, ThreadCpuAffinity); // 读取模型列表 - for (int j = 0; j < modelGroup.elementsByTagName("Model").count(); j++) { - QDomElement model = modelGroup.elementsByTagName("Model").at(j).toElement(); - QString modelName = model.attribute("Name"); - QString libName = model.attribute("ClassName"); - libName = libName.left(libName.lastIndexOf('.')); - // 获得动态库的路径 - QString dynamicLibName = modelPath + "lib" + libName + ".so"; + tinyxml2::XMLElement *model = modelGroup->FirstChildElement("Model"); + while (model) { + std::string modelName = model->Attribute("Name"); + std::string libName = model->Attribute("ClassName"); + libName = getFileNameWithoutExt(libName); + std::string dynamicLibName = modelPath + "lib" + libName + ".so"; // 加载动态库 - emit LoadModel(dynamicLibName, libName); + GetFramework()->GetModelManager()->LoadModel(dynamicLibName, libName, 0, threadID); + model = model->NextSiblingElement("Model"); } - } - // TODO 提交事件 - emit AnalyzeScenarioXmlSuccess(); + modelGroup = modelGroup->NextSiblingElement("ModelGroup"); + } + + return true; } diff --git a/XNCore/XNScenarioManager.h b/XNCore/XNScenarioManager.h index 1115f80..9870c3c 100755 --- a/XNCore/XNScenarioManager.h +++ b/XNCore/XNScenarioManager.h @@ -11,7 +11,7 @@ #pragma once #include "XNBaseFrameObject.h" -class XNScenarioManagerPrivate; +struct XNScenarioManagerPrivate; /** * @brief 运行环境描述管理器类 @@ -19,14 +19,13 @@ class XNScenarioManagerPrivate; */ class XNScenarioManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNScenarioManager) - Q_DISABLE_COPY(XNScenarioManager) + XN_METATYPE(XNScenarioManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNScenarioManager) public: /** * @brief 运行环境描述管理器类默认构造函数 */ - explicit XNScenarioManager(QObject *parent = nullptr); + XNScenarioManager(); /** * @brief 运行环境描述管理器类析构函数 @@ -39,110 +38,39 @@ protected: * @param p:私有结构体指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNScenarioManager(XNScenarioManagerPrivate &dd, QObject *parent = nullptr); + XNScenarioManager(PrivateType *p); public: /** * @brief 获取运行环境名称 * @return const XNString&: 运行环境名称 */ - const QString &GetSimName(); + const std::string &GetSimName(); /** * @brief 设置运行环境名称 * @param simName: XNString类型,运行环境名称 */ - void SetSimName(QString &simName); + void SetSimName(const std::string &simName); - /** - * @brief 获取运行环境开始时间 - * @return const XNTime&: 运行环境开始时间 - */ - const QDateTime &GetSimStartTime(); - - /** - * @brief 设置运行环境开始时间 - * @param startTime: QDateTime类型,运行环境开始时间 - */ - void SetSimStartTime(QDateTime &startTime); - -signals: - /** - * @brief 信号,用于通知线程管理器添加线程 - */ - void AddThreadPool(QString name, FreqLevel freq, quint32 priority, quint32 CPUAff, - double RunInter); - - /** - * @brief 信号,用于通知模型管理器加载模型 - */ - void LoadModel(const QString &modelPath, const QString &className); - - /** - * @brief 信号,用于通知服务管理器加载服务 - */ - void LoadService(const QString &servicePath, const QString &className); - - /** - * @brief 信号,用于通知框架设置工作路径 - */ - void SetWorkPath(const QString &workPath); - - /** - * @brief 信号,用于通知框架设置模型库路径 - */ - void SetModelPath(const QString &modelPath); - - /** - * @brief 信号,用于通知框架设置服务库路径 - */ - void SetServicePath(const QString &servicePath); - - /** - * @brief 信号,用于通知框架设置CPU亲和性 - */ - void SetCpuAffinity(quint32 cpuAffinity); - - /** - * @brief 设置基础运行频率 - * @param freq: 基础运行频率,单位Hz - */ - void SetBaseFreq(const double &freq); - - /** - * @brief 设置DDS域ID - * @param domainID: DDS域ID - */ - void SetDomainID(quint32 domainID); - - /** - * @brief 解析配置文件成功 - */ - void AnalyzeScenarioXmlSuccess(); - - /** - * @brief 解析配置文件失败 - */ - void AnalyzeScenarioXmlFailed(); - -public slots: +public: /** * @brief 初始化运行环境描述管理器 * @return true: 初始化成功 * @return false: 初始化失败 * @details 运行环境描述管理器的初始化接口函数 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 仿真运行前最后处理 * @note 运行环境描述管理器在系统运行开始前的准备工作 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 运行环境配置文件解析 - * @param XmlPath: QString类型,运行环境配置文件解析路径 + * @param XmlPath: std::string类型,运行环境配置文件解析路径 */ - virtual void AnalysisScenarioXml(const QString &XmlPath); + virtual bool AnalysisScenarioXml(const std::string &XmlPath); }; diff --git a/XNCore/XNScenarioManager_p.h b/XNCore/XNScenarioManager_p.h index e41c85b..c3453f3 100755 --- a/XNCore/XNScenarioManager_p.h +++ b/XNCore/XNScenarioManager_p.h @@ -14,19 +14,9 @@ /** * @brief 运行环境描述管理器类私有结构体 */ -class XNScenarioManagerPrivate : public XNBaseFrameObjectPrivate -{ - -public: - Q_DECLARE_PUBLIC(XNScenarioManager) - explicit XNScenarioManagerPrivate(XNScenarioManager *q) : XNBaseFrameObjectPrivate(q) {} +struct XNScenarioManagerPrivate : public XNBaseFrameObjectPrivate { /** * @brief 运行环境名称 */ - QString _ScenarioName; - - /** - * @brief 运行环境开始时间 - */ - QDateTime _SimStartTime; + std::string _ScenarioName; }; diff --git a/XNCore/XNServiceManager.cpp b/XNCore/XNServiceManager.cpp index f5c420d..0fe8784 100755 --- a/XNCore/XNServiceManager.cpp +++ b/XNCore/XNServiceManager.cpp @@ -4,13 +4,14 @@ #include #include #include +#include +#include -XNServiceManager::XNServiceManager(QObject *parent) - : XNBaseFrameObject(*new XNServiceManagerPrivate(this), parent) +XNServiceManager::XNServiceManager() : XNBaseFrameObject(new XNServiceManagerPrivate()) { - setUniqueId(4); - setObjectName("XNServiceManager"); - Q_D(XNServiceManager); + SetUniqueId(4); + SetObjectName("XNServiceManager"); + T_D(); d->ServiceIDAssigned.resize(10000, false); } @@ -18,107 +19,91 @@ XNServiceManager::~XNServiceManager() { } -XNServiceManager::XNServiceManager(XNServiceManagerPrivate &dd, QObject *parent) - : XNBaseFrameObject(dd, parent) +XNServiceManager::XNServiceManager(PrivateType *p) : XNBaseFrameObject(p) { } -void XNServiceManager::OnInitialize() +bool XNServiceManager::Initialize() { - Q_D(XNServiceManager); + T_D(); LOG_INFO("XNServiceManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; - emit Initialize(); + return true; } -void XNServiceManager::OnPrepareForExecute() +bool XNServiceManager::PrepareForExecute() { - Q_D(XNServiceManager); + T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNServiceManager is prepared!"); - emit PrepareForExecute(); + return true; } -void XNServiceManager::OnLoadService(const QString &servicePath, const QString &serviceName) +void XNServiceManager::LoadService(const std::string &servicePath, const std::string &serviceName, + uint32_t initialType) { - Q_D(XNServiceManager); - QLibrary lib(servicePath); - if (lib.load()) { - typedef void (*InitialServiceFunc)(); - QString initialServiceName = "Initial" + serviceName; + T_D(); + void *handle = dlopen(servicePath.c_str(), RTLD_LAZY); + if (handle) { + typedef XNServiceObjectPtr (*InitialServiceFunc)(); + std::string initialServiceName = "Initial" + serviceName; InitialServiceFunc initialService = - (InitialServiceFunc)lib.resolve(initialServiceName.toUtf8().constData()); + (InitialServiceFunc)dlsym(handle, initialServiceName.c_str()); if (initialService) { - initialService(); - QMetaType metaType = QMetaType::fromName(serviceName.toUtf8().constData()); - if (metaType.isValid()) { - QObject *obj = static_cast(metaType.create()); - if (obj) { - XNServiceObject *service = qobject_cast(obj); - if (service) { - quint32 serviceID = RegisterService(); - if (serviceID == 0) { - LOG_WARNING("0x2174 Assign Service ID Failed, Service ID is used up!"); - delete obj; - return; - } - service->setParent(this); - service->setObjectName(serviceName); - service->setUniqueId(serviceID); - QString configFilePath = - QFileInfo(servicePath).absolutePath() + "/" + serviceName + ".scfg"; - service->SetXmlPath(configFilePath); - connect(this, &XNServiceManager::PrepareForExecute, service, - &XNServiceObject::OnPrepareForExecute); - service->OnInitialize(); - } else { - LOG_WARNING("0x2175 Service %1 Instantiation Failed, Not a subclass of " - "XNServiceObject!", - serviceName); - delete obj; - return; - } - } else { - LOG_WARNING( - "0x2176 Service %1 Instantiation Failed, Not a subclass of QObject!", - serviceName); - delete obj; + XNServiceObjectPtr service = initialService(); + if (service) { + uint32_t serviceID = RegisterService(); + if (serviceID == 0) { + LOG_WARNING("0x2174 Assign Service ID Failed, Service ID is used up!"); + dlclose(handle); return; } + service->SetUniqueId(serviceID); + service->SetObjectName(serviceName); + service->SetFramework(GetFramework()); + // 使用std::filesystem处理路径 + std::filesystem::path configPath = + std::filesystem::path(servicePath).parent_path() / (serviceName + ".scfg"); + service->SetXmlPath(configPath.string()); + + // 注册服务到管理器 + d->ServiceList[serviceID] = service; + + // 初始化服务 + service->Initialize(initialType); } else { - LOG_WARNING("0x2173 Service %1 Not found in dynamic link library %2!", serviceName, - servicePath); + LOG_WARNING("0x2173 Service %s Not found in dynamic link library %s!", + serviceName.c_str(), servicePath.c_str()); + dlclose(handle); return; } } else { - LOG_WARNING("0x2177 Service %1 Initialization Failed, Function InitialService Not " - "Found!", - serviceName); + LOG_WARNING( + "0x2177 Service %s Initialization Failed, Function InitialService Not Found!", + serviceName.c_str()); + dlclose(handle); return; } } else { - LOG_WARNING("0x2172 Service %1 Dynamic link library loading failed! Error: %2", serviceName, - lib.errorString()); + LOG_WARNING("0x2172 Service %s Dynamic link library loading failed! Error: %s", + serviceName.c_str(), dlerror()); } } -XNServiceObject *XNServiceManager::GetService(quint32 serviceID) +XNServiceObjectPtr XNServiceManager::GetService(uint32_t serviceID) { - Q_D(XNServiceManager); - if (d->ServiceIDAssigned[serviceID - 20000]) { - QList serviceList = findChildren(); - for (auto &service : serviceList) { - if (service->getUniqueId() == serviceID) - return service; - } - return nullptr; - } else + T_D(); + if (d->ServiceIDAssigned[serviceID - 20000] + && d->ServiceList.find(serviceID) != d->ServiceList.end()) { + return d->ServiceList[serviceID]; + } else { return nullptr; + } } -quint32 XNServiceManager::RegisterService() +uint32_t XNServiceManager::RegisterService() { - Q_D(XNServiceManager); + T_D(); // 从20000~29999的编号中分配ID for (int i = 0; i < 10000; i++) { if (d->ServiceIDAssigned[i]) diff --git a/XNCore/XNServiceManager.h b/XNCore/XNServiceManager.h index 74573a3..eb0a5bb 100755 --- a/XNCore/XNServiceManager.h +++ b/XNCore/XNServiceManager.h @@ -3,26 +3,35 @@ // 添加前向声明 class XNServiceObject; -class XNServiceManagerPrivate; +XNCLASS_PTR_DECLARE(XNServiceObject) + +struct XNServiceManagerPrivate; class XNServiceManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNServiceManager) - Q_DISABLE_COPY(XNServiceManager) + XN_METATYPE(XNServiceManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNServiceManager) public: - explicit XNServiceManager(QObject *parent = nullptr); + /** + * @brief 服务管理器类默认构造函数 + */ + XNServiceManager(); + + /** + * @brief 服务管理器类析构函数 + */ virtual ~XNServiceManager(); protected: - XNServiceManager(XNServiceManagerPrivate &dd, QObject *parent = nullptr); - -public slots: - virtual void OnInitialize() override; - virtual void OnPrepareForExecute() override; - void OnLoadService(const QString &servicePath, const QString &serviceName); + XNServiceManager(PrivateType *p); public: - XNServiceObject *GetService(quint32 serviceID); - quint32 RegisterService(); + virtual bool Initialize() override; + virtual bool PrepareForExecute() override; + void LoadService(const std::string &servicePath, const std::string &serviceName, + uint32_t initialType); + +public: + XNServiceObjectPtr GetService(uint32_t serviceID); + uint32_t RegisterService(); }; diff --git a/XNCore/XNServiceManager_p.h b/XNCore/XNServiceManager_p.h index 79d9380..864da21 100755 --- a/XNCore/XNServiceManager_p.h +++ b/XNCore/XNServiceManager_p.h @@ -1,16 +1,16 @@ #pragma once #include "XNBaseFrameObject_p.h" -class XNServiceManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNServiceManager) - - explicit XNServiceManagerPrivate(XNServiceManager *q) : XNBaseFrameObjectPrivate(q) {} - +struct XNServiceManagerPrivate : public XNBaseFrameObjectPrivate { /** * @brief 服务ID库 * @details 所有服务已用ID的存储库 */ - QVector ServiceIDAssigned; + std::vector ServiceIDAssigned; + + /** + * @brief 服务列表 + * @details 所有服务的存储库 + */ + std::map ServiceList; }; \ No newline at end of file diff --git a/XNCore/XNServiceObject.cpp b/XNCore/XNServiceObject.cpp index f5e6fee..601bdce 100755 --- a/XNCore/XNServiceObject.cpp +++ b/XNCore/XNServiceObject.cpp @@ -1,7 +1,9 @@ #include "XNServiceObject.h" #include "XNServiceObject_p.h" +#include "XNEventManager.h" +#include "XNFramework.h" -XNServiceObject::XNServiceObject(QObject *parent) : XNObject(parent) +XNServiceObject::XNServiceObject() : XNObject(new XNServiceObjectPrivate()) { } @@ -9,179 +11,191 @@ XNServiceObject::~XNServiceObject() { } -XNServiceObject::XNServiceObject(XNServiceObjectPrivate &dd, QObject *parent) : XNObject(dd, parent) +XNServiceObject::XNServiceObject(PrivateType *p) : XNObject(p) { } -const QString &XNServiceObject::GetVersion() +const std::string &XNServiceObject::GetVersion() { - Q_D(XNServiceObject); + T_D(); return d->_sVersion; } -const QString &XNServiceObject::GetDescription() +const std::string &XNServiceObject::GetDescription() { - Q_D(XNServiceObject); + T_D(); return d->_sDescription; } -const QString &XNServiceObject::GetAuthor() +const std::string &XNServiceObject::GetAuthor() { - Q_D(XNServiceObject); + T_D(); return d->_sAuthor; } -const QString &XNServiceObject::GetXmlPath() +const std::string &XNServiceObject::GetXmlPath() { - Q_D(XNServiceObject); + T_D(); return d->_sXmlPath; } -const QDateTime &XNServiceObject::GetCreateTime() +const XNTimePoint &XNServiceObject::GetCreateTime() { - Q_D(XNServiceObject); + T_D(); return d->_cCreateTime; } -const QDateTime &XNServiceObject::GetChangeTime() +const XNTimePoint &XNServiceObject::GetChangeTime() { - Q_D(XNServiceObject); + T_D(); return d->_cChangeTime; } -void XNServiceObject::SetVersion(const QString &version) +void XNServiceObject::SetVersion(const std::string &version) { - Q_D(XNServiceObject); + T_D(); d->_sVersion = version; } -void XNServiceObject::SetDescription(const QString &sDescription) +void XNServiceObject::SetDescription(const std::string &sDescription) { - Q_D(XNServiceObject); + T_D(); d->_sDescription = sDescription; } -void XNServiceObject::SetAuthor(const QString &sAuthor) +void XNServiceObject::SetAuthor(const std::string &sAuthor) { - Q_D(XNServiceObject); + T_D(); d->_sAuthor = sAuthor; } -void XNServiceObject::SetXmlPath(const QString &sXmlPath) +void XNServiceObject::SetXmlPath(const std::string &sXmlPath) { - Q_D(XNServiceObject); + T_D(); d->_sXmlPath = sXmlPath; } -void XNServiceObject::SetCreateTime(const QDateTime &cTime) +void XNServiceObject::SetCreateTime(const XNTimePoint &cTime) { - Q_D(XNServiceObject); + T_D(); d->_cCreateTime = cTime; } -void XNServiceObject::SetChangeTime(const QDateTime &cTime) +void XNServiceObject::SetChangeTime(const XNTimePoint &cTime) { - Q_D(XNServiceObject); + T_D(); d->_cChangeTime = cTime; } -int XNServiceObject::RegisterEventHandler(const QString &eventName, - std::function callback, +int XNServiceObject::RegisterEventHandler(const std::string &eventName, XNEventCallback callback, bool async, XNEvent::Priority priority) { // 注册事件处理器 - Q_D(XNServiceObject); - if (d->pEventManager) { - return d->pEventManager->RegisterEventHandler(eventName, callback, getUniqueId(), async, + T_D(); + auto framework = GetFramework(); + if (framework) { + auto eventManager = framework->GetEventManager(); + if (eventManager) { + return eventManager->RegisterEventHandler(eventName, callback, GetUniqueId(), async, priority); + } } return -1; } -void XNServiceObject::TriggerEvent(const QString &eventName, const QVariant &eventData, +void XNServiceObject::TriggerEvent(const std::string &eventName, const std::any &eventData, bool forceAsync, XNEvent::Priority priority) { // 触发事件 - Q_D(XNServiceObject); - if (d->pEventManager) { - d->pEventManager->TriggerEvent(eventName, eventData, forceAsync, priority); + T_D(); + auto framework = GetFramework(); + if (framework) { + auto eventManager = framework->GetEventManager(); + if (eventManager) { + eventManager->TriggerEvent(eventName, eventData, forceAsync, priority); + } } } -int XNServiceObject::RegisterRTEventHandler(const QString &eventName, - std::function callback) +int XNServiceObject::RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback) { return RegisterEventHandler(eventName, callback, true, XNEvent::Priority::RealTime); } -void XNServiceObject::TriggerRTEvent(const QString &eventName, const QVariant &eventData) +void XNServiceObject::TriggerRTEvent(const std::string &eventName, const std::any &eventData) { TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); } -void XNServiceObject::OnInitialize() +void XNServiceObject::Initialize(uint32_t initialType) { - Q_D(XNServiceObject); - // 获取事件管理器 - XNServiceManager *serviceManager = qobject_cast(parent()); - if (serviceManager == nullptr) { - LOG_WARNING("Failed to get ServiceManager!"); - return; - } + T_D(); + if (initialType == 0) { + tinyxml2::XMLDocument doc; + if (doc.LoadFile(GetXmlPath().c_str()) != tinyxml2::XML_SUCCESS) { + LOG_WARNING("Failed to open the service configuration file: %1!", GetXmlPath()); + return; + } - d->pEventManager = serviceManager->parent()->findChild(); - if (d->pEventManager == nullptr) { - LOG_WARNING("Failed to get EventManager!"); - return; - } + tinyxml2::XMLElement *rootNode = doc.RootElement(); + if (!rootNode) { + LOG_WARNING("Invalid XML file format: %1!", GetXmlPath()); + return; + } - QFile file(GetXmlPath()); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - LOG_WARNING("Failed to open the service configuration file: %1!", GetXmlPath()); - return; - } - QDomDocument doc; - doc.setContent(&file); + const char *serviceName = rootNode->FirstChildElement("Name")->GetText(); + if (serviceName != GetObjectName()) { + LOG_WARNING( + "The service name in the configuration file of service %1 is not consistent " + "with the service name in the configuration file of service %2!", + GetObjectName(), serviceName); + return; + } - QDomElement rootNode = doc.documentElement(); - QString serviceName = rootNode.firstChildElement("Name").text(); - if (serviceName != objectName()) { - LOG_WARNING("The service name in the configuration file of service %1 is not consistent " - "with the service name in the configuration file of service %2!", - objectName(), serviceName); - return; - } - d->_sDescription = rootNode.firstChildElement("Description").text(); - d->_sAuthor = rootNode.firstChildElement("Author").text(); - d->_sVersion = rootNode.firstChildElement("Version").text(); - d->_cCreateTime = - QDateTime::fromString(rootNode.firstChildElement("CreateTime").text(), Qt::ISODate); - d->_cChangeTime = - QDateTime::fromString(rootNode.firstChildElement("ChangeTime").text(), Qt::ISODate); + d->_sDescription = rootNode->FirstChildElement("Description")->GetText(); + d->_sAuthor = rootNode->FirstChildElement("Author")->GetText(); + d->_sVersion = rootNode->FirstChildElement("Version")->GetText(); - QDomElement nodeCmds = rootNode.firstChildElement("CommandList"); - for (QDomElement nodeCmd = nodeCmds.firstChildElement("Command"); !nodeCmd.isNull(); - nodeCmd = nodeCmd.nextSiblingElement("Command")) { - QString cmdName = nodeCmd.attribute("Name"); - QString cmdDescription = nodeCmd.attribute("Description"); - QString cmdCall = nodeCmd.attribute("Call"); + // 解析时间 + const char *createTimeStr = rootNode->FirstChildElement("CreateTime")->GetText(); + const char *changeTimeStr = rootNode->FirstChildElement("ChangeTime")->GetText(); + d->_cCreateTime = parseISOTime(createTimeStr); + d->_cChangeTime = parseISOTime(changeTimeStr); + + tinyxml2::XMLElement *nodeCmds = rootNode->FirstChildElement("CommandList"); + if (nodeCmds) { + for (tinyxml2::XMLElement *nodeCmd = nodeCmds->FirstChildElement("Command"); + nodeCmd != nullptr; nodeCmd = nodeCmd->NextSiblingElement("Command")) { + const char *cmdName = nodeCmd->Attribute("Name"); + const char *cmdDescription = nodeCmd->Attribute("Description"); + const char *cmdCall = nodeCmd->Attribute("Call"); + // TODO: 处理命令信息 + } + } + } else { } } -void XNServiceObject::OnPrepareForExecute() +void XNServiceObject::PrepareForExecute() { - Q_D(XNServiceObject); + T_D(); RegisterDDSParticipant(); } void XNServiceObject::RegisterDDSParticipant() { - Q_D(XNServiceObject); + T_D(); //TODO 注册服务状态主题参与者 } -XNEventManager *XNServiceObject::GetEventManager() const +XNFrameworkPtr XNServiceObject::GetFramework() const { - Q_D(const XNServiceObject); - return d->pEventManager; + T_D(); + return d->pFramework; +} + +void XNServiceObject::SetFramework(XNFrameworkPtr framework) +{ + T_D(); + d->pFramework = framework; } diff --git a/XNCore/XNServiceObject.h b/XNCore/XNServiceObject.h index 49f7802..8d32457 100755 --- a/XNCore/XNServiceObject.h +++ b/XNCore/XNServiceObject.h @@ -3,68 +3,59 @@ #include "XNObject.h" #include "XNServiceManager.h" #include "XNEventManager.h" - -class XNServiceObjectPrivate; +struct XNServiceObjectPrivate; class XNServiceObject : public XNObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNServiceObject) - Q_DISABLE_COPY(XNServiceObject) - - Q_PROPERTY(QString description READ GetDescription WRITE SetDescription) - Q_PROPERTY(QString author READ GetAuthor WRITE SetAuthor) - Q_PROPERTY(QString xmlPath READ GetXmlPath WRITE SetXmlPath) - Q_PROPERTY(QDateTime createTime READ GetCreateTime WRITE SetCreateTime) - Q_PROPERTY(QDateTime changeTime READ GetChangeTime WRITE SetChangeTime) - Q_PROPERTY(QString version READ GetVersion WRITE SetVersion) - + XN_METATYPE(XNServiceObject, XNObject) + XN_DECLARE_PRIVATE(XNServiceObject) public: - explicit XNServiceObject(QObject *parent = nullptr); + XNServiceObject(); virtual ~XNServiceObject(); protected: - explicit XNServiceObject(XNServiceObjectPrivate &dd, QObject *parent = nullptr); + XNServiceObject(PrivateType *p); public: - const QString &GetVersion(); - const QString &GetDescription(); - const QString &GetAuthor(); - const QString &GetXmlPath(); - const QDateTime &GetCreateTime(); - const QDateTime &GetChangeTime(); + const std::string &GetVersion(); + const std::string &GetDescription(); + const std::string &GetAuthor(); + const std::string &GetXmlPath(); + const XNTimePoint &GetCreateTime(); + const XNTimePoint &GetChangeTime(); - void SetVersion(const QString &version); - void SetDescription(const QString &description); - void SetAuthor(const QString &author); - void SetXmlPath(const QString &xmlPath); - void SetCreateTime(const QDateTime &createTime); - void SetChangeTime(const QDateTime &changeTime); + void SetVersion(const std::string &version); + void SetDescription(const std::string &description); + void SetAuthor(const std::string &author); + void SetXmlPath(const std::string &xmlPath); + void SetCreateTime(const XNTimePoint &createTime); + void SetChangeTime(const XNTimePoint &changeTime); - int RegisterEventHandler(const QString &eventName, - std::function callback, bool async = false, + int RegisterEventHandler(const std::string &eventName, XNEventCallback callback, + bool async = false, XNEvent::Priority priority = XNEvent::Priority::Normal); - void TriggerEvent(const QString &eventName, const QVariant &eventData = QVariant(), + void TriggerEvent(const std::string &eventName, const std::any &eventData = std::any(), bool forceAsync = false, XNEvent::Priority priority = XNEvent::Priority::Normal); - int RegisterRTEventHandler(const QString &eventName, - std::function callback); + int RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback); - void TriggerRTEvent(const QString &eventName, const QVariant &eventData = QVariant()); + void TriggerRTEvent(const std::string &eventName, const std::any &eventData = std::any()); -public slots: - virtual void OnInitialize(); - virtual void OnPrepareForExecute(); + virtual void Initialize(uint32_t initialType); + virtual void PrepareForExecute(); -public: virtual void RegisterDDSParticipant(); -private: - XNEventManager *GetEventManager() const; + void SetFramework(XNFrameworkPtr framework); + +protected: + XNFrameworkPtr GetFramework() const; }; +XNCLASS_PTR_DECLARE(XNServiceObject) + #define XN_DECLARE_DDS_SERVICE() \ public: \ virtual void RegisterDDSParticipant() override; @@ -74,11 +65,11 @@ public: { \ XNServiceObject::RegisterDDSParticipant(); \ Q_D(class); \ - XNServiceManager *serviceManager = qobject_cast(parent()); \ - if (serviceManager == nullptr) \ + auto framework = GetFramework(); \ + if (!framework) \ return; \ - XNDDSManager *ddsManager = serviceManager->parent()->findChild(); \ - if (ddsManager == nullptr) \ + XNDDSManagerPtr ddsManager = framework->GetDDSManager(); \ + if (!ddsManager) \ return; \ quint32 MyID = getUniqueId(); @@ -90,3 +81,10 @@ public: #topic, MyID, std::bind(fun, this, std::placeholders::_1)); #define XN_REGISTER_SERVICE_END_SERVICE(class) } + +#define XN_SERVICE_INITIALIZE(ClassName) \ + extern "C" XNServiceObjectPtr Initial##ClassName() \ + { \ + ClassNamePtr obj = std::make_shared(); \ + return obj; \ + } diff --git a/XNCore/XNServiceObject_p.h b/XNCore/XNServiceObject_p.h index 574b159..32bc8ba 100755 --- a/XNCore/XNServiceObject_p.h +++ b/XNCore/XNServiceObject_p.h @@ -1,21 +1,13 @@ #pragma once #include "XNObject_p.h" -#include -#include -#include "XNEventManager.h" -class XNServiceObjectPrivate : public XNObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNServiceObject) - explicit XNServiceObjectPrivate(XNServiceObject *q) : XNObjectPrivate(q) {} - QString _sDescription; - QString _sAuthor; - QString _sXmlPath; - QDateTime _cCreateTime; - QDateTime _cChangeTime; - QString _sVersion; - QHash _dataWriters; - - XNEventManager *pEventManager; +struct XNServiceObjectPrivate : public XNObjectPrivate { + std::string _sDescription; + std::string _sAuthor; + std::string _sXmlPath; + XNTimePoint _cCreateTime; + XNTimePoint _cChangeTime; + std::string _sVersion; + std::unordered_map _dataWriters; + XNFrameworkPtr pFramework; }; diff --git a/XNCore/XNThread.cpp b/XNCore/XNThread.cpp index 394cf6c..e12b3ab 100755 --- a/XNCore/XNThread.cpp +++ b/XNCore/XNThread.cpp @@ -10,152 +10,65 @@ */ #include "XNLogger.h" #include "XNThread.h" +#include "XNThread_p.h" +#include "XNFramework.h" #include "XNThreadManager.h" #include "XNDDSManager.h" #include "XNIDL/XNSimStatusPubSubTypes.hpp" -/** - * @brief 线程类私有结构体 - */ -class XNThreadPrivate +XNThread::XNThread(std::string name, double freq, uint32_t priority, uint32_t CPUAff) + : XNObject(new XNThreadPrivate()) { -public: - /** - * @brief 宏定义,用于声明公有数据成员 - */ - Q_DECLARE_PUBLIC(XNThread) - - /** - * @brief 构造函数 - * @param q 线程类指针 - */ - explicit XNThreadPrivate(XNThread *q) : q_ptr(q) {} - -private: - /** - * @brief 线程类指针 - */ - XNThread *q_ptr; - /** - * @brief 线程运行频率组 - */ - FreqLevel _eRunFreq = FreqLevel::BaseFreq; - /** - * @brief 线程运行优先级 - */ - quint32 _uPriority = 0; - /** - * @brief 线程CPU亲和性掩码 - * @details 按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。例如:0x00000003表示使用0,1号CPU - */ - quint32 _uAffinity = 0; - /** - * @brief 线程运行频率 - */ - double _setFreq = BASE_RUN_FREQ; - /** - * @brief 线程调度任务表 - */ - QVector > > _funVec; - /** - * @brief pthread线程调度参数 - */ - sched_param param; - /** - * @brief pthread线程属性 - */ - pthread_attr_t attr; - /** - * @brief pthread线程 - */ - pthread_t thread; - /** - * @brief 线程睡眠时间控制 - */ - PERIOD_INFO pinfo; - /** - * @brief 线程控制锁 - */ - pthread_mutex_t _mtx = PTHREAD_MUTEX_INITIALIZER; - /** - * @brief 线程控制条件变量 - */ - pthread_cond_t _cond = PTHREAD_COND_INITIALIZER; - /** - * @brief 线程运行状态 - */ - RunStatus _eRunStatus = RunStatus::NotStart; - /** - * @brief 线程执行进度 - */ - quint32 _RunPosition = 0; - /** - * @brief 线程执行计数 - */ - int count = 0; - /** - * @brief 线程执行时间统计 - */ - timespec _lastRunTime; - /** - * @brief 线程运行状态主题写入器 - */ - FAST_DDS_MACRO::DataWriter *writer; - /** - * @brief 线程ID - */ - quint32 _threadID = 0; -}; - -// 默认构造函数 -XNThread::XNThread(QObject *parent) : QObject(parent), d_ptr(new XNThreadPrivate(this)) -{ -} - -XNThread::XNThread(QObject *parent, QString name, FreqLevel freq, quint32 priority, quint32 CPUAff, - double RunInter) - : QObject(parent), d_ptr(new XNThreadPrivate(this)) -{ - Q_D(XNThread); - setObjectName(name); - d->_eRunFreq = freq; + SetObjectName(name); + T_D(); d->_uPriority = priority; d->_uAffinity = CPUAff; - d->pinfo.period_ns = RunInter; - d->_setFreq = 1.0E9 / RunInter; - InitialFunPool(); + d->pinfo.period_ns = 1.0E9 / freq; + d->_setFreq = freq; + d->_funVec.resize(32); + //InitialFunPool(); } // 默认析构函数 XNThread::~XNThread(void) { - Q_D(XNThread); - delete d; +} + +XNFrameworkPtr XNThread::GetFramework() +{ + T_D(); + return d->_framework; +} + +void XNThread::SetFramework(XNFrameworkPtr framework) +{ + T_D(); + d->_framework = framework; } // 初始化函数 bool XNThread::Initialize() { - Q_D(XNThread); + T_D(); int ret; // 初始化线程参数 ret = pthread_attr_init(&(d->attr)); if (ret) { - LOG_ERROR("0x2210 Thread: %1 Initialize Attribute Failed!", objectName()); + LOG_ERROR("0x2210 Thread: %1 Initialize Attribute Failed!", GetObjectName()); return false; } // 设置线程栈空间大小 ret = pthread_attr_setstacksize(&(d->attr), PTHREAD_STACK_MIN); if (ret) { - LOG_ERROR("0x2211 Thread: %1 Set Stack Space Failed!", objectName()); + LOG_ERROR("0x2211 Thread: %1 Set Stack Space Failed!", GetObjectName()); return false; } // 设置线程调度策略 ret = pthread_attr_setschedpolicy(&(d->attr), SCHED_FIFO); if (ret) { - LOG_ERROR("0x2212 Thread: %1 Set Scheduling Policy Failed!", objectName()); + LOG_ERROR("0x2212 Thread: %1 Set Scheduling Policy Failed!", GetObjectName()); return false; } @@ -163,21 +76,21 @@ bool XNThread::Initialize() d->param.sched_priority = d->_uPriority; ret = pthread_attr_setschedparam(&(d->attr), &d->param); if (ret) { - LOG_ERROR("0x2213 Thread: %1 Set Priority Failed!", objectName()); + LOG_ERROR("0x2213 Thread: %1 Set Priority Failed!", GetObjectName()); return false; } // 设置调度器继承 ret = pthread_attr_setinheritsched(&(d->attr), PTHREAD_EXPLICIT_SCHED); if (ret) { - LOG_ERROR("0x2214 Thread: %1 Set Scheduler Inheritance Failed!", objectName()); + LOG_ERROR("0x2214 Thread: %1 Set Scheduler Inheritance Failed!", GetObjectName()); return false; } // 线程创建 ret = pthread_create(&d->thread, &d->attr, ThreadFunction, this); if (ret) { - LOG_ERROR("0x2215 Thread: %1 Create Failed!", objectName()); + LOG_ERROR("0x2215 Thread: %1 Create Failed!", GetObjectName()); return false; } @@ -186,34 +99,32 @@ bool XNThread::Initialize() return false; } - // if (objectName() == "TimeManagerThread") - // return true; - XNThreadManager *threadManager = qobject_cast(parent()); - if (threadManager == nullptr) { - LOG_WARNING("0x2216 Thread: %1 get ThreadManager Failed!", objectName()); + XNFrameworkPtr framework = GetFramework(); + if (!framework) { + LOG_WARNING("0x2216 Thread: %1 get Framework Failed!", GetObjectName()); return true; } - XNDDSManager *ddsManager = threadManager->parent()->findChild(); - if (ddsManager == nullptr) { - LOG_WARNING("0x2216 Thread: %1 get DDSManager Failed!", objectName()); + XNDDSManagerPtr ddsManager = framework->GetDDSManager(); + if (!ddsManager) { + LOG_WARNING("0x2216 Thread: %1 get DDSManager Failed!", GetObjectName()); return true; } d->writer = ddsManager->RegisterPublisher( "XNSim::XNSimStatus::XNThreadStatus", d->_threadID); if (d->writer == nullptr) { - LOG_WARNING("0x2217 Thread: %1 get DDS Writer Failed!", objectName()); + LOG_WARNING("0x2217 Thread: %1 get DDS Writer Failed!", GetObjectName()); return true; } - LOG_INFO("Thread: %1 is prepared!", objectName()); + LOG_INFO("Thread: %1 is prepared!", GetObjectName()); return true; } // 仿真控制 -void XNThread::OnSimControl(quint32 objectId, SimControlCmd cmd) +void XNThread::SimControl(uint32_t objectId, SimControlCmd cmd) { - Q_D(XNThread); + T_D(); if (objectId == 0) { switch (cmd) { case SimControlCmd::Start: @@ -235,7 +146,7 @@ void XNThread::OnSimControl(quint32 objectId, SimControlCmd cmd) // 开始执行 void XNThread::Start() { - Q_D(XNThread); + T_D(); pthread_mutex_lock(&d->_mtx); // 设置运行状态 if (d->_eRunStatus == RunStatus::NotStart || d->_eRunStatus == RunStatus::Suspend) { @@ -243,26 +154,26 @@ void XNThread::Start() } pthread_cond_signal(&d->_cond); pthread_mutex_unlock(&d->_mtx); - LOG_INFO("Thread: %1 Start!", objectName()); + LOG_INFO("Thread: %1 Start!", GetObjectName()); } // 暂停执行 void XNThread::Pause() { - Q_D(XNThread); + T_D(); pthread_mutex_lock(&d->_mtx); // 设置运行状态 if (d->_eRunStatus == RunStatus::Runing) { d->_eRunStatus = RunStatus::Suspend; } pthread_mutex_unlock(&d->_mtx); - LOG_INFO("Thread: %1 Pause!", objectName()); + LOG_INFO("Thread: %1 Pause!", GetObjectName()); } // 继续执行 void XNThread::Continue() { - Q_D(XNThread); + T_D(); pthread_mutex_lock(&d->_mtx); // 设置运行状态 if (d->_eRunStatus == RunStatus::Suspend) { @@ -275,7 +186,7 @@ void XNThread::Continue() // 停止执行 void XNThread::Stop(bool force) { - Q_D(XNThread); + T_D(); if (force) { pthread_mutex_lock(&d->_mtx); // 设置运行状态 @@ -291,34 +202,34 @@ void XNThread::Stop(bool force) pthread_mutex_unlock(&d->_mtx); Join(); } - LOG_INFO("Thread: %1 Stop!", objectName()); + LOG_INFO("Thread: %1 Stop!", GetObjectName()); } // 加入线程 void XNThread::Join() { - Q_D(XNThread); + T_D(); pthread_join(d->thread, NULL); } // 分离线程 void XNThread::Detach() { - Q_D(XNThread); + T_D(); pthread_detach(d->thread); } // 获取线程运行状态 RunStatus XNThread::GetRunStatus() { - Q_D(XNThread); + T_D(); return d->_eRunStatus; } // 向线程添加周期性函数 -void XNThread::AddFunction(XNCallBack fun, FreqLevel freq, quint32 pos, quint32 priorty) +void XNThread::AddFunction(XNCallBack fun, FreqLevel freq, uint32_t pos, uint32_t priorty) { - Q_D(XNThread); + T_D(); for (int i = 0; i < d->_funVec.size();) { if (i + pos >= d->_funVec.size()) break; @@ -350,60 +261,51 @@ void XNThread::AddFunction(XNCallBack fun, FreqLevel freq, quint32 pos, quint32 } // 获取线程运行频率 -const FreqLevel &XNThread::GetRunFrequecy() +const double &XNThread::GetRunFrequecy() { - Q_D(XNThread); - return d->_eRunFreq; + T_D(); + return d->_setFreq; } // 设置线程运行频率 -void XNThread::SetRunFrequecy(const FreqLevel &eRunFrequecy) +void XNThread::SetRunFrequecy(const double &dRunFrequecy) { - Q_D(XNThread); - d->_eRunFreq = eRunFrequecy; - InitialFunPool(); + T_D(); + d->_setFreq = dRunFrequecy; } // 获取线程运行优先级 -const quint32 &XNThread::GetRunPriority() +const uint32_t &XNThread::GetRunPriority() { - Q_D(XNThread); + T_D(); return d->_uPriority; } // 设置线程运行优先级 -void XNThread::SetRunPriority(const quint32 &uRunPriority) +void XNThread::SetRunPriority(const uint32_t &uRunPriority) { - Q_D(XNThread); + T_D(); d->_uPriority = uRunPriority; } // 获取线程CPU亲和性掩码 -const quint32 &XNThread::GetCPUAffinity() +const uint32_t &XNThread::GetCPUAffinity() { - Q_D(XNThread); + T_D(); return d->_uAffinity; } // 设置线程CPU亲和性掩码 -void XNThread::SetCPUAffinity(const quint32 &uCPUAffinity) +void XNThread::SetCPUAffinity(const uint32_t &uCPUAffinity) { - Q_D(XNThread); + T_D(); d->_uAffinity = uCPUAffinity; } -// 设置线程运行间隔 -void XNThread::SetRunInter(const double &dRunInter) -{ - Q_D(XNThread); - d->pinfo.period_ns = dRunInter; - d->_setFreq = 1.0E9 / dRunInter; -} - // 获取线程运行间隔 -void XNThread::OnSetStartTime(const timespec &startTime) +void XNThread::SetStartTime(const timespec &startTime) { - Q_D(XNThread); + T_D(); d->pinfo.next_period = startTime; d->_lastRunTime = startTime; } @@ -411,7 +313,7 @@ void XNThread::OnSetStartTime(const timespec &startTime) // 执行线程CPU亲和性设置 bool XNThread::OnSetCPUAffinity() { - Q_D(XNThread); + T_D(); cpu_set_t mask; CPU_ZERO(&mask); int cpuNum = sysconf(_SC_NPROCESSORS_CONF); @@ -420,7 +322,7 @@ bool XNThread::OnSetCPUAffinity() CPU_SET(i, &mask); } if (pthread_setaffinity_np(d->thread, sizeof(mask), &mask) == -1) { - LOG_WARNING("0x2216 线程: %1 设置CPU亲和性失败!", objectName()); + LOG_WARNING("0x2216 线程: %1 设置CPU亲和性失败!", GetObjectName()); return false; } return true; @@ -430,7 +332,8 @@ bool XNThread::OnSetCPUAffinity() void *XNThread::ThreadFunction(void *args) { // 获取创建线程类的私有变量结构体指针 - XNThreadPrivate *temp = ((XNThread *)args)->d_ptr; + ThisType *thisPtr = (ThisType *)args; + PrivateType *temp = thisPtr->GetPP(); // 获取当前时间 // clock_gettime(CLOCK_MONOTONIC, &(temp->pinfo.next_period)); @@ -461,7 +364,7 @@ void *XNThread::ThreadFunction(void *args) // 任务执行 auto &funMap = temp->_funVec[temp->_RunPosition++]; for (auto &funv : funMap) { - for (auto &fun : funv) { + for (auto &fun : funv.second) { fun(); } } @@ -476,16 +379,16 @@ void *XNThread::ThreadFunction(void *args) pthread_mutex_unlock(&temp->_mtx); // 填写DDS主题数据 - quint32 setFreq = (1.0E9 / temp->pinfo.period_ns) < 1.0 ? 1 : (quint32)temp->_setFreq; + uint32_t setFreq = (1.0E9 / temp->pinfo.period_ns) < 1.0 ? 1 : (uint32_t)temp->_setFreq; if (temp->writer != nullptr && temp->count > 0 && temp->count % setFreq == 0) { timespec now; clock_gettime(CLOCK_MONOTONIC, &now); double seconds = (double)(now.tv_sec - temp->_lastRunTime.tv_sec) + (double)(now.tv_nsec - temp->_lastRunTime.tv_nsec) / 1.0E9; XNSim::XNSimStatus::XNThreadStatus threadStatus; - threadStatus.XNThreadName(temp->q_ptr->objectName().toStdString()); + threadStatus.XNThreadName(thisPtr->GetObjectName()); threadStatus.XNThreadID(pthread_self()); - threadStatus.XNThreadSt((quint32)temp->_eRunStatus); + threadStatus.XNThreadSt((uint32_t)temp->_eRunStatus); threadStatus.XNThreadAff(temp->_uAffinity); threadStatus.XNThreadPro(temp->_uPriority); threadStatus.XNThRunCnt(temp->count); @@ -494,7 +397,7 @@ void *XNThread::ThreadFunction(void *args) temp->writer->write(&threadStatus); temp->_lastRunTime = now; LOG_DEBUG("Thread: %1 Write DDS! SetFreq: %2 Hz, CurFreq: %3 Hz", - temp->q_ptr->objectName(), temp->_setFreq, temp->_setFreq / seconds); + thisPtr->GetObjectName(), temp->_setFreq, temp->_setFreq / seconds); } temp->count++; @@ -514,43 +417,43 @@ void *XNThread::ThreadFunction(void *args) return nullptr; } -// 初始化线程调度表 -void XNThread::InitialFunPool() -{ - Q_D(XNThread); - // 设置循环表长度 - switch (d->_eRunFreq) { - case FreqLevel::BaseFreq: - d->_funVec.resize(32); - break; - case FreqLevel::HalfFreq: - d->_funVec.resize(16); - break; - case FreqLevel::QuarterFreq: - d->_funVec.resize(8); - break; - case FreqLevel::EighthFreq: - d->_funVec.resize(4); - break; - case FreqLevel::SixteenthFreq: - d->_funVec.resize(2); - break; - default: - d->_funVec.resize(1); - break; - } -} +// // 初始化线程调度表 +// void XNThread::InitialFunPool() +// { +// T_D(); +// // 设置循环表长度 +// switch (d->_eRunFreq) { +// case FreqLevel::BaseFreq: +// d->_funVec.resize(32); +// break; +// case FreqLevel::HalfFreq: +// d->_funVec.resize(16); +// break; +// case FreqLevel::QuarterFreq: +// d->_funVec.resize(8); +// break; +// case FreqLevel::EighthFreq: +// d->_funVec.resize(4); +// break; +// case FreqLevel::SixteenthFreq: +// d->_funVec.resize(2); +// break; +// default: +// d->_funVec.resize(1); +// break; +// } +// } // 获取线程ID -const quint32 &XNThread::GetThreadID() +const uint32_t &XNThread::GetThreadID() { - Q_D(XNThread); + T_D(); return d->_threadID; } // 设置线程ID -void XNThread::SetThreadID(const quint32 &threadID) +void XNThread::SetThreadID(const uint32_t &threadID) { - Q_D(XNThread); + T_D(); d->_threadID = threadID; } diff --git a/XNCore/XNThread.h b/XNCore/XNThread.h index 936140e..87e1bd0 100755 --- a/XNCore/XNThread.h +++ b/XNCore/XNThread.h @@ -9,36 +9,43 @@ * */ #pragma once -#include -#include -#include "XNCore_global.h" +#include "XNObject.h" -class XNThreadPrivate; +struct XNThreadPrivate; /** * @brief 调度线程类 * @details 调度所有模型提交的周期性执行函数 */ -class XNCORE_EXPORT XNThread : public QObject +class XNCORE_EXPORT XNThread : public XNObject { - Q_OBJECT - Q_DISABLE_COPY(XNThread) - Q_DECLARE_PRIVATE(XNThread) + XN_METATYPE(XNThread, XNObject) + XN_DECLARE_PRIVATE(XNThread) public: - explicit XNThread(QObject *parent = nullptr); - XNThread(QObject *parent = nullptr, QString name = "", FreqLevel freq = FreqLevel::BaseFreq, - quint32 priority = 99, quint32 CPUAff = 0, double RunInter = BASE_RUN_INTER); + XNThread() = delete; -protected: - XNThreadPrivate *d_ptr; - -public: /** * @brief 默认析构函数 */ virtual ~XNThread(); + explicit XNThread(std::string name = "", double freq = BASE_RUN_FREQ, uint32_t priority = 99, + uint32_t CPUAff = 0); + +public: + /** + * @brief 获取框架对象 + * @return 框架对象 + */ + XNFrameworkPtr GetFramework(); + + /** + * @brief 设置框架对象 + * @param framework 框架对象 + */ + void SetFramework(XNFrameworkPtr framework); + /** * @brief 线程初始化 * @return true: 初始化成功 @@ -46,26 +53,19 @@ public: */ bool Initialize(); -public slots: /** * @brief 仿真控制 * @param objectId: 对象ID * @param cmd: 仿真控制命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); + void SimControl(uint32_t objectId, SimControlCmd cmd); /** * @brief 设置线程运行的开始时间 * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 * @details 通过设置统一的开始时间,使个线程能同步执行 */ - void OnSetStartTime(const timespec &simTime); - - /** - * @brief 设置线程运行间隔 - * @param dRunInter: double类型,线程运行间隔,单位纳秒 - */ - void SetRunInter(const double &dRunInter); + void SetStartTime(const timespec &simTime); /** * @brief 加入线程 @@ -78,19 +78,73 @@ public slots: */ void Detach(); -public: /** * @brief 获取线程ID * @return const quint32&: 线程ID */ - const quint32 &GetThreadID(); + const uint32_t &GetThreadID(); /** * @brief 设置线程ID * @param threadID: 线程ID */ - void SetThreadID(const quint32 &threadID); + void SetThreadID(const uint32_t &threadID); + /** + * @brief 获取运行状态 + * @return RunStatus: 运行状态枚举 + */ + RunStatus GetRunStatus(); + + /** + * @brief 获取线程运行频率 + * @return const double&:线程运行频率 + */ + const double &GetRunFrequecy(); + + /** + * @brief 设置线程运行频率 + * @param eRunFrequecy: double类型,线程运行频率 + */ + void SetRunFrequecy(const double &dRunFrequecy); + + /** + * @brief 获取线程运行优先级 + * @return const UINT32&:运行优先级,0~99,99最高 + */ + const uint32_t &GetRunPriority(); + + /** + * @brief 设置线程运行优先级 + * @param uRunPriority: UINT32类型,运行优先级,0~99,99最高 + */ + void SetRunPriority(const uint32_t &uRunPriority); + + /** + * @brief 设置线程CPU亲和性掩码 + * @return const UINT32&: CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + */ + const uint32_t &GetCPUAffinity(); + + /** + * @brief 获取线程CPU亲和性掩码 + * @param uCPUAffinity: UINT32类型,CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + */ + void SetCPUAffinity(const uint32_t &uCPUAffinity); + + /** + * @brief 向线程添加周期性函数 + * @param fun:XNCallBack函数包装器类型,需要提交的函数的包装 + * @param freq:FreqLevel类型,提交的函数运行频率组 + * @param pos:UINT32类型,提交的函数运行节点号 + * @param priorty:UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 + * @details 根据运行频率组和节点号向调度线程任务表中添加周期性函数 + */ + void AddFunction(XNCallBack fun, FreqLevel freq, uint32_t pos, uint32_t priorty); + +private: /** * @brief 控制线程开始 * @return true: 线程启动成功 @@ -120,61 +174,6 @@ public: */ void Stop(bool force = false); - /** - * @brief 获取运行状态 - * @return RunStatus: 运行状态枚举 - */ - RunStatus GetRunStatus(); - - /** - * @brief 获取线程运行频率族 - * @return const FreqLevel&:线程运行频率族 - */ - const FreqLevel &GetRunFrequecy(); - - /** - * @brief 设置线程运行频率族 - * @param eRunFrequecy: FreqLevel枚举类,线程运行频率族 - */ - void SetRunFrequecy(const FreqLevel &eRunFrequecy); - - /** - * @brief 获取线程运行优先级 - * @return const UINT32&:运行优先级,0~99,99最高 - */ - const quint32 &GetRunPriority(); - - /** - * @brief 设置线程运行优先级 - * @param uRunPriority: UINT32类型,运行优先级,0~99,99最高 - */ - void SetRunPriority(const quint32 &uRunPriority); - - /** - * @brief 设置线程CPU亲和性掩码 - * @return const UINT32&: CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 - * 例如:0x00000003表示使用0,1号CPU - */ - const quint32 &GetCPUAffinity(); - - /** - * @brief 获取线程CPU亲和性掩码 - * @param uCPUAffinity: UINT32类型,CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 - * 例如:0x00000003表示使用0,1号CPU - */ - void SetCPUAffinity(const quint32 &uCPUAffinity); - - /** - * @brief 向线程添加周期性函数 - * @param fun:XNCallBack函数包装器类型,需要提交的函数的包装 - * @param freq:FreqLevel类型,提交的函数运行频率组 - * @param pos:UINT32类型,提交的函数运行节点号 - * @param priorty:UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 - * @details 根据运行频率组和节点号向调度线程任务表中添加周期性函数 - */ - void AddFunction(XNCallBack fun, FreqLevel freq, quint32 pos, quint32 priorty); - -private: /** * @brief 执行线程CPU亲和性设置 * @return true: 设置线程CPU亲和性成功 @@ -189,8 +188,10 @@ private: */ static void *ThreadFunction(void *args); - /** - * @brief 初始化周期性函数表 - */ - void InitialFunPool(); -}; \ No newline at end of file + // /** + // * @brief 初始化周期性函数表 + // */ + //void InitialFunPool(); +}; + +XNCLASS_PTR_DECLARE(XNThread) \ No newline at end of file diff --git a/XNCore/XNThreadManager.cpp b/XNCore/XNThreadManager.cpp index effa636..a3637ad 100755 --- a/XNCore/XNThreadManager.cpp +++ b/XNCore/XNThreadManager.cpp @@ -11,39 +11,40 @@ #include "XNThreadManager.h" #include "XNThreadManager_p.h" #include "XNFramework.h" +#include "XNTimeManager.h" #include "XNModelManager.h" // 默认构造函数 -XNThreadManager::XNThreadManager(QObject *parent) - : XNBaseFrameObject(*new XNThreadManagerPrivate(this), parent) +XNThreadManager::XNThreadManager() : XNBaseFrameObject(new XNThreadManagerPrivate()) { - setUniqueId(3); - setObjectName("XNThreadManager"); + SetUniqueId(3); + SetObjectName("XNThreadManager"); } XNThreadManager::~XNThreadManager() { } -XNThreadManager::XNThreadManager(XNThreadManagerPrivate &dd, QObject *parent) - : XNBaseFrameObject(dd, parent) +XNThreadManager::XNThreadManager(PrivateType *p) : XNBaseFrameObject(p) { } // 初始化函数 -void XNThreadManager::OnInitialize() +bool XNThreadManager::Initialize() { - Q_D(XNThreadManager); + T_D(); d->_eRunStatus = RunStatus::NotStart; + d->threadList.clear(); + d->funList.clear(); LOG_INFO("XNThreadManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; - emit Initialize(); + return true; } // 开始控制 -void XNThreadManager::OnStart() +void XNThreadManager::Start() { - Q_D(XNThreadManager); + T_D(); // 如果当前状态是未开始状态 if (d->_eRunStatus == RunStatus::NotStart) { // 状态切换为正在运行 @@ -52,9 +53,9 @@ void XNThreadManager::OnStart() } // 停止控制 -void XNThreadManager::OnAbort() +void XNThreadManager::Abort() { - Q_D(XNThreadManager); + T_D(); // 如果当前状态不是停止状态 if (d->_eRunStatus != RunStatus::Aborted) { // 状态切换为停止 @@ -63,9 +64,9 @@ void XNThreadManager::OnAbort() } // 暂停控制 -void XNThreadManager::OnPause() +void XNThreadManager::Pause() { - Q_D(XNThreadManager); + T_D(); // 如果当前是正在运行状态 if (d->_eRunStatus == RunStatus::Runing) { // 状态切换为暂停 @@ -74,9 +75,9 @@ void XNThreadManager::OnPause() } // 继续控制 -void XNThreadManager::OnContinue() +void XNThreadManager::Continue() { - Q_D(XNThreadManager); + T_D(); // 如果当前是暂停状态 if (d->_eRunStatus == RunStatus::Suspend) { //TODO 这里需要重新设置一下时间信息,不然启动后会加速运行至设定的时间 @@ -88,49 +89,46 @@ void XNThreadManager::OnContinue() // 获取当前运行状态 RunStatus XNThreadManager::GetStatus() { - Q_D(XNThreadManager); + T_D(); return d->_eRunStatus; } // 添加周期性函数 -void XNThreadManager::OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, - quint32 RunPos, quint32 RunPriorty) +void XNThreadManager::RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, + uint32_t freqGroup, uint32_t RunPos, uint32_t RunPriorty) { - Q_D(XNThreadManager); + T_D(); // 如果周期性函数校验通过 if (IsFunParamRight(id, freqGroup, RunPos)) { // 存储提交的函数 - funInfoPtr sFunInfo = funInfoPtr::create(); + funInfoPtr sFunInfo = std::make_shared(); sFunInfo->fun = fun; + sFunInfo->threadID = threadID; sFunInfo->freqGroup = freqGroup; sFunInfo->RunPos = RunPos; sFunInfo->RunPriority = RunPriorty; d->funList[id].push_back(sFunInfo); - // 加入线程任务池 - auto threadPool = this->findChildren(); - for (auto thread : threadPool) { - if ((quint32)thread->GetRunFrequecy() == freqGroup) { - thread->AddFunction(fun, (FreqLevel)freqGroup, RunPos, RunPriorty); - break; - } + if (d->threadList.find(threadID) != d->threadList.end()) { + d->threadList[threadID]->AddFunction(fun, (FreqLevel)freqGroup, RunPos, RunPriorty); + LOG_INFO("Model [ %1] register periodic function success! Run node: %2-%3 Priority: %4", + id, freqGroup, RunPos, RunPriorty); + } else { + LOG_ERROR("0x2172 The thread [ %1 ] does not exist, registration failed!", threadID); } - LOG_INFO("Model [ %1] register periodic function success! Run node: %2-%3 Priority: %4", id, - freqGroup, RunPos, RunPriorty); } } // 注册函数校验 -bool XNThreadManager::IsFunParamRight(quint32 id, quint32 freqGroup, quint32 RunPos) +bool XNThreadManager::IsFunParamRight(uint32_t id, uint32_t freqGroup, uint32_t RunPos) { - quint32 ufreq = freqGroup; // 检查提交的函数是否符合规定 - if (ufreq < 0 || ufreq > 5) { + if (freqGroup < 0 || freqGroup > 5) { // 如果频率分组不是0~5 LOG_WARNING("0x2170 The submitted function's run frequency group of Model [ %1 ] is not " "between 0 and 5, registration failed!", id); return false; - } else if (RunPos > pow(2, freqGroup)) { + } else if (RunPos > (1 << freqGroup)) { // 如果运行节点不符合要求 LOG_WARNING("0x2171 The run node submitted for registration by model [ %1 ] exceeds the " "maximum node count for the frequency group, registration failed!", @@ -141,115 +139,89 @@ bool XNThreadManager::IsFunParamRight(quint32 id, quint32 freqGroup, quint32 Run } // 仿真运行前做最后处理 -void XNThreadManager::OnPrepareForExecute() +bool XNThreadManager::PrepareForExecute() { - Q_D(XNThreadManager); + T_D(); PERIOD_INFO pinfo; clock_gettime(CLOCK_MONOTONIC, &(pinfo.next_period)); - emit SetStartTime(pinfo.next_period); + for (auto &thread : d->threadList) { + thread.second->SetStartTime(pinfo.next_period); + } + //设置开始事件 + auto framework = GetFramework(); + if (framework) { + auto timeManager = framework->GetTimeManager(); + if (timeManager) { + timeManager->SetStartTime(pinfo.next_period); + } + } // 所有线程初始化 LOG_INFO("XNThreadManager is preparing..."); - auto threadPool = this->findChildren(); - for (auto &thread : threadPool) { - bool bRet = thread->Initialize(); + for (auto &thread : d->threadList) { + bool bRet = thread.second->Initialize(); if (!bRet) { - emit PrepareForExecuteFailed(); - return; + LOG_ERROR("Thread [ %1 ] PrepareForExecute Failed!", thread.first); + continue; } } d->_status = XNFrameObjectStatus::Ready; - // 通知模型管理器进行最后准备 LOG_INFO("XNThreadManager is prepared!"); - emit PrepareForExecute(); + return true; } // 添加线程 -void XNThreadManager::OnAddThreadPool(QString name, FreqLevel freq, quint32 priority, - quint32 CPUAff, double RunInter) +uint32_t XNThreadManager::AddThreadPool(std::string name, double freq, uint32_t priority, + uint32_t CPUAff) { - Q_D(XNThreadManager); + T_D(); // 创建线程对象 - XNThread *thread = new XNThread(this, name, freq, priority, CPUAff, RunInter); - // 连接信号和槽 - //connect(this, &XNThreadManager::SetRunInter, thread, &XNThread::SetRunInter); - connect(this, &XNThreadManager::SetStartTime, thread, &XNThread::OnSetStartTime); - connect(this, &XNThreadManager::SimControl, thread, &XNThread::OnSimControl); + XNThreadPtr thread = std::make_shared(name, freq, priority, CPUAff); thread->SetThreadID(AllocateThreadID()); - LOG_INFO("Add Thread Success, Frequency: %1 Hz, Interval: %2 ns.", - d->dRunFreq / pow(2, (quint32)freq), RunInter); - d->threadCount++; + LOG_INFO("Add Thread Success, Frequency: %1 Hz, Interval: %2 ns.", freq, 1.0e9 / freq); + d->threadList[thread->GetThreadID()] = thread; + return thread->GetThreadID(); } -void XNThreadManager::OnSimControl(quint32 objectId, SimControlCmd cmd) +void XNThreadManager::SimControl(uint32_t objectId, SimControlCmd cmd) { + T_D(); if (objectId == 0) { switch (cmd) { case SimControlCmd::Start: - OnStart(); + Start(); break; case SimControlCmd::Abort: - OnAbort(); + Abort(); break; case SimControlCmd::Continue: - OnContinue(); + Continue(); break; case SimControlCmd::Suspend: - OnPause(); + Pause(); break; } } - emit SimControl(objectId, cmd); -} - -// 设置模型运行基频 -void XNThreadManager::OnSetBaseFreq(const double &dBaseFreq) -{ - Q_D(XNThreadManager); - d->dRunFreq = dBaseFreq; - d->dRunInter = 1.0e9 / dBaseFreq; - //emit SetRunInter(d->dRunInter); - LOG_INFO("Set engine base run frequency to %1 Hz, interval: %2 ns.", d->dRunFreq, d->dRunInter); -} - -// 获得模型运行基频 -const double &XNThreadManager::GetBaseFreq() -{ - Q_D(XNThreadManager); - return d->dRunFreq; -} - -// 获得模型运行基础间隔 -const double &XNThreadManager::GetBaseInter() -{ - Q_D(XNThreadManager); - return d->dRunInter; -} - -// 通过运行间隔设置基频 -void XNThreadManager::SetBaseFreqByInter(const double &dBaseInter) -{ - Q_D(XNThreadManager); - d->dRunFreq = 1.0e9 / dBaseInter; - d->dRunInter = dBaseInter; - LOG_INFO("Set engine base run frequency to %1 Hz, interval: %2 ns.", d->dRunFreq, d->dRunInter); + for (auto &thread : d->threadList) { + thread.second->SimControl(objectId, cmd); + } } // 获取线程数量 -quint32 XNThreadManager::GetThreadCount() +uint32_t XNThreadManager::GetThreadCount() { - Q_D(XNThreadManager); - return d->threadCount; + T_D(); + return d->threadList.size(); } // 分配线程ID -quint32 XNThreadManager::AllocateThreadID() +uint32_t XNThreadManager::AllocateThreadID() { - Q_D(XNThreadManager); + T_D(); //从5000到9999分配线程ID - static quint32 threadID = 5000; - while (d->threadIDMap.contains(threadID)) { + static uint32_t threadID = 5000; + while (d->threadList.find(threadID) != d->threadList.end()) { threadID++; } - d->threadIDMap.insert(threadID); + d->threadList[threadID] = nullptr; return threadID; } diff --git a/XNCore/XNThreadManager.h b/XNCore/XNThreadManager.h index e5ef942..968a90d 100755 --- a/XNCore/XNThreadManager.h +++ b/XNCore/XNThreadManager.h @@ -11,7 +11,7 @@ #pragma once #include "XNBaseFrameObject.h" -class XNThreadManagerPrivate; +struct XNThreadManagerPrivate; /** * @brief 线程管理器类 @@ -19,15 +19,14 @@ class XNThreadManagerPrivate; */ class XNThreadManager : public XNBaseFrameObject { - Q_OBJECT - Q_DECLARE_PRIVATE(XNThreadManager) - Q_DISABLE_COPY(XNThreadManager) + XN_METATYPE(XNThreadManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNThreadManager) public: /** * @brief 线程管理器类默认构造函数 */ - explicit XNThreadManager(QObject *parent = nullptr); + XNThreadManager(); /** * @brief 线程管理器类析构函数 @@ -41,53 +40,32 @@ protected: * @param parent:QObject类型,父对象指针 * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 */ - XNThreadManager(XNThreadManagerPrivate &dd, QObject *parent = nullptr); + XNThreadManager(PrivateType *p); -signals: - /** - * @brief 设置仿真开始时间信号 - * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 - * @details 通过设置统一的开始时间,使个线程能同步执行 - */ - void SetStartTime(const timespec &simTime); - - /** - * @brief 设置线程运行间隔信号 - * @param dRunInter: double类型,线程运行间隔,单位纳秒 - */ - void SetRunInter(const double &dRunInter); - - /** - * @brief 仿真控制信号 - * @param objectId: 对象ID - * @param cmd: 仿真控制命令 - */ - void SimControl(quint32 objectId, SimControlCmd cmd); - -public slots: +public: /** * @brief 开始控制 * @details 控制线程管理器开始运行接口 */ - void OnStart(); + void Start(); /** * @brief 停止控制 * @details 控制线程管理器停止运行接口 */ - void OnAbort(); + void Abort(); /** * @brief 暂停控制 * @details 控制线程管理器暂停运行接口 */ - void OnPause(); + void Pause(); /** * @brief 继续控制 * @details 控制线程管理器继续运行接口 */ - void OnContinue(); + void Continue(); /** * @brief 初始化线程管理器 @@ -95,29 +73,21 @@ public slots: * @return false: 初始化失败 * @details 线程管理器的初始化接口函数 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 仿真运行前最后处理 * @note 线程管理器在所有线程开始执行前的准备工作 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 仿真控制 * @param objectId: 对象ID * @param cmd: 仿真控制命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); + void SimControl(uint32_t objectId, SimControlCmd cmd); - /** - * @brief 设置仿真系统运行基频 - * @param dBaseFreq: double类型,频率值,单位Hz - * @details 仿真系统所有线程以此基频的 1 或 1/2 或 1/4 或 1/8 或 1/16 或 1/32 倍运行 - */ - void OnSetBaseFreq(const double &dBaseFreq); - -public: /** * @brief 获取运行状态 * @return RunStatus: 枚举类,线程运行状态 @@ -125,50 +95,29 @@ public: */ RunStatus GetStatus(); - /** - * @brief 获得仿真系统运行基频 - * @return const double&: 频率值,单位Hz - */ - const double &GetBaseFreq(); - - /** - * @brief 获得仿真系统运行基础间隔 - * @return const double&: 运行周期值,单位纳秒 - * @details 模型基础运行间隔由基频计算获得 - */ - const double &GetBaseInter(); - - /** - * @brief 通过运行间隔设置基频 - * @param dBaseInter:double类型,运行周期值,单位纳秒 - * @details 使用运行间隔计算得到基频并设置 - */ - void SetBaseFreqByInter(const double &dBaseInter); - /** * @brief 获取线程数量 * @return quint32: 线程数量 */ - quint32 GetThreadCount(); + uint32_t GetThreadCount(); -public slots: /** * @brief 添加一个线程 * @param name: XNString类型,线程名称 - * @param freq: FreqLevel枚举类型,线程运行频率组 + * @param freq: double类型,线程运行频率,单位Hz * @param priority: UINT32类型,线程运行优先级,99~0,优先级数值越大,优先级越高 * @param CPUAff: UINT32类型,线程的CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 * 例如:0x00000003表示使用0,1号CPU - * @param RunInter: double类型,线程的运行周期,单位纳秒 * @details 按照设置的参数创建线程 */ - virtual void OnAddThreadPool(QString name, FreqLevel freq, quint32 priority, quint32 CPUAff, - double RunInter); + virtual uint32_t AddThreadPool(std::string name, double freq, uint32_t priority, + uint32_t CPUAff); /** * @brief 向线程中添加周期性函数 * @param id: UINT32类型,模型全局唯一ID * @param fun: XNCallBack函数包装器类型,需要提交的函数的包装 + * @param threadID: UINT32类型,线程ID * @param freqGroup: UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) * @param RunPriorty: UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 @@ -176,8 +125,8 @@ public slots: * @return false: 添加失败 * @details 根据运行频率组和节点号向对应的线程中添加周期性函数 */ - void OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos, - quint32 RunPriorty); + void RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID, uint32_t freqGroup, + uint32_t RunPos, uint32_t RunPriorty); private: /** @@ -187,7 +136,7 @@ private: * @return true:提交的函数频率与节点号符合规则 * @return false:提交的函数频率与节点号不符合规则 */ - bool IsFunParamRight(quint32 ModelID, quint32 freqGroup, quint32 RunPos); + bool IsFunParamRight(uint32_t ModelID, uint32_t freqGroup, uint32_t RunPos); - quint32 AllocateThreadID(); + uint32_t AllocateThreadID(); }; \ No newline at end of file diff --git a/XNCore/XNThreadManager_p.h b/XNCore/XNThreadManager_p.h index a3f4686..ecc2bd3 100755 --- a/XNCore/XNThreadManager_p.h +++ b/XNCore/XNThreadManager_p.h @@ -20,55 +20,46 @@ struct funInfo { * @brief 周期性函数包装器 */ XNCallBack fun; + /** + * @brief 线程ID + */ + uint32_t threadID; /** * @brief 运行频率组 */ - quint32 freqGroup; + uint32_t freqGroup; /** * @brief 运行节点 */ - quint32 RunPos; + uint32_t RunPos; /** * @brief 运行优先级 */ - quint32 RunPriority; + uint32_t RunPriority; }; /** * @brief 声明周期性函数存储结构体的智能指针 */ -using funInfoPtr = QSharedPointer; +using funInfoPtr = std::shared_ptr; /** * @brief 线程管理器类私有结构体 */ -class XNThreadManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - XNThreadManagerPrivate(XNThreadManager *q) : XNBaseFrameObjectPrivate(q) {} - Q_DECLARE_PUBLIC(XNThreadManager) -private: +struct XNThreadManagerPrivate : public XNBaseFrameObjectPrivate { /** * @brief 所有线程运行状态 */ RunStatus _eRunStatus; + /** + * @brief 线程列表 + */ + std::map threadList; /** * @brief 周期性函数存储列表 */ - QMap > funList; - /** - * @brief 基础运行频率 - */ - double dRunFreq = BASE_RUN_FREQ; - /** - * @brief 基础运行间隔 - */ - double dRunInter = BASE_RUN_INTER; + std::map > funList; /** * @brief 线程ID */ - QSet threadIDMap; - /** - * @brief 线程数量 - */ - quint32 threadCount = 0; + std::set threadIDMap; }; diff --git a/XNCore/XNThread_p.h b/XNCore/XNThread_p.h new file mode 100644 index 0000000..654eefe --- /dev/null +++ b/XNCore/XNThread_p.h @@ -0,0 +1,76 @@ +#pragma once +#include "XNObject_p.h" +/** + * @brief 线程类私有结构体 + */ +struct XNThreadPrivate : public XNObjectPrivate { + /** + * @brief 框架对象 + */ + XNFrameworkPtr _framework; + /** + * @brief 线程运行优先级 + */ + uint32_t _uPriority = 0; + /** + * @brief 线程CPU亲和性掩码 + * @details 按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。例如:0x00000003表示使用0,1号CPU + */ + uint32_t _uAffinity = 0; + /** + * @brief 线程运行频率 + */ + double _setFreq = BASE_RUN_FREQ; + /** + * @brief 线程调度任务表 + */ + std::vector > > _funVec; + /** + * @brief pthread线程调度参数 + */ + sched_param param; + /** + * @brief pthread线程属性 + */ + pthread_attr_t attr; + /** + * @brief pthread线程 + */ + pthread_t thread; + /** + * @brief 线程睡眠时间控制 + */ + PERIOD_INFO pinfo; + /** + * @brief 线程控制锁 + */ + pthread_mutex_t _mtx = PTHREAD_MUTEX_INITIALIZER; + /** + * @brief 线程控制条件变量 + */ + pthread_cond_t _cond = PTHREAD_COND_INITIALIZER; + /** + * @brief 线程运行状态 + */ + RunStatus _eRunStatus = RunStatus::NotStart; + /** + * @brief 线程执行进度 + */ + uint32_t _RunPosition = 0; + /** + * @brief 线程执行计数 + */ + int count = 0; + /** + * @brief 线程执行时间统计 + */ + timespec _lastRunTime; + /** + * @brief 线程运行状态主题写入器 + */ + FAST_DDS_MACRO::DataWriter *writer; + /** + * @brief 线程ID + */ + uint32_t _threadID = 0; +}; diff --git a/XNCore/XNTimeManager.cpp b/XNCore/XNTimeManager.cpp index 39805ae..d2098c8 100755 --- a/XNCore/XNTimeManager.cpp +++ b/XNCore/XNTimeManager.cpp @@ -12,47 +12,46 @@ #include "XNTimeManager_p.h" #include "XNDDSManager.h" #include "XNThreadManager.h" +#include "XNFramework.h" #include "XNIDL/XNSimStatusPubSubTypes.hpp" typedef std::shared_ptr XNThreadPtr; -XNTimeManager::XNTimeManager(QObject *parent) - : XNBaseFrameObject(*new XNTimeManagerPrivate(this), parent) +XNTimeManager::XNTimeManager() : XNBaseFrameObject(new XNTimeManagerPrivate()) { - setUniqueId(2); - setObjectName("XNTimeManager"); + SetUniqueId(2); + SetObjectName("XNTimeManager"); } XNTimeManager::~XNTimeManager() { } -XNTimeManager::XNTimeManager(XNTimeManagerPrivate &dd, QObject *parent) - : XNBaseFrameObject(dd, parent) +XNTimeManager::XNTimeManager(PrivateType *p) : XNBaseFrameObject(p) { } -QDateTime XNTimeManager::GetSimTime() +std::chrono::system_clock::time_point XNTimeManager::GetSimTime() { - Q_D(XNTimeManager); + T_D(); pthread_mutex_lock(&(d->_mtx)); - QDateTime sSimTime = d->_SimTime; + auto simTime = d->_SimTime; pthread_mutex_unlock(&(d->_mtx)); - return sSimTime; + return simTime; } -void XNTimeManager::OnSetStartTime(const timespec &simTime) +void XNTimeManager::SetStartTime(const timespec &simTime) { - Q_D(XNTimeManager); - d->_SimStartTime = QDateTime::fromSecsSinceEpoch(simTime.tv_sec); - d->_SimStartTime = d->_SimStartTime.addMSecs(simTime.tv_nsec / 1000000.0); - //d->_TimeManagerThread->OnSetStartTime(simTime); - //d->_TimeManagerThread->Initialize(); + T_D(); + // 将timespec转换为chrono::system_clock::time_point + auto duration = + std::chrono::seconds(simTime.tv_sec) + std::chrono::nanoseconds(simTime.tv_nsec); + d->_SimStartTime = std::chrono::system_clock::time_point(duration); } -void XNTimeManager::OnStart() +void XNTimeManager::Start() { - Q_D(XNTimeManager); + T_D(); if (d->_eRunStatus == RunStatus::NotStart) { LOG_INFO("XNSim Start!"); d->_eRunStatus = RunStatus::Runing; @@ -61,9 +60,9 @@ void XNTimeManager::OnStart() } } -void XNTimeManager::OnAbort() +void XNTimeManager::Abort() { - Q_D(XNTimeManager); + T_D(); if (d->_eRunStatus != RunStatus::Aborted) { LOG_INFO("XNSim Abort!"); d->_eRunStatus = RunStatus::Aborted; @@ -72,9 +71,9 @@ void XNTimeManager::OnAbort() } } -void XNTimeManager::OnPause() +void XNTimeManager::Pause() { - Q_D(XNTimeManager); + T_D(); if (d->_eRunStatus == RunStatus::Runing) { LOG_INFO("XNSim Pause!"); d->_eRunStatus = RunStatus::Suspend; @@ -83,9 +82,9 @@ void XNTimeManager::OnPause() } } -void XNTimeManager::OnContinue() +void XNTimeManager::Continue() { - Q_D(XNTimeManager); + T_D(); if (d->_eRunStatus == RunStatus::Suspend) { LOG_INFO("XNSim Continue!"); d->_eRunStatus = RunStatus::Runing; @@ -96,34 +95,33 @@ void XNTimeManager::OnContinue() RunStatus XNTimeManager::GetStatus() { - Q_D(XNTimeManager); + T_D(); return d->_eRunStatus; } -void XNTimeManager::OnSimControl(quint32 objectId, SimControlCmd cmd) +void XNTimeManager::SimControl(uint32_t objectId, SimControlCmd cmd) { if (objectId == 0) { switch (cmd) { case SimControlCmd::Start: - OnStart(); + Start(); break; case SimControlCmd::Abort: - OnAbort(); + Abort(); break; case SimControlCmd::Continue: - OnContinue(); + Continue(); break; case SimControlCmd::Suspend: - OnPause(); + Pause(); break; } } - emit SimControl(objectId, cmd); } -void XNTimeManager::OnInitialize() +bool XNTimeManager::Initialize() { - Q_D(XNTimeManager); + T_D(); // 初始化锁 pthread_mutex_init(&(d->_mtx), NULL); @@ -150,23 +148,23 @@ void XNTimeManager::OnInitialize() LOG_INFO("XNTimeManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; - emit Initialize(); + return true; } -void XNTimeManager::OnPrepareForExecute() +bool XNTimeManager::PrepareForExecute() { - Q_D(XNTimeManager); + T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNTimeManager is prepared!"); - emit PrepareForExecute(); + return true; } void XNTimeManager::StepExecute() { - Q_D(XNTimeManager); + T_D(); // TODO 提交事件 // 时间推进 pthread_mutex_lock(&(d->_mtx)); - d->_SimTime = d->_SimTime.addMSecs(BASE_RUN_INTER * 1.0E6); + d->_SimTime += std::chrono::microseconds(static_cast(BASE_RUN_INTER * 1.0E6)); pthread_mutex_unlock(&(d->_mtx)); } diff --git a/XNCore/XNTimeManager.h b/XNCore/XNTimeManager.h index 214162d..8b39434 100755 --- a/XNCore/XNTimeManager.h +++ b/XNCore/XNTimeManager.h @@ -10,9 +10,9 @@ */ #pragma once #include "XNBaseFrameObject.h" -#include +#include -class XNTimeManagerPrivate; +struct XNTimeManagerPrivate; /** * @brief 时间管理器类 @@ -20,16 +20,14 @@ class XNTimeManagerPrivate; */ class XNCORE_EXPORT XNTimeManager : public XNBaseFrameObject { - Q_OBJECT - Q_DISABLE_COPY(XNTimeManager); - Q_DECLARE_PRIVATE(XNTimeManager); + XN_METATYPE(XNTimeManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNTimeManager) public: /** * @brief 构造函数 - * @param parent: 父对象 */ - explicit XNTimeManager(QObject *parent = nullptr); + XNTimeManager(); /** * @brief 析构函数 @@ -39,63 +37,46 @@ public: protected: /** * @brief 构造函数 - * @param dd: 私有数据成员 - * @param parent: 父对象 + * @param p: 私有数据成员 */ - XNTimeManager(XNTimeManagerPrivate &dd, QObject *parent = nullptr); + XNTimeManager(PrivateType *p); public: /** * @brief 获取当前仿真时间 - * @return QDateTime: 当前仿真时间 + * @return std::chrono::system_clock::time_point: 当前仿真时间 */ - QDateTime GetSimTime(); + XNTimePoint GetSimTime(); -signals: - /** - * @brief 设置仿真开始时间信号 - * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 - * @details 通过设置统一的开始时间,使个线程能同步执行 - */ - void SetStartTime(const timespec &simTime); - - /** - * @brief 仿真控制信号 - * @param objectId: 对象ID - * @param cmd: 仿真控制命令 - */ - void SimControl(quint32 objectId, SimControlCmd cmd); - -public slots: /** * @brief 设置仿真开始时间 - * @param simTime: timespec类型,仿真开始时间 + * @param simTime: timespec类型,仿真开始时间 */ - void OnSetStartTime(const timespec &simTime); + void SetStartTime(const timespec &simTime); /** * @brief 开始控制 * @details 控制时间管理器线程开始运行接口 */ - void OnStart(); + void Start(); /** * @brief 停止控制 * @details 控制时间管理器线程停止运行接口 */ - void OnAbort(); + void Abort(); /** * @brief 暂停控制 * @details 控制时间管理器线程暂停运行接口 */ - void OnPause(); + void Pause(); /** * @brief 继续控制 * @details 控制时间管理器线程继续运行接口 */ - void OnContinue(); + void Continue(); /** * @brief 初始化时间管理器 @@ -103,22 +84,21 @@ public slots: * @return false: 初始化失败 * @details 时间管理器的初始化接口函数 */ - virtual void OnInitialize() override; + virtual bool Initialize() override; /** * @brief 仿真运行前最后处理 * @note 时间管理器在开始执行前的准备工作 */ - virtual void OnPrepareForExecute() override; + virtual bool PrepareForExecute() override; /** * @brief 仿真控制 * @param objectId: 对象ID * @param cmd: 仿真控制命令 */ - void OnSimControl(quint32 objectId, SimControlCmd cmd); + void SimControl(uint32_t objectId, SimControlCmd cmd); -public: /** * @brief 获取运行状态 * @return RunStatus: 枚举类,时间管理器线程运行状态 diff --git a/XNCore/XNTimeManager_p.h b/XNCore/XNTimeManager_p.h index 57e5068..382edd1 100755 --- a/XNCore/XNTimeManager_p.h +++ b/XNCore/XNTimeManager_p.h @@ -11,21 +11,12 @@ #pragma once #include "XNBaseFrameObject_p.h" #include "XNThread.h" +#include /** * @brief 时间管理器类私有结构体 */ -class XNTimeManagerPrivate : public XNBaseFrameObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(XNTimeManager) - - explicit XNTimeManagerPrivate(XNTimeManager *q) : XNBaseFrameObjectPrivate(q) - { - _eRunStatus = RunStatus::NotStart; - } - -private: +struct XNTimeManagerPrivate : public XNBaseFrameObjectPrivate { /* * @brief 仿真运行状态 */ @@ -33,11 +24,11 @@ private: /** * @brief 仿真开始时间 */ - QDateTime _SimStartTime; + std::chrono::system_clock::time_point _SimStartTime; /** * @brief 当前仿真时间 */ - QDateTime _SimTime; + std::chrono::system_clock::time_point _SimTime; /** * @brief 时间管理器线程智能指针 */ diff --git a/XNModels/XNGroundHandling/.vscode/settings.json b/XNModels/XNGroundHandling/.vscode/settings.json index 44dc75a..863f241 100755 --- a/XNModels/XNGroundHandling/.vscode/settings.json +++ b/XNModels/XNGroundHandling/.vscode/settings.json @@ -1,6 +1,76 @@ { "files.associations": { "*.cpp": "cpp", - "qobject": "cpp" + "qobject": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "chrono": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.cpp b/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.cpp index e3c7881..84b3f62 100755 --- a/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.cpp +++ b/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.cpp @@ -137,6 +137,16 @@ void XNGroundHandling::StepUpdate() OnOutput(); } +// template +// void CopyInputData(T1 *model_input, const T2 &dds_input) +// { +// Q_D(XNGroundHandling); +// QMutexLocker locker(&d->_mutex); +// if (dds_input.l_04_i_gdcomac_frz_l1()) { +// model_input->l_04_i_gdcomac_frz_l1 = dds_input.l_04_i_gdcomac_frz_l1().value(); +// } +// } + void XNGroundHandling::OnInput(const XNSim::ATA04::GroundHandling_input &input) { Q_D(XNGroundHandling); diff --git a/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.h b/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.h index 10c5843..67f8563 100755 --- a/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.h +++ b/XNModels/XNGroundHandling/XNGroundHandling/XNGroundHandling.h @@ -1,7 +1,7 @@ #pragma once #include "XNGroundHandling_global.h" #include -#include "../XNGroundHandlingInterface/XNGroundHandlingPubSubTypes.hpp" +#include "../XNGroundHandlingInterface/XNGroundHandlingInterface.hpp" class XNGroundHandlingPrivate; diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.hpp b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.hpp index 36111df..1fd7f7e 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.hpp +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.hpp @@ -3794,20 +3794,30 @@ public: } /*! - * @brief This function sets a value in member groundhandling_model_heartbeat - * @param _groundhandling_model_heartbeat New value for member groundhandling_model_heartbeat + * @brief This function copies the value in member groundhandling_model_heartbeat + * @param _groundhandling_model_heartbeat New value to be copied in member groundhandling_model_heartbeat */ eProsima_user_DllExport void groundhandling_model_heartbeat( - int32_t _groundhandling_model_heartbeat) + const eprosima::fastcdr::optional& _groundhandling_model_heartbeat) { m_groundhandling_model_heartbeat = _groundhandling_model_heartbeat; } /*! - * @brief This function returns the value of member groundhandling_model_heartbeat - * @return Value of member groundhandling_model_heartbeat + * @brief This function moves the value in member groundhandling_model_heartbeat + * @param _groundhandling_model_heartbeat New value to be moved in member groundhandling_model_heartbeat */ - eProsima_user_DllExport int32_t groundhandling_model_heartbeat() const + eProsima_user_DllExport void groundhandling_model_heartbeat( + eprosima::fastcdr::optional&& _groundhandling_model_heartbeat) + { + m_groundhandling_model_heartbeat = std::move(_groundhandling_model_heartbeat); + } + + /*! + * @brief This function returns a constant reference to member groundhandling_model_heartbeat + * @return Constant reference to member groundhandling_model_heartbeat + */ + eProsima_user_DllExport const eprosima::fastcdr::optional& groundhandling_model_heartbeat() const { return m_groundhandling_model_heartbeat; } @@ -3816,7 +3826,7 @@ public: * @brief This function returns a reference to member groundhandling_model_heartbeat * @return Reference to member groundhandling_model_heartbeat */ - eProsima_user_DllExport int32_t& groundhandling_model_heartbeat() + eProsima_user_DllExport eprosima::fastcdr::optional& groundhandling_model_heartbeat() { return m_groundhandling_model_heartbeat; } @@ -3825,7 +3835,7 @@ public: private: - int32_t m_groundhandling_model_heartbeat{0}; + eprosima::fastcdr::optional m_groundhandling_model_heartbeat; }; diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.idl b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.idl index 14ac426..e810547 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.idl +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandling.idl @@ -84,7 +84,7 @@ module XNSim }; struct GroundHandling_heartbeat { - long groundhandling_model_heartbeat; + @optional long groundhandling_model_heartbeat; }; }; }; diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.hpp b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.hpp index 449b7fb..36ed0f0 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.hpp +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.hpp @@ -30,7 +30,7 @@ constexpr uint32_t XNSim_ATA04_GroundHandling_input_max_key_cdr_typesize {0UL}; constexpr uint32_t XNSim_ATA04_GroundHandling_output_max_cdr_typesize {1328UL}; constexpr uint32_t XNSim_ATA04_GroundHandling_output_max_key_cdr_typesize {0UL}; -constexpr uint32_t XNSim_ATA04_GroundHandling_heartbeat_max_cdr_typesize {8UL}; +constexpr uint32_t XNSim_ATA04_GroundHandling_heartbeat_max_cdr_typesize {12UL}; constexpr uint32_t XNSim_ATA04_GroundHandling_heartbeat_max_key_cdr_typesize {0UL}; diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.ipp b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.ipp index ead9a25..e4d0516 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.ipp +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingCdrAux.ipp @@ -1229,7 +1229,10 @@ void serialize_key( static_cast(scdr); static_cast(data); - scdr << data.groundhandling_model_heartbeat(); + if (data.groundhandling_model_heartbeat().has_value()) + { + scdr << data.groundhandling_model_heartbeat().value(); + } } diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.cxx b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.cxx index 66dba92..4c6da11 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.cxx +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.cxx @@ -4,8 +4,7 @@ namespace XNSim { namespace ATA04 { - GroundHandling_input_Interface::GroundHandling_input_Interface(QObject *parent) - : XNDDSInterface(parent) + GroundHandling_input_Interface::GroundHandling_input_Interface() { MAP_GET_DATA_FUNC(l_04_i_gdcomac_frz_l1); MAP_GET_DATA_FUNC(l_04_i_gdcomac_chocks_l1); @@ -55,12 +54,10 @@ namespace ATA04 void GroundHandling_input_Interface::inputDataListener( const XNSim::ATA04::GroundHandling_input &input) { - QMutexLocker locker(&mutex); this->data = input; } - GroundHandling_output_Interface::GroundHandling_output_Interface(QObject *parent) - : XNDDSInterface(parent) + GroundHandling_output_Interface::GroundHandling_output_Interface() { MAP_GET_DATA_FUNC(l_04_o_gdcomac_frz_l1); MAP_GET_DATA_FUNC(l_04_o_gdcomac_ac_on_ground_l1); @@ -106,22 +103,12 @@ namespace ATA04 void GroundHandling_output_Interface::outputDataListener( const XNSim::ATA04::GroundHandling_output &output) { - QMutexLocker locker(&mutex); this->data = output; } - GroundHandling_heartbeat_Interface::GroundHandling_heartbeat_Interface(QObject *parent) - : XNDDSInterface(parent) + GroundHandling_heartbeat_Interface::GroundHandling_heartbeat_Interface() { - getDataFunction["groundhandling_model_heartbeat"] = [this]() { - return QString::number(data.groundhandling_model_heartbeat()); - }; - getByteArrayFunction.push_back([this]() { - QByteArray tmp; - tmp.fromRawData(reinterpret_cast(&data.groundhandling_model_heartbeat()), - sizeof(data.groundhandling_model_heartbeat())); - return tmp; - }); + MAP_GET_DATA_FUNC(groundhandling_model_heartbeat); } GroundHandling_heartbeat_Interface::~GroundHandling_heartbeat_Interface() @@ -131,7 +118,6 @@ namespace ATA04 void GroundHandling_heartbeat_Interface::heartbeatListener( const XNSim::ATA04::GroundHandling_heartbeat &heartbeat) { - QMutexLocker locker(&mutex); this->data = heartbeat; } } // namespace ATA04 diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.hpp b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.hpp index 2661c70..ce2c825 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.hpp +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingInterface.hpp @@ -8,11 +8,101 @@ namespace ATA04 { class GroundHandling_input_Interface : public XNDDSInterface { - Q_OBJECT public: - explicit GroundHandling_input_Interface(QObject *parent); + explicit GroundHandling_input_Interface(); virtual ~GroundHandling_input_Interface(); void inputDataListener(const XNSim::ATA04::GroundHandling_input &input); + template + void getData(T *model_data) + { + if (model_data == nullptr) + return; + ASSIGN_VALUE_GET(l_04_i_gdcomac_frz_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_chocks_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_alt_agl_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_frzflt_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_p_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_q_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_r_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_ug_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_vg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_wg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_blcg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_bscg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_wlcg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_pb_active_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_brake_torq_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_gear_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_gsteer_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_tire_pres_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_onjax_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_contdep_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_thetag_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_phig_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_rwyrgh_i2); + ASSIGN_VALUE_GET(l_04_i_gdcomac_rwyhdg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_reset_braketemp_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_reset_tirepress_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_temp_c_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_brake_temp_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_tire_tburst_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_tire_tflat_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_brk_reset_tpres_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_rcon_ci_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_pb_towforce_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_gsteer_state_i4); + ASSIGN_VALUE_GET(l_04_i_gdcomac_trim_active_l1); + ASSIGN_VALUE_GET(l_04_i_gdcomac_phi_deg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_theta_deg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_psi_deg_f8); + ASSIGN_VALUE_GET(l_04_i_gdcomac_resetint_l1); + } + + template + void setData(T *model_data) + { + if (model_data == nullptr) + return; + ASSIGN_VALUE_SET(l_04_i_gdcomac_frz_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_chocks_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_alt_agl_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_frzflt_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_p_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_q_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_r_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_ug_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_vg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_wg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_blcg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_bscg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_wlcg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_pb_active_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_brake_torq_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_gear_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_gsteer_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_tire_pres_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_onjax_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_contdep_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_thetag_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_phig_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_rwyrgh_i2); + ASSIGN_VALUE_SET(l_04_i_gdcomac_rwyhdg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_reset_braketemp_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_reset_tirepress_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_temp_c_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_brake_temp_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_tire_tburst_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_tire_tflat_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_brk_reset_tpres_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_rcon_ci_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_pb_towforce_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_gsteer_state_i4); + ASSIGN_VALUE_SET(l_04_i_gdcomac_trim_active_l1); + ASSIGN_VALUE_SET(l_04_i_gdcomac_phi_deg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_theta_deg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_psi_deg_f8); + ASSIGN_VALUE_SET(l_04_i_gdcomac_resetint_l1); + } private: XNSim::ATA04::GroundHandling_input data; @@ -20,9 +110,8 @@ namespace ATA04 class GroundHandling_output_Interface : public XNDDSInterface { - Q_OBJECT public: - explicit GroundHandling_output_Interface(QObject *parent); + explicit GroundHandling_output_Interface(); virtual ~GroundHandling_output_Interface(); void outputDataListener(const XNSim::ATA04::GroundHandling_output &output); @@ -32,9 +121,8 @@ namespace ATA04 class GroundHandling_heartbeat_Interface : public XNDDSInterface { - Q_OBJECT public: - explicit GroundHandling_heartbeat_Interface(QObject *parent); + explicit GroundHandling_heartbeat_Interface(); virtual ~GroundHandling_heartbeat_Interface(); void heartbeatListener(const XNSim::ATA04::GroundHandling_heartbeat &heartbeat); diff --git a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingTypeObjectSupport.cxx b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingTypeObjectSupport.cxx index f62ad8c..5ef8935 100755 --- a/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingTypeObjectSupport.cxx +++ b/XNModels/XNGroundHandling/XNGroundHandlingInterface/XNGroundHandlingTypeObjectSupport.cxx @@ -4330,7 +4330,7 @@ void register_GroundHandling_heartbeat_type_identifier( return; } StructMemberFlag member_flags_groundhandling_model_heartbeat = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, - false, false, false, false); + true, false, false, false); MemberId member_id_groundhandling_model_heartbeat = 0x00000000; bool common_groundhandling_model_heartbeat_ec {false}; CommonStructMember common_groundhandling_model_heartbeat {TypeObjectUtils::build_common_struct_member(member_id_groundhandling_model_heartbeat, member_flags_groundhandling_model_heartbeat, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_groundhandling_model_heartbeat, common_groundhandling_model_heartbeat_ec))}; @@ -4342,6 +4342,19 @@ void register_GroundHandling_heartbeat_type_identifier( MemberName name_groundhandling_model_heartbeat = "groundhandling_model_heartbeat"; eprosima::fastcdr::optional member_ann_builtin_groundhandling_model_heartbeat; ann_custom_GroundHandling_heartbeat.reset(); + AppliedAnnotationSeq tmp_ann_custom_groundhandling_model_heartbeat; + eprosima::fastcdr::optional unit_groundhandling_model_heartbeat; + eprosima::fastcdr::optional min_groundhandling_model_heartbeat; + eprosima::fastcdr::optional max_groundhandling_model_heartbeat; + eprosima::fastcdr::optional hash_id_groundhandling_model_heartbeat; + if (unit_groundhandling_model_heartbeat.has_value() || min_groundhandling_model_heartbeat.has_value() || max_groundhandling_model_heartbeat.has_value() || hash_id_groundhandling_model_heartbeat.has_value()) + { + member_ann_builtin_groundhandling_model_heartbeat = TypeObjectUtils::build_applied_builtin_member_annotations(unit_groundhandling_model_heartbeat, min_groundhandling_model_heartbeat, max_groundhandling_model_heartbeat, hash_id_groundhandling_model_heartbeat); + } + if (!tmp_ann_custom_groundhandling_model_heartbeat.empty()) + { + ann_custom_GroundHandling_heartbeat = tmp_ann_custom_groundhandling_model_heartbeat; + } CompleteMemberDetail detail_groundhandling_model_heartbeat = TypeObjectUtils::build_complete_member_detail(name_groundhandling_model_heartbeat, member_ann_builtin_groundhandling_model_heartbeat, ann_custom_GroundHandling_heartbeat); CompleteStructMember member_groundhandling_model_heartbeat = TypeObjectUtils::build_complete_struct_member(common_groundhandling_model_heartbeat, detail_groundhandling_model_heartbeat); TypeObjectUtils::add_complete_struct_member(member_seq_GroundHandling_heartbeat, member_groundhandling_model_heartbeat);