XNCore重构完成,暂未测试

This commit is contained in:
jinchao 2025-05-20 15:39:40 +08:00
parent fc315a882c
commit f2970327fa
84 changed files with 3437 additions and 3327 deletions

View File

@ -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);
};

View File

@ -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;
};

View File

@ -1,14 +1,13 @@
#ifndef XNCORE_GLOBAL_H
#define XNCORE_GLOBAL_H
#include <QtCore/qglobal.h>
#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 <pthread.h>
# include <sched.h>
@ -20,8 +19,34 @@
# include <memory>
# include <errno.h>
# include <unistd.h>
# include <limits.h>
# include <functional>
# include <map>
# include <unordered_map>
# include <vector>
# include <set>
# include <any>
# include <string>
# include <thread>
# include <mutex>
# include <condition_variable>
# include <queue>
# include <tinyxml2.h>
# include <chrono>
# include <iomanip>
# include <sstream>
# include <dlfcn.h>
# include <filesystem>
#endif
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#define FAST_DDS_MACRO eprosima::fastdds::dds
/**
@ -40,6 +65,9 @@ using XNCallBack = std::function<void()>;
//DDS回调函数类型别名
using XNDDSCallBack = std::function<void(void *)>;
//事件回调函数类型别名
using XNEventCallback = std::function<void(const std::any &)>;
/**
* @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>(#ClassName); \
template <class ToType, class FromType>
FORCEINLINE ToType XNStaticCastHelper(const FromType &from)
{
return std::static_pointer_cast<typename ToType::element_type>(from);
}
#endif // XNCORE_GLOBAL_H
template <class ToType, class FromType>
FORCEINLINE ToType XNCastHelper(const FromType &from)
{
return std::dynamic_pointer_cast<typename ToType::element_type>(from);
}
#define XN_CAST(from, to) XNStaticCastHelper<to>(from)
#define XN_THISPTR std::static_pointer_cast<ThisType>(shared_from_this())
#define XNCLASS_PTR_DECLARE(a) \
using a##Ptr = std::shared_ptr<class a>; \
using a##WPtr = std::weak_ptr<class a>; \
using a##UPtr = std::unique_ptr<class a>; \
using a##ConsPtr = std::shared_ptr<const class a>;
#define XNSTRUCT_PTR_DECLARE(a) \
using a##Ptr = std::shared_ptr<struct a>; \
using a##WPtr = std::weak_ptr<struct a>; \
using a##UPtr = std::unique_ptr<struct a>; \
using a##ConsPtr = std::shared_ptr<const struct a>;
#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<Class##Private *>(_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;

View File

@ -45,44 +45,6 @@ public:
XNDDSInterface() = default;
virtual ~XNDDSInterface() = default;
template <typename T>
void getByteArray(eprosima::fastcdr::optional<T> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>())
return;
if constexpr (std::is_arithmetic_v<T>) {
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<T>) {
if (data) {
getByteArrayFromStdArray(data.value(), buffer, bufferSize);
} else {
T zero = {};
getByteArrayFromStdArray(zero, buffer, bufferSize);
}
}
}
template <typename T, std::size_t N>
void getByteArrayFromStdArray(std::array<T, N> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>() * N)
return;
for (std::size_t i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
std::memcpy(buffer + i * getTypeSize<T>(), &data[i], getTypeSize<T>());
} else {
getByteArrayFromStdArray(data[i], buffer + i * getTypeSize<T>(), getTypeSize<T>());
}
}
}
void getUDPPackage(uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < MAX_UDP_PACKET_SIZE)
@ -112,42 +74,6 @@ public:
}
}
template <typename T>
std::string getString(eprosima::fastcdr::optional<T> data)
{
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
return std::to_string(data.value());
} else {
return std::to_string(0);
}
} else if constexpr (std::is_same_v<T, std::string>) {
if (data) {
return getStringFromStdArray(data.value());
} else {
T zero = {};
return getStringFromStdArray(zero);
}
}
return std::string();
}
template <typename T, std::size_t N>
std::string getStringFromStdArray(std::array<T, N> data)
{
std::stringstream ss;
for (std::size_t i = 0; i < N; ++i) {
if (i > 0)
ss << ",";
if constexpr (std::is_arithmetic_v<T>) {
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 <typename T>
void getByteArray(eprosima::fastcdr::optional<T> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>())
return;
if constexpr (std::is_arithmetic_v<T>) {
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<T>) {
if (data) {
getByteArrayFromStdArray(data.value(), buffer, bufferSize);
} else {
T zero = {};
getByteArrayFromStdArray(zero, buffer, bufferSize);
}
}
}
template <typename T, std::size_t N>
void getByteArrayFromStdArray(std::array<T, N> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>() * N)
return;
for (std::size_t i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
std::memcpy(buffer + i * getTypeSize<T>(), &data[i], getTypeSize<T>());
} else {
getByteArrayFromStdArray(data[i], buffer + i * getTypeSize<T>(), getTypeSize<T>());
}
}
}
template <typename T>
std::string getString(eprosima::fastcdr::optional<T> data)
{
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
return std::to_string(data.value());
} else {
return std::to_string(0);
}
} else if constexpr (std::is_same_v<T, std::string>) {
if (data) {
return getStringFromStdArray(data.value());
} else {
T zero = {};
return getStringFromStdArray(zero);
}
}
return std::string();
}
template <typename T, std::size_t N>
std::string getStringFromStdArray(std::array<T, N> data)
{
std::stringstream ss;
for (std::size_t i = 0; i < N; ++i) {
if (i > 0)
ss << ",";
if constexpr (std::is_arithmetic_v<T>) {
ss << data[i];
} else {
ss << getStringFromStdArray(data[i]);
}
}
return ss.str();
}
protected:
struct ByteArrayFunc {
std::function<void(uint8_t *, size_t)> func;
@ -239,3 +240,47 @@ protected:
getByteArrayFunction.push_back( \
{[this](uint8_t *buffer, size_t size) { getByteArray(data.NAME(), buffer, size); }, \
getTypeSize<decltype(data.NAME())>()})
#define ASSIGN_VALUE_GET(NAME) \
if (data.NAME()) { \
auto temp = data.NAME().value(); \
if constexpr (std::is_arithmetic_v<decltype(temp)>) { \
model_data->NAME = temp; \
} else if constexpr (std::is_std_array_v<decltype(temp)>) { \
size_t arraySize = std::tuple_size<decltype(temp)>::value; \
for (size_t i = 0; i < arraySize; ++i) { \
if constexpr (std::is_arithmetic_v<decltype(temp[i])>) { \
model_data->NAME[i] = temp[i]; \
} else if constexpr (std::is_std_array_v<decltype(temp[i])>) { \
size_t arraySize2 = std::tuple_size<decltype(temp[i])>::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<decltype(data.NAME())::type>) { \
data.NAME(model_data->NAME); \
} else if constexpr (std::is_std_array_v<decltype(data.NAME())::type>) { \
using thisType = typename decltype(data.NAME())::type; \
thisType temp; \
size_t arraySize1 = std::tuple_size<thisType>::value; \
using subType = thisType::value_type; \
if constexpr (std::is_arithmetic_v<subType>) { \
for (size_t i = 0; i < arraySize1; ++i) { \
temp[i] = model_data->NAME[i]; \
} \
} else if constexpr (std::is_std_array_v<subType>) { \
size_t arraySize2 = std::tuple_size<subType>::value; \
std::array<subType, arraySize1> 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); \
}

View File

@ -1,14 +1,6 @@
#pragma once
#include "XNBaseFrameObject.h"
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#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<quint32, PublisherInfo> publishers_;
QMap<quint32, SubscriberInfo> subscribers_;
std::map<uint32_t, PublisherInfo> publishers_;
std::map<uint32_t, SubscriberInfo> subscribers_;
};
template <typename T>
@ -46,50 +38,54 @@ private:
std::function<void(const T &)> callback_;
};
class XNDDSManagerPrivate;
struct XNDDSManagerPrivate : public XNBaseFrameObjectPrivate {
FAST_DDS_MACRO::DomainParticipant *participant_;
std::map<std::string, TopicInfo> 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 <typename T>
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<std::mutex> lock(mutex_);
if (!topics_.contains(topicName)) {
topics_[topicName] = TopicInfo();
TopicInfo &tmp = topics_[topicName];
T_D();
std::lock_guard<std::mutex> 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(),
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 <typename T>
void RegisterSubscriber(const QString &topicName, quint32 subscriberID,
void RegisterSubscriber(const std::string &topicName, uint32_t subscriberID,
std::function<void(const typename T::type &)> fun)
{
Q_D(XNDDSManager);
std::lock_guard<std::mutex> lock(mutex_);
if (!topics_.contains(topicName)) {
topics_[topicName] = TopicInfo();
TopicInfo &tmp = topics_[topicName];
T_D();
std::lock_guard<std::mutex> 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(),
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<QString, TopicInfo> topics_;
std::mutex mutex_;
};

View File

@ -1,6 +1,6 @@
#pragma once
#include "XNBaseFrameObject.h"
#include <QVariant>
// 事件优先级定义
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) // 禁用拷贝构造和赋值操作
XN_METATYPE(XNEventManager, XNBaseFrameObject)
XN_DECLARE_PRIVATE(XNEventManager)
public:
// 构造函数,创建事件管理器实例
explicit XNEventManager(QObject *parent = nullptr);
XNEventManager();
// 析构函数
~XNEventManager();
@ -34,21 +33,20 @@ class XNEventManager : public XNBaseFrameObject
// @param async: 是否异步处理该事件
// @param priority: 事件优先级
// @return: 返回处理器ID失败返回-1
int RegisterEventHandler(const QString &eventName,
std::function<void(const QVariant &)> 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;
};

View File

@ -1,9 +1,6 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include "XNEventManager.h"
#include <QMap>
#include <QMutex>
#include <QThreadPool>
#include <functional>
#include <sys/types.h>
#include <bits/pthreadtypes.h>
@ -12,78 +9,130 @@
#include <queue>
#include <mutex>
#include <condition_variable>
#include <string>
#include <any>
#include <map>
#include <list>
// 事件处理器信息结构
struct EventHandlerInfo {
std::function<void(const QVariant &)> callback; // 回调函数
quint32 objectId; // 对象ID
int localId; // 本地ID
std::function<void(const std::any &)> 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<void(const QVariant &)> callback, XNEventManager *manager)
/**
* @brief
* @param name
* @param data
* @param callback
* @param manager
*/
BaseEventTask(const std::string &name, const std::any &data,
std::function<void(const std::any &)> 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<void(const QVariant &)> eventCallback;
std::string eventName;
std::any eventData;
std::function<void(const std::any &)> eventCallback;
XNEventManager *eventManager;
};
// 实时事件任务
class RTEventTask
// 异步事件任务
class AsyncEventTask : public BaseEventTask
{
public:
RTEventTask(const QString &name, const QVariant &data,
std::function<void(const QVariant &)> 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<void(const std::any &)> 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);
}
}
}
};
// 实时事件任务
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<void(const std::any &)> callback, XNEventManager *manager)
: BaseEventTask(name, data, callback, manager)
{
}
private:
QString eventName;
QVariant eventData;
std::function<void(const QVariant &)> eventCallback;
XNEventManager *eventManager;
/**
* @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<QString, QList<EventHandlerInfo>> eventHandlers;
std::map<std::string, std::list<EventHandlerInfo>> eventHandlers;
// 处理器ID到事件名称的反向映射用于快速查找
QMap<int, QString> handlerToEvent;
std::map<int, std::string> handlerToEvent;
// 本地ID计数器
int localIdCounter = 0;
// 互斥锁,用于保护事件处理器表的线程安全访问
QMutex eventMutex;
std::mutex eventMutex;
// 线程池,用于异步执行事件处理器
QThreadPool threadPool;
// 实时线程池
QThreadPool rtThreadPool;
// 线程池相关
std::vector<std::thread> workerThreads;
std::queue<BaseEventTask *> taskQueue;
std::mutex taskMutex;
std::condition_variable taskCond;
bool running = true;
RTThreadManager rtManager;
QThreadPool normalThreadPool; // 用于非实时任务
};

View File

@ -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);
};

View File

@ -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;
};

View File

@ -9,13 +9,15 @@
*
*/
#pragma once
#include <QString>
#include <QMutex>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDir>
#include <string>
#include <mutex>
#include <fstream>
#include <chrono>
#include <filesystem>
#include <type_traits>
#include <iostream>
#include <iomanip>
#include <sstream>
/**
* @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 <typename... Args>
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 <typename T>
static QString convertToString(const T &arg)
static std::string convertToString(const T &arg)
{
if constexpr (std::is_arithmetic<T>::value) {
return QString::number(arg); // 处理数值类型
return std::to_string(arg); // 处理数值类型
} else {
return arg;
return std::string(arg);
}
}
// 递归变参函数,用于处理多个参数
template <typename T, typename... Args>
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; }
};
/**

View File

@ -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类型990
*/
void OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos,
quint32 RunPriorty);
signals:
/**
* @brief
* @param id: UINT32类型ID
* @param fun:
* @param freqGroup: UINT32类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty: UINT32类型990
*/
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);
};

View File

@ -1,25 +1,17 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include <QVector>
#include <QHash>
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<bool> ModelIDAssigned;
std::vector<bool> ModelIDAssigned;
/**
* @brief 仿
* @details 仿线 1 1/2 1/4 1/8 1/16 1/32
* @brief ID与模型指针的映射表
* @details ID与模型指针的映射表
*/
double dBaseFreq;
std::map<uint32_t, XNModelObjectPtr> ModelMap;
};

View File

@ -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<void(const QVariant &)> 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<void(const QVariant &)> 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类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty:INT32类型990
* @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<XNModelManager *>(parent()); \
if (modelManager == nullptr) \
auto framework = GetFramework(); \
if (!framework) \
return; \
XNDDSManager *ddsManager = modelManager->parent()->findChild<XNDDSManager *>(); \
if (ddsManager == nullptr) \
XNDDSManagerPtr ddsManager = framework->GetDDSManager(); \
if (!ddsManager) \
return; \
quint32 MyID = getUniqueId();
@ -234,3 +211,10 @@ public:
#topic, MyID, std::bind(fun, this, std::placeholders::_1));
#define XN_REGISTER_PARTICIPANT_END(class) }
#define XN_MODEL_INITIALIZE(ClassName) \
extern "C" XNModelObjectPtr Initial##ClassName() \
{ \
ClassNamePtr obj = std::make_shared<ClassName>(); \
return obj; \
}

View File

@ -10,62 +10,49 @@
*/
#pragma once
#include "XNObject_p.h"
#include <QLibrary>
#include <QFunctionPointer>
#include <QHash>
#include <fastdds/dds/publisher/DataWriter.hpp>
/**
* @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<QString, FAST_DDS_MACRO::DataWriter *> _dataWriters;
std::unordered_map<std::string, FAST_DDS_MACRO::DataWriter *> _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;
};

View File

@ -10,75 +10,83 @@
*/
#pragma once
#include <QObject>
#include <QVariant>
#include <QtXml/QDomDocument>
#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<XNObject>
{
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)

View File

@ -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;
};

View File

@ -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);
};

View File

@ -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;
};

View File

@ -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();
};

View File

@ -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<bool> ServiceIDAssigned;
std::vector<bool> ServiceIDAssigned;
/**
* @brief
* @details
*/
std::map<uint32_t, XNServiceObjectPtr> ServiceList;
};

View File

@ -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<void(const QVariant &)> 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<void(const QVariant &)> 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<XNServiceManager *>(parent()); \
if (serviceManager == nullptr) \
auto framework = GetFramework(); \
if (!framework) \
return; \
XNDDSManager *ddsManager = serviceManager->parent()->findChild<XNDDSManager *>(); \
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<ClassName>(); \
return obj; \
}

View File

@ -1,21 +1,13 @@
#pragma once
#include "XNObject_p.h"
#include <QHash>
#include <fastdds/dds/publisher/DataWriter.hpp>
#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<QString, FAST_DDS_MACRO::DataWriter *> _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<std::string, FAST_DDS_MACRO::DataWriter *> _dataWriters;
XNFrameworkPtr pFramework;
};

View File

@ -9,36 +9,43 @@
*
*/
#pragma once
#include <QObject>
#include <QThread>
#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&:09999
*/
const uint32_t &GetRunPriority();
/**
* @brief 线
* @param uRunPriority: UINT32类型09999
*/
void SetRunPriority(const uint32_t &uRunPriority);
/**
* @brief 线CPU亲和性掩码
* @return const UINT32&: CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
const uint32_t &GetCPUAffinity();
/**
* @brief 线CPU亲和性掩码
* @param uCPUAffinity: UINT32类型CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
void SetCPUAffinity(const uint32_t &uCPUAffinity);
/**
* @brief 线
* @param fun:XNCallBack函数包装器类型
* @param freq:FreqLevel类型
* @param pos:UINT32类型
* @param priorty:UINT32类型990
* @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&:09999
*/
const quint32 &GetRunPriority();
/**
* @brief 线
* @param uRunPriority: UINT32类型09999
*/
void SetRunPriority(const quint32 &uRunPriority);
/**
* @brief 线CPU亲和性掩码
* @return const UINT32&: CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
const quint32 &GetCPUAffinity();
/**
* @brief 线CPU亲和性掩码
* @param uCPUAffinity: UINT32类型CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
void SetCPUAffinity(const quint32 &uCPUAffinity);
/**
* @brief 线
* @param fun:XNCallBack函数包装器类型
* @param freq:FreqLevel类型
* @param pos:UINT32类型
* @param priorty:UINT32类型990
* @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();
// /**
// * @brief 初始化周期性函数表
// */
//void InitialFunPool();
};
XNCLASS_PTR_DECLARE(XNThread)

View File

@ -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类型线990
* @param CPUAff: UINT32类型线CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
* @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类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty: UINT32类型990
@ -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();
};

View File

@ -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<funInfo>;
using funInfoPtr = std::shared_ptr<funInfo>;
/**
* @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<uint32_t, XNThreadPtr> threadList;
/**
* @brief
*/
QMap<quint32, std::vector<funInfoPtr> > funList;
/**
* @brief
*/
double dRunFreq = BASE_RUN_FREQ;
/**
* @brief
*/
double dRunInter = BASE_RUN_INTER;
std::map<uint32_t, std::vector<funInfoPtr> > funList;
/**
* @brief 线ID
*/
QSet<quint32> threadIDMap;
/**
* @brief 线
*/
quint32 threadCount = 0;
std::set<uint32_t> threadIDMap;
};

View File

@ -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,1CPU
*/
uint32_t _uAffinity = 0;
/**
* @brief 线
*/
double _setFreq = BASE_RUN_FREQ;
/**
* @brief 线
*/
std::vector<std::map<uint32_t, std::vector<XNCallBack> > > _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;
};

View File

@ -10,9 +10,9 @@
*/
#pragma once
#include "XNBaseFrameObject.h"
#include <QDateTime>
#include <chrono>
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类型仿
*/
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: 线

View File

@ -11,21 +11,12 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include "XNThread.h"
#include <chrono>
/**
* @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 线
*/

View File

@ -78,6 +78,7 @@
"qlibrary": "cpp",
"csignal": "cpp",
"any": "cpp",
"unordered_set": "cpp"
"unordered_set": "cpp",
"fstream": "cpp"
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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;
};

View File

@ -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;
}

View File

@ -1,14 +1,13 @@
#ifndef XNCORE_GLOBAL_H
#define XNCORE_GLOBAL_H
#include <QtCore/qglobal.h>
#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 <pthread.h>
# include <sched.h>
@ -20,8 +19,34 @@
# include <memory>
# include <errno.h>
# include <unistd.h>
# include <limits.h>
# include <functional>
# include <map>
# include <unordered_map>
# include <vector>
# include <set>
# include <any>
# include <string>
# include <thread>
# include <mutex>
# include <condition_variable>
# include <queue>
# include <tinyxml2.h>
# include <chrono>
# include <iomanip>
# include <sstream>
# include <dlfcn.h>
# include <filesystem>
#endif
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#define FAST_DDS_MACRO eprosima::fastdds::dds
/**
@ -40,6 +65,9 @@ using XNCallBack = std::function<void()>;
//DDS回调函数类型别名
using XNDDSCallBack = std::function<void(void *)>;
//事件回调函数类型别名
using XNEventCallback = std::function<void(const std::any &)>;
/**
* @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>(#ClassName); \
template <class ToType, class FromType>
FORCEINLINE ToType XNStaticCastHelper(const FromType &from)
{
return std::static_pointer_cast<typename ToType::element_type>(from);
}
#endif // XNCORE_GLOBAL_H
template <class ToType, class FromType>
FORCEINLINE ToType XNCastHelper(const FromType &from)
{
return std::dynamic_pointer_cast<typename ToType::element_type>(from);
}
#define XN_CAST(from, to) XNStaticCastHelper<to>(from)
#define XN_THISPTR std::static_pointer_cast<ThisType>(shared_from_this())
#define XNCLASS_PTR_DECLARE(a) \
using a##Ptr = std::shared_ptr<class a>; \
using a##WPtr = std::weak_ptr<class a>; \
using a##UPtr = std::unique_ptr<class a>; \
using a##ConsPtr = std::shared_ptr<const class a>;
#define XNSTRUCT_PTR_DECLARE(a) \
using a##Ptr = std::shared_ptr<struct a>; \
using a##WPtr = std::weak_ptr<struct a>; \
using a##UPtr = std::unique_ptr<struct a>; \
using a##ConsPtr = std::shared_ptr<const struct a>;
#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<Class##Private *>(_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;

193
XNCore/XNDDSInterface.h Executable file → Normal file
View File

@ -45,44 +45,6 @@ public:
XNDDSInterface() = default;
virtual ~XNDDSInterface() = default;
template <typename T>
void getByteArray(eprosima::fastcdr::optional<T> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>())
return;
if constexpr (std::is_arithmetic_v<T>) {
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<T>) {
if (data) {
getByteArrayFromStdArray(data.value(), buffer, bufferSize);
} else {
T zero = {};
getByteArrayFromStdArray(zero, buffer, bufferSize);
}
}
}
template <typename T, std::size_t N>
void getByteArrayFromStdArray(std::array<T, N> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>() * N)
return;
for (std::size_t i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
std::memcpy(buffer + i * getTypeSize<T>(), &data[i], getTypeSize<T>());
} else {
getByteArrayFromStdArray(data[i], buffer + i * getTypeSize<T>(), getTypeSize<T>());
}
}
}
void getUDPPackage(uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < MAX_UDP_PACKET_SIZE)
@ -112,42 +74,6 @@ public:
}
}
template <typename T>
std::string getString(eprosima::fastcdr::optional<T> data)
{
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
return std::to_string(data.value());
} else {
return std::to_string(0);
}
} else if constexpr (std::is_same_v<T, std::string>) {
if (data) {
return getStringFromStdArray(data.value());
} else {
T zero = {};
return getStringFromStdArray(zero);
}
}
return std::string();
}
template <typename T, std::size_t N>
std::string getStringFromStdArray(std::array<T, N> data)
{
std::stringstream ss;
for (std::size_t i = 0; i < N; ++i) {
if (i > 0)
ss << ",";
if constexpr (std::is_arithmetic_v<T>) {
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 <typename T>
void getByteArray(eprosima::fastcdr::optional<T> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>())
return;
if constexpr (std::is_arithmetic_v<T>) {
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<T>) {
if (data) {
getByteArrayFromStdArray(data.value(), buffer, bufferSize);
} else {
T zero = {};
getByteArrayFromStdArray(zero, buffer, bufferSize);
}
}
}
template <typename T, std::size_t N>
void getByteArrayFromStdArray(std::array<T, N> data, uint8_t *buffer, size_t bufferSize)
{
if (bufferSize < getTypeSize<T>() * N)
return;
for (std::size_t i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
std::memcpy(buffer + i * getTypeSize<T>(), &data[i], getTypeSize<T>());
} else {
getByteArrayFromStdArray(data[i], buffer + i * getTypeSize<T>(), getTypeSize<T>());
}
}
}
template <typename T>
std::string getString(eprosima::fastcdr::optional<T> data)
{
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
return std::to_string(data.value());
} else {
return std::to_string(0);
}
} else if constexpr (std::is_same_v<T, std::string>) {
if (data) {
return getStringFromStdArray(data.value());
} else {
T zero = {};
return getStringFromStdArray(zero);
}
}
return std::string();
}
template <typename T, std::size_t N>
std::string getStringFromStdArray(std::array<T, N> data)
{
std::stringstream ss;
for (std::size_t i = 0; i < N; ++i) {
if (i > 0)
ss << ",";
if constexpr (std::is_arithmetic_v<T>) {
ss << data[i];
} else {
ss << getStringFromStdArray(data[i]);
}
}
return ss.str();
}
protected:
struct ByteArrayFunc {
std::function<void(uint8_t *, size_t)> func;
@ -239,3 +240,47 @@ protected:
getByteArrayFunction.push_back( \
{[this](uint8_t *buffer, size_t size) { getByteArray(data.NAME(), buffer, size); }, \
getTypeSize<decltype(data.NAME())>()})
#define ASSIGN_VALUE_GET(NAME) \
if (data.NAME()) { \
auto temp = data.NAME().value(); \
if constexpr (std::is_arithmetic_v<decltype(temp)>) { \
model_data->NAME = temp; \
} else if constexpr (std::is_std_array_v<decltype(temp)>) { \
size_t arraySize = std::tuple_size<decltype(temp)>::value; \
for (size_t i = 0; i < arraySize; ++i) { \
if constexpr (std::is_arithmetic_v<decltype(temp[i])>) { \
model_data->NAME[i] = temp[i]; \
} else if constexpr (std::is_std_array_v<decltype(temp[i])>) { \
size_t arraySize2 = std::tuple_size<decltype(temp[i])>::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<decltype(data.NAME())::type>) { \
data.NAME(model_data->NAME); \
} else if constexpr (std::is_std_array_v<decltype(data.NAME())::type>) { \
using thisType = typename decltype(data.NAME())::type; \
thisType temp; \
size_t arraySize1 = std::tuple_size<thisType>::value; \
using subType = thisType::value_type; \
if constexpr (std::is_arithmetic_v<subType>) { \
for (size_t i = 0; i < arraySize1; ++i) { \
temp[i] = model_data->NAME[i]; \
} \
} else if constexpr (std::is_std_array_v<subType>) { \
size_t arraySize2 = std::tuple_size<subType>::value; \
std::array<subType, arraySize1> 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); \
}

View File

@ -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);
LOG_INFO("XNDDSManager Initialize Success!");
T_D();
d->_status = XNFrameObjectStatus::Initialized;
emit Initialize();
d->participant_ = nullptr;
d->topics_.clear();
LOG_INFO("XNDDSManager Initialize Success!");
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!");
}
}

View File

@ -1,14 +1,6 @@
#pragma once
#include "XNBaseFrameObject.h"
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#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<quint32, PublisherInfo> publishers_;
QMap<quint32, SubscriberInfo> subscribers_;
std::map<uint32_t, PublisherInfo> publishers_;
std::map<uint32_t, SubscriberInfo> subscribers_;
};
template <typename T>
@ -46,50 +38,54 @@ private:
std::function<void(const T &)> callback_;
};
class XNDDSManagerPrivate;
struct XNDDSManagerPrivate : public XNBaseFrameObjectPrivate {
FAST_DDS_MACRO::DomainParticipant *participant_;
std::map<std::string, TopicInfo> 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 <typename T>
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<std::mutex> lock(mutex_);
if (!topics_.contains(topicName)) {
topics_[topicName] = TopicInfo();
TopicInfo &tmp = topics_[topicName];
T_D();
std::lock_guard<std::mutex> 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(),
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 <typename T>
void RegisterSubscriber(const QString &topicName, quint32 subscriberID,
void RegisterSubscriber(const std::string &topicName, uint32_t subscriberID,
std::function<void(const typename T::type &)> fun)
{
Q_D(XNDDSManager);
std::lock_guard<std::mutex> lock(mutex_);
if (!topics_.contains(topicName)) {
topics_[topicName] = TopicInfo();
TopicInfo &tmp = topics_[topicName];
T_D();
std::lock_guard<std::mutex> 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(),
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<QString, TopicInfo> topics_;
std::mutex mutex_;
};

View File

@ -1,15 +0,0 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include <mutex>
#include <fastdds/dds/domain/DomainParticipant.hpp>
struct TopicInfo;
class XNDDSManagerPrivate : public XNBaseFrameObjectPrivate
{
public:
Q_DECLARE_PUBLIC(XNDDSManager)
explicit XNDDSManagerPrivate(XNDDSManager *q) : XNBaseFrameObjectPrivate(q) {}
};

View File

@ -1,76 +1,47 @@
#include "XNEventManager.h"
#include "XNEventManager_p.h"
#include "XNFramework.h"
#include <thread>
#include <algorithm>
// 构造函数
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<void(const QVariant &)> 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<void(const QVariant &)> eventCallback;
XNEventManager *eventManager;
};
// 修改注册事件处理器的实现
int XNEventManager::RegisterEventHandler(const QString &eventName,
std::function<void(const QVariant &)> 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<std::mutex> 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<std::mutex> 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 (handlerIt != handlers.end()) {
handlers.erase(handlerIt);
d->handlerToEvent.erase(handlerId);
LOG_INFO("Removed handler ID " + std::to_string(handlerId)
+ " from event: " + eventName);
// 如果事件没有处理器了,移除整个事件
if (handlers.isEmpty()) {
d->eventHandlers.remove(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();
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 (handlerIt != handlers.end()) {
handlers.erase(handlerIt);
d->handlerToEvent.erase(handlerId);
LOG_INFO("Removed handler ID " + std::to_string(handlerId)
+ " from event: " + eventToRemove);
// 如果事件没有处理器了,移除整个事件
if (handlers.isEmpty()) {
d->eventHandlers.remove(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<EventHandlerInfo> handlers;
T_D();
std::list<EventHandlerInfo> handlers;
{
QMutexLocker locker(&d->eventMutex);
if (!d->eventHandlers.contains(eventName)) {
//LOG_WARNING(QString("No handlers registered for event: %1").arg(eventName));
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(d->taskMutex);
return d->workerThreads.size();
}
void XNEventManager::WaitForAsyncEvents()
{
Q_D(XNEventManager);
d->threadPool.waitForDone();
T_D();
std::unique_lock<std::mutex> 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<XNFramework *>(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"));
}

View File

@ -1,6 +1,6 @@
#pragma once
#include "XNBaseFrameObject.h"
#include <QVariant>
// 事件优先级定义
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) // 禁用拷贝构造和赋值操作
XN_METATYPE(XNEventManager, XNBaseFrameObject)
XN_DECLARE_PRIVATE(XNEventManager)
public:
// 构造函数,创建事件管理器实例
explicit XNEventManager(QObject *parent = nullptr);
XNEventManager();
// 析构函数
~XNEventManager();
@ -34,21 +33,20 @@ class XNEventManager : public XNBaseFrameObject
// @param async: 是否异步处理该事件
// @param priority: 事件优先级
// @return: 返回处理器ID失败返回-1
int RegisterEventHandler(const QString &eventName,
std::function<void(const QVariant &)> 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;
};

View File

@ -1,9 +1,6 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include "XNEventManager.h"
#include <QMap>
#include <QMutex>
#include <QThreadPool>
#include <functional>
#include <sys/types.h>
#include <bits/pthreadtypes.h>
@ -12,78 +9,130 @@
#include <queue>
#include <mutex>
#include <condition_variable>
#include <string>
#include <any>
#include <map>
#include <list>
// 事件处理器信息结构
struct EventHandlerInfo {
std::function<void(const QVariant &)> callback; // 回调函数
quint32 objectId; // 对象ID
int localId; // 本地ID
std::function<void(const std::any &)> 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<void(const QVariant &)> callback, XNEventManager *manager)
/**
* @brief
* @param name
* @param data
* @param callback
* @param manager
*/
BaseEventTask(const std::string &name, const std::any &data,
std::function<void(const std::any &)> 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<void(const QVariant &)> eventCallback;
std::string eventName;
std::any eventData;
std::function<void(const std::any &)> eventCallback;
XNEventManager *eventManager;
};
// 实时事件任务
class RTEventTask
// 异步事件任务
class AsyncEventTask : public BaseEventTask
{
public:
RTEventTask(const QString &name, const QVariant &data,
std::function<void(const QVariant &)> 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<void(const std::any &)> 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);
}
}
}
};
// 实时事件任务
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<void(const std::any &)> callback, XNEventManager *manager)
: BaseEventTask(name, data, callback, manager)
{
}
private:
QString eventName;
QVariant eventData;
std::function<void(const QVariant &)> eventCallback;
XNEventManager *eventManager;
/**
* @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<QString, QList<EventHandlerInfo>> eventHandlers;
std::map<std::string, std::list<EventHandlerInfo>> eventHandlers;
// 处理器ID到事件名称的反向映射用于快速查找
QMap<int, QString> handlerToEvent;
std::map<int, std::string> handlerToEvent;
// 本地ID计数器
int localIdCounter = 0;
// 互斥锁,用于保护事件处理器表的线程安全访问
QMutex eventMutex;
std::mutex eventMutex;
// 线程池,用于异步执行事件处理器
QThreadPool threadPool;
// 实时线程池
QThreadPool rtThreadPool;
// 线程池相关
std::vector<std::thread> workerThreads;
std::queue<BaseEventTask *> taskQueue;
std::mutex taskMutex;
std::condition_variable taskCond;
bool running = true;
RTThreadManager rtManager;
QThreadPool normalThreadPool; // 用于非实时任务
};

View File

@ -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<XNTimeManager>();
d->threadManager = std::make_shared<XNThreadManager>();
d->scenarioManager = std::make_shared<XNScenarioManager>();
d->ddsManager = std::make_shared<XNDDSManager>();
d->modelManager = std::make_shared<XNModelManager>();
d->serviceManager = std::make_shared<XNServiceManager>();
d->eventManager = std::make_shared<XNEventManager>();
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;
}

View File

@ -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);
};

View File

@ -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;
};

View File

@ -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<std::chrono::milliseconds>(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<std::mutex> 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:

View File

@ -9,13 +9,15 @@
*
*/
#pragma once
#include <QString>
#include <QMutex>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QDir>
#include <string>
#include <mutex>
#include <fstream>
#include <chrono>
#include <filesystem>
#include <type_traits>
#include <iostream>
#include <iomanip>
#include <sstream>
/**
* @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 <typename... Args>
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 <typename T>
static QString convertToString(const T &arg)
static std::string convertToString(const T &arg)
{
if constexpr (std::is_arithmetic<T>::value) {
return QString::number(arg); // 处理数值类型
return std::to_string(arg); // 处理数值类型
} else {
return arg;
return std::string(arg);
}
}
// 递归变参函数,用于处理多个参数
template <typename T, typename... Args>
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; }
};
/**

View File

@ -11,17 +11,15 @@
#include "XNModelManager.h"
#include "XNModelManager_p.h"
#include "XNModelObject.h"
#include <QLibrary>
#include <QMetaObject>
#include <QPointer>
#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<QObject *>(metaType.create());
if (obj) {
XNModelObject *model = qobject_cast<XNModelObject *>(obj);
XNModelObjectPtr model = initialModel();
if (model) {
quint32 modelID = RegisterModel();
uint32_t modelID = RegisterModel();
if (modelID == 0) {
LOG_WARNING("0x2174 Assign Model ID Failed, Model ID is used up!");
delete obj;
dlclose(handle);
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;
return;
}
} else {
LOG_WARNING("0x2173 Model %1 Not found in dynamic link library %2!", className,
modelPath);
}
} else {
LOG_WARNING("0x2177 InitialModel function not found in dynamic link library %2!",
modelPath);
}
} else {
LOG_WARNING("0x2172 Model %1 Dynamic link library loading failed! Error: %2", className,
lib.errorString());
}
}
model->SetUniqueId(modelID);
model->SetObjectName(className);
model->SetFramework(GetFramework());
void XNModelManager::OnSetBaseFreq(const double &dBaseFreq)
{
Q_D(XNModelManager);
d->dBaseFreq = dBaseFreq;
// 使用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 %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 %s!",
modelPath.c_str());
dlclose(handle);
return;
}
} else {
LOG_WARNING("0x2172 Model %s Dynamic link library loading failed! Error: %s",
className.c_str(), dlerror());
}
}
// 模型注册
quint32 XNModelManager::RegisterModel()
uint32_t XNModelManager::RegisterModel()
{
Q_D(XNModelManager);
T_D();
// 从1000019999的编号中分配ID
for (int i = 0; i < 10000; i++) {
if (d->ModelIDAssigned[i])
@ -140,26 +128,29 @@ 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<XNModelObject *> modelList = findChildren<XNModelObject *>();
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!",

View File

@ -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类型990
*/
void OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup, quint32 RunPos,
quint32 RunPriorty);
signals:
/**
* @brief
* @param id: UINT32类型ID
* @param fun:
* @param freqGroup: UINT32类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty: UINT32类型990
*/
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);
};

View File

@ -1,25 +1,17 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include <QVector>
#include <QHash>
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<bool> ModelIDAssigned;
std::vector<bool> ModelIDAssigned;
/**
* @brief 仿
* @details 仿线 1 1/2 1/4 1/8 1/16 1/32
* @brief ID与模型指针的映射表
* @details ID与模型指针的映射表
*/
double dBaseFreq;
std::map<uint32_t, XNModelObjectPtr> ModelMap;
};

View File

@ -15,10 +15,9 @@
#include "XNModelManager.h"
#include "XNDDSManager.h"
#include "XNIDL/XNSimStatusPubSubTypes.hpp"
#include <QMetaMethod>
// 默认构造函数
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);
T_D();
if (initialType == 0) {
// 读取配置文件,设置循环执行函数
QFile file(GetXmlPath());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
std::ifstream file(GetXmlPath());
if (!file.is_open()) {
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);
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;
}
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());
// 读取配置文件的模型参数
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->_runFreq = funcNode.left(tmp).toInt();
d->_setFreq = d->_setFreq / pow(2.0, d->_runFreq);
d->_runNode = funcNode.right(funcNode.length() - tmp - 1).toInt();
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));
// 注册周期性函数
emit RegisterFunction(getUniqueId(), std::bind(&XNModelObject::StepUpdate, this), d->_runFreq,
d->_runNode, d->_runPriority);
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);
}
}
// 加载动态库
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()) { // 动态库加载成功
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!",
objectName(), d->_sLibPath);
GetObjectName(), 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;
GetObjectName(), d->_sLibPath);
d->_dynamicLib = nullptr;
}
}
// 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");
// 处理指令列表
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: 处理命令列表
}
}
}
}
// 单步执行函数
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<XNModelManager *>(parent());
if (modelManager == nullptr)
T_D();
auto framework = GetFramework();
if (framework == nullptr) {
LOG_WARNING("Failed to get Framework!");
return;
XNDDSManager *ddsManager = modelManager->parent()->findChild<XNDDSManager *>();
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<void(const QVariant &)> callback, bool async,
int XNModelObject::RegisterEventHandler(const std::string &eventName,
std::function<void(const std::any &)> callback, bool async,
XNEvent::Priority priority)
{
// 获取事件管理器
XNModelManager *modelManager = qobject_cast<XNModelManager *>(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<XNEventManager *>();
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<XNModelManager *>(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<XNEventManager *>();
XNEventManagerPtr eventManager = framework->GetEventManager();
if (eventManager == nullptr) {
LOG_WARNING("Failed to get EventManager!");
return;

View File

@ -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<void(const QVariant &)> 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<void(const QVariant &)> 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类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty:INT32类型990
* @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<XNModelManager *>(parent()); \
if (modelManager == nullptr) \
auto framework = GetFramework(); \
if (!framework) \
return; \
XNDDSManager *ddsManager = modelManager->parent()->findChild<XNDDSManager *>(); \
if (ddsManager == nullptr) \
XNDDSManagerPtr ddsManager = framework->GetDDSManager(); \
if (!ddsManager) \
return; \
quint32 MyID = getUniqueId();
@ -234,3 +211,10 @@ public:
#topic, MyID, std::bind(fun, this, std::placeholders::_1));
#define XN_REGISTER_PARTICIPANT_END(class) }
#define XN_MODEL_INITIALIZE(ClassName) \
extern "C" XNModelObjectPtr Initial##ClassName() \
{ \
ClassNamePtr obj = std::make_shared<ClassName>(); \
return obj; \
}

View File

@ -10,62 +10,49 @@
*/
#pragma once
#include "XNObject_p.h"
#include <QLibrary>
#include <QFunctionPointer>
#include <QHash>
#include <fastdds/dds/publisher/DataWriter.hpp>
/**
* @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<QString, FAST_DDS_MACRO::DataWriter *> _dataWriters;
std::unordered_map<std::string, FAST_DDS_MACRO::DataWriter *> _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;
};

View File

@ -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;
}

View File

@ -10,75 +10,83 @@
*/
#pragma once
#include <QObject>
#include <QVariant>
#include <QtXml/QDomDocument>
#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<XNObject>
{
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)

View File

@ -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;
};

View File

@ -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 <fstream>
#include <streambuf>
#include <cerrno>
#include <tinyxml2.h>
// 默认构造函数
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<std::string> split(const std::string &str, const std::string &delim)
{
std::vector<std::string> 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<std::string> 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";
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";
// 加载动态库
emit LoadService(dynamicLibName, libName);
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<std::string> 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));
}
emit AddThreadPool(modelGroupName, (FreqLevel)modelGroupFreq, modelGroupPriority,
ThreadCpuAffinity, (1.0E9 / basefreq) * pow(2.0, modelGroupFreq));
int ThreadCpuAffinity = 0;
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);
}
}
// 添加线程池
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;
}

View File

@ -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);
};

View File

@ -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;
};

View File

@ -4,13 +4,14 @@
#include <QLibrary>
#include <QMetaType>
#include <QObject>
#include <dlfcn.h>
#include <filesystem>
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<QObject *>(metaType.create());
if (obj) {
XNServiceObject *service = qobject_cast<XNServiceObject *>(obj);
XNServiceObjectPtr service = initialService();
if (service) {
quint32 serviceID = RegisterService();
uint32_t serviceID = RegisterService();
if (serviceID == 0) {
LOG_WARNING("0x2174 Assign Service ID Failed, Service ID is used up!");
delete obj;
dlclose(handle);
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();
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("0x2175 Service %1 Instantiation Failed, Not a subclass of "
"XNServiceObject!",
serviceName);
delete obj;
LOG_WARNING("0x2173 Service %s Not found in dynamic link library %s!",
serviceName.c_str(), servicePath.c_str());
dlclose(handle);
return;
}
} else {
LOG_WARNING(
"0x2176 Service %1 Instantiation Failed, Not a subclass of QObject!",
serviceName);
delete obj;
"0x2177 Service %s Initialization Failed, Function InitialService Not Found!",
serviceName.c_str());
dlclose(handle);
return;
}
} else {
LOG_WARNING("0x2173 Service %1 Not found in dynamic link library %2!", serviceName,
servicePath);
return;
}
} else {
LOG_WARNING("0x2177 Service %1 Initialization Failed, Function InitialService Not "
"Found!",
serviceName);
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<XNServiceObject *> serviceList = findChildren<XNServiceObject *>();
for (auto &service : serviceList) {
if (service->getUniqueId() == serviceID)
return service;
T_D();
if (d->ServiceIDAssigned[serviceID - 20000]
&& d->ServiceList.find(serviceID) != d->ServiceList.end()) {
return d->ServiceList[serviceID];
} else {
return nullptr;
}
return nullptr;
} else
return nullptr;
}
quint32 XNServiceManager::RegisterService()
uint32_t XNServiceManager::RegisterService()
{
Q_D(XNServiceManager);
T_D();
// 从2000029999的编号中分配ID
for (int i = 0; i < 10000; i++) {
if (d->ServiceIDAssigned[i])

View File

@ -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();
};

View File

@ -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<bool> ServiceIDAssigned;
std::vector<bool> ServiceIDAssigned;
/**
* @brief
* @details
*/
std::map<uint32_t, XNServiceObjectPtr> ServiceList;
};

View File

@ -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<void(const QVariant &)> 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<void(const QVariant &)> 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<XNServiceManager *>(parent());
if (serviceManager == nullptr) {
LOG_WARNING("Failed to get ServiceManager!");
return;
}
d->pEventManager = serviceManager->parent()->findChild<XNEventManager *>();
if (d->pEventManager == nullptr) {
LOG_WARNING("Failed to get EventManager!");
return;
}
QFile file(GetXmlPath());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
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;
}
QDomDocument doc;
doc.setContent(&file);
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);
tinyxml2::XMLElement *rootNode = doc.RootElement();
if (!rootNode) {
LOG_WARNING("Invalid XML file format: %1!", GetXmlPath());
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);
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 *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;
}
d->_sDescription = rootNode->FirstChildElement("Description")->GetText();
d->_sAuthor = rootNode->FirstChildElement("Author")->GetText();
d->_sVersion = rootNode->FirstChildElement("Version")->GetText();
// 解析时间
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;
}

View File

@ -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<void(const QVariant &)> 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<void(const QVariant &)> 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<XNServiceManager *>(parent()); \
if (serviceManager == nullptr) \
auto framework = GetFramework(); \
if (!framework) \
return; \
XNDDSManager *ddsManager = serviceManager->parent()->findChild<XNDDSManager *>(); \
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<ClassName>(); \
return obj; \
}

View File

@ -1,21 +1,13 @@
#pragma once
#include "XNObject_p.h"
#include <QHash>
#include <fastdds/dds/publisher/DataWriter.hpp>
#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<QString, FAST_DDS_MACRO::DataWriter *> _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<std::string, FAST_DDS_MACRO::DataWriter *> _dataWriters;
XNFrameworkPtr pFramework;
};

View File

@ -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,1CPU
*/
quint32 _uAffinity = 0;
/**
* @brief 线
*/
double _setFreq = BASE_RUN_FREQ;
/**
* @brief 线
*/
QVector<QMap<quint32, QVector<XNCallBack> > > _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<XNThreadManager *>(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<XNDDSManager *>();
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::XNThreadStatusPubSubType>(
"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;
}

View File

@ -9,36 +9,43 @@
*
*/
#pragma once
#include <QObject>
#include <QThread>
#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&:09999
*/
const uint32_t &GetRunPriority();
/**
* @brief 线
* @param uRunPriority: UINT32类型09999
*/
void SetRunPriority(const uint32_t &uRunPriority);
/**
* @brief 线CPU亲和性掩码
* @return const UINT32&: CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
const uint32_t &GetCPUAffinity();
/**
* @brief 线CPU亲和性掩码
* @param uCPUAffinity: UINT32类型CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
void SetCPUAffinity(const uint32_t &uCPUAffinity);
/**
* @brief 线
* @param fun:XNCallBack函数包装器类型
* @param freq:FreqLevel类型
* @param pos:UINT32类型
* @param priorty:UINT32类型990
* @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&:09999
*/
const quint32 &GetRunPriority();
/**
* @brief 线
* @param uRunPriority: UINT32类型09999
*/
void SetRunPriority(const quint32 &uRunPriority);
/**
* @brief 线CPU亲和性掩码
* @return const UINT32&: CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
const quint32 &GetCPUAffinity();
/**
* @brief 线CPU亲和性掩码
* @param uCPUAffinity: UINT32类型CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
void SetCPUAffinity(const quint32 &uCPUAffinity);
/**
* @brief 线
* @param fun:XNCallBack函数包装器类型
* @param freq:FreqLevel类型
* @param pos:UINT32类型
* @param priorty:UINT32类型990
* @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();
// /**
// * @brief 初始化周期性函数表
// */
//void InitialFunPool();
};
XNCLASS_PTR_DECLARE(XNThread)

View File

@ -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<funInfo>();
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<XNThread *>();
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) {
// 如果频率分组不是05
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<XNThread *>();
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<XNThread>(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);
for (auto &thread : d->threadList) {
thread.second->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);
}
// 获取线程数量
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;
}

View File

@ -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类型线990
* @param CPUAff: UINT32类型线CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
* @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类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty: UINT32类型990
@ -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();
};

View File

@ -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<funInfo>;
using funInfoPtr = std::shared_ptr<funInfo>;
/**
* @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<uint32_t, XNThreadPtr> threadList;
/**
* @brief
*/
QMap<quint32, std::vector<funInfoPtr> > funList;
/**
* @brief
*/
double dRunFreq = BASE_RUN_FREQ;
/**
* @brief
*/
double dRunInter = BASE_RUN_INTER;
std::map<uint32_t, std::vector<funInfoPtr> > funList;
/**
* @brief 线ID
*/
QSet<quint32> threadIDMap;
/**
* @brief 线
*/
quint32 threadCount = 0;
std::set<uint32_t> threadIDMap;
};

76
XNCore/XNThread_p.h Normal file
View File

@ -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,1CPU
*/
uint32_t _uAffinity = 0;
/**
* @brief 线
*/
double _setFreq = BASE_RUN_FREQ;
/**
* @brief 线
*/
std::vector<std::map<uint32_t, std::vector<XNCallBack> > > _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;
};

View File

@ -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<XNThread> 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<int64_t>(BASE_RUN_INTER * 1.0E6));
pthread_mutex_unlock(&(d->_mtx));
}

View File

@ -10,9 +10,9 @@
*/
#pragma once
#include "XNBaseFrameObject.h"
#include <QDateTime>
#include <chrono>
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类型仿
*/
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: 线

View File

@ -11,21 +11,12 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include "XNThread.h"
#include <chrono>
/**
* @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 线
*/

View File

@ -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"
}
}

View File

@ -137,6 +137,16 @@ void XNGroundHandling::StepUpdate()
OnOutput();
}
// template <class T1, class T2>
// 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);

View File

@ -1,7 +1,7 @@
#pragma once
#include "XNGroundHandling_global.h"
#include <XNCore/XNModelObject.h>
#include "../XNGroundHandlingInterface/XNGroundHandlingPubSubTypes.hpp"
#include "../XNGroundHandlingInterface/XNGroundHandlingInterface.hpp"
class XNGroundHandlingPrivate;

View File

@ -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<int32_t>& _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<int32_t>&& _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<int32_t>& 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<int32_t>& groundhandling_model_heartbeat()
{
return m_groundhandling_model_heartbeat;
}
@ -3825,7 +3835,7 @@ public:
private:
int32_t m_groundhandling_model_heartbeat{0};
eprosima::fastcdr::optional<int32_t> m_groundhandling_model_heartbeat;
};

View File

@ -84,7 +84,7 @@ module XNSim
};
struct GroundHandling_heartbeat
{
long groundhandling_model_heartbeat;
@optional long groundhandling_model_heartbeat;
};
};
};

View File

@ -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};

View File

@ -1229,7 +1229,10 @@ void serialize_key(
static_cast<void>(scdr);
static_cast<void>(data);
scdr << data.groundhandling_model_heartbeat();
if (data.groundhandling_model_heartbeat().has_value())
{
scdr << data.groundhandling_model_heartbeat().value();
}
}

View File

@ -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<const char *>(&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

View File

@ -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 <typename T>
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 <typename T>
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);

View File

@ -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<AppliedBuiltinMemberAnnotations> member_ann_builtin_groundhandling_model_heartbeat;
ann_custom_GroundHandling_heartbeat.reset();
AppliedAnnotationSeq tmp_ann_custom_groundhandling_model_heartbeat;
eprosima::fastcdr::optional<std::string> unit_groundhandling_model_heartbeat;
eprosima::fastcdr::optional<AnnotationParameterValue> min_groundhandling_model_heartbeat;
eprosima::fastcdr::optional<AnnotationParameterValue> max_groundhandling_model_heartbeat;
eprosima::fastcdr::optional<std::string> 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);