diff --git a/XNCore_Win/CMakeLists.txt b/XNCore_Win/CMakeLists.txt new file mode 100644 index 0000000..7ba0d81 --- /dev/null +++ b/XNCore_Win/CMakeLists.txt @@ -0,0 +1,149 @@ +cmake_minimum_required(VERSION 3.16) + +project(XNCore LANGUAGES CXX) + +# 第三方库路径(需要根据实际情况修改) +set(THIRD_PARTY_DIR "I:/MyPrj/XNSim/ThirdPart") + +# Windows平台设置32位编译 +if(WIN32) + set(CMAKE_GENERATOR_PLATFORM "Win32" CACHE STRING "Target platform" FORCE) + set(CMAKE_VS_PLATFORM_NAME "Win32" CACHE STRING "Win32/x64 build." FORCE) + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE) + set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE) + + set(CMAKE_SIZEOF_VOID_P 4) + + add_definitions(-DWIN32 -D_WINDOWS) + + +endif() + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +if(WIN32) + # 设置OpenSSL路径(使用缓存变量) + set(OPENSSL_ROOT_DIR "${THIRD_PARTY_DIR}/openssl" CACHE PATH "OpenSSL root directory") + set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include" CACHE PATH "OpenSSL include directory") + set(OPENSSL_LIBRARIES "${OPENSSL_ROOT_DIR}/lib" CACHE PATH "OpenSSL library directory") + set(OPENSSL_CRYPTO_LIBRARY "${OPENSSL_ROOT_DIR}/lib/libcrypto.lib" CACHE FILEPATH "OpenSSL crypto library") + set(OPENSSL_SSL_LIBRARY "${OPENSSL_ROOT_DIR}/lib/libssl.lib" CACHE FILEPATH "OpenSSL ssl library") + + # 验证OpenSSL目录 + if(NOT EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/ssl.h") + message(FATAL_ERROR "OpenSSL headers not found in ${OPENSSL_INCLUDE_DIR}") + endif() + + # 设置SQLite3路径 + set(SQLITE3_ROOT_DIR "${THIRD_PARTY_DIR}/sqlite3/") + set(SQLITE3_INCLUDE_DIR "${SQLITE3_ROOT_DIR}/include") + set(SQLITE3_LIBRARIE "${SQLITE3_ROOT_DIR}/lib/sqlite3.lib") + + # 设置tinyxml2路径 + set(TINYXML2_INCLUDE_DIR "${THIRD_PARTY_DIR}/tinyxml2-6.0.0/") + file(GLOB TINYXML2_SOURCES "${THIRD_PARTY_DIR}/tinyxml2-6.0.0/*.cpp") +else() + find_package(nlohmann_json REQUIRED) + find_package(Threads REQUIRED) + find_package(SQLite3 REQUIRED) +endif() + +find_package(OpenSSL REQUIRED) +if(NOT fastcdr_FOUND) + find_package(fastcdr 2 REQUIRED) +endif() +if(NOT fastdds_FOUND) + find_package(fastdds 3 REQUIRED) +endif() + +set(XNCORE_SOURCES "") + +add_subdirectory(XNBaseFrameObject) +add_subdirectory(XNDDSInterface) +add_subdirectory(XNDDSManager) +add_subdirectory(XNEventManager) +add_subdirectory(XNFramework) +add_subdirectory(XNGlobalDefine) +add_subdirectory(XNLogger) +add_subdirectory(XNModelManager) +add_subdirectory(XNModelObject) +add_subdirectory(XNObject) +add_subdirectory(XNConfigManager) +add_subdirectory(XNServiceManager) +add_subdirectory(XNServiceObject) +add_subdirectory(XNThreadManager) +add_subdirectory(XNThreadObject) +add_subdirectory(XNTimeManager) +add_subdirectory(XNIDL) + +if(WIN32) + add_library(XNCore SHARED + ${XNCORE_SOURCES} + ${XNCORE_IDL_SOURCES} + ${TINYXML2_SOURCES} + ${THIRD_PARTY_DIR}/nlohmann/json.hpp + ) + + target_include_directories(XNCore PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${OPENSSL_INCLUDE_DIR} + ${SQLITE3_INCLUDE_DIR} + ${TINYXML2_INCLUDE_DIR} + ${THIRD_PARTY_DIR} + ) +else() + add_library(XNCore SHARED + ${XNCORE_SOURCES} + ${XNCORE_IDL_SOURCES} + ) + target_include_directories(XNCore PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ) +endif() + +if(WIN32) +target_link_libraries(XNCore PRIVATE + ${CMAKE_THREAD_LIBS_INIT} + fastcdr + fastdds + OpenSSL::SSL + OpenSSL::Crypto + ${SQLITE3_LIBRARIE} + ) +else() + target_link_libraries(XNCore PRIVATE + ${CMAKE_THREAD_LIBS_INIT} + fastcdr + fastdds + pthread + OpenSSL::SSL + OpenSSL::Crypto + nlohmann_json + sqlite3 + tinyxml2 + dl + ) +endif() + +target_compile_definitions(XNCore PRIVATE XNCORE_LIBRARY) + +# Check if CMAKE_INSTALL_PREFIX is set to its default value +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/../Release" CACHE PATH "Install path prefix" FORCE) +endif() + +include(GNUInstallDirs) +install(TARGETS XNCore + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION . +) + +# 使用 install 命令在安装时拷贝头文件 +file(GLOB_RECURSE ALL_HEADERS "*.h") +install(FILES ${ALL_HEADERS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/XNCore) + +file(GLOB IDL_FILES "XNIDL/*") +install(FILES ${IDL_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/XNIDL) \ No newline at end of file diff --git a/XNCore_Win/XNBaseFrameObject/CMakeLists.txt b/XNCore_Win/XNBaseFrameObject/CMakeLists.txt new file mode 100644 index 0000000..6c12682 --- /dev/null +++ b/XNCore_Win/XNBaseFrameObject/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNBASEFRAMEOBJECT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNBaseFrameObject.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNBaseFrameObject_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNBaseFrameObject.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNBASEFRAMEOBJECT_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject.cpp b/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject.cpp new file mode 100644 index 0000000..8700a39 --- /dev/null +++ b/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject.cpp @@ -0,0 +1,26 @@ +#include "XNBaseFrameObject.h" +#include "XNBaseFrameObject_p.h" + +namespace XNSim { +XNBaseFrameObject::XNBaseFrameObject() + : XNObject(new XNBaseFrameObjectPrivate()) {} + +XNBaseFrameObject::~XNBaseFrameObject() {} + +XNBaseFrameObject::XNBaseFrameObject(PrivateType *p) : XNObject(p) {} + +XNFrameObjectStatus XNBaseFrameObject::GetFrameObjectStatus() { + T_D(); + return d->_status; +} + +XNFrameworkPtr XNBaseFrameObject::GetFramework() { + T_D(); + return d->_framework; +} + +void XNBaseFrameObject::SetFramework(XNFrameworkPtr framework) { + T_D(); + d->_framework = framework; +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject.h b/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject.h new file mode 100644 index 0000000..a9029ba --- /dev/null +++ b/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject.h @@ -0,0 +1,81 @@ +/** + * @file XNBaseFrameObject.h + * @author jinchao + * @brief 框架对象基类 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ +#pragma once + +#include + +namespace XNSim { +struct XNBaseFrameObjectPrivate; + +/** + * @brief 框架对象基类 + */ +class XNCORE_EXPORT XNBaseFrameObject : public XNObject { + /** + * @brief 宏定义,用于禁用拷贝构造函数 + */ + XN_METATYPE(XNBaseFrameObject, XNObject) + + /** + * @brief 宏定义,用于声明私有数据成员 + */ + XN_DECLARE_PRIVATE(XNBaseFrameObject) + +public: + /** + * @brief 构造函数 + * @param parent 父对象 + */ + XNBaseFrameObject(); + + /** + * @brief 析构函数 + */ + virtual ~XNBaseFrameObject(); + +protected: + /** + * @brief 构造函数 + * @param dd 私有数据成员 + * @param parent 父对象 + */ + XNBaseFrameObject(PrivateType *p); + +public: + /** + * @brief 初始化 + */ + virtual XN_BOOL Initialize() = 0; + + /** + * @brief 准备执行 + */ + virtual XN_BOOL PrepareForExecute() = 0; + + /** + * @brief 获取框架对象状态 + * @return 框架对象状态 + */ + XNFrameObjectStatus GetFrameObjectStatus(); + + /** + * @brief 获取框架对象 + * @return 框架对象 + */ + XNFrameworkPtr GetFramework(); + + /** + * @brief 设置框架对象 + * @param framework 框架对象 + */ + void SetFramework(XNFrameworkPtr framework); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject_p.h b/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject_p.h new file mode 100644 index 0000000..fe3f717 --- /dev/null +++ b/XNCore_Win/XNBaseFrameObject/XNBaseFrameObject_p.h @@ -0,0 +1,30 @@ +/** + * @file XNBaseFrameObject_p.h + * @author jinchao + * @brief 框架对象基类的私有数据成员 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ + +#pragma once + +#include + +namespace XNSim { +/** + * @brief 框架对象基类的私有数据成员 + */ +struct XNBaseFrameObjectPrivate : public XNObjectPrivate { + /** + * @brief 框架对象状态 + */ + XNFrameObjectStatus _status = XNFrameObjectStatus::NotReady; + /** + * @brief 框架对象 + */ + XNFrameworkPtr _framework; +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNConfigManager/CMakeLists.txt b/XNCore_Win/XNConfigManager/CMakeLists.txt new file mode 100644 index 0000000..dec4e96 --- /dev/null +++ b/XNCore_Win/XNConfigManager/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNCONFIGMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNConfigManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNConfigManager_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNConfigManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNCONFIGMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNConfigManager/XNConfigManager.cpp b/XNCore_Win/XNConfigManager/XNConfigManager.cpp new file mode 100644 index 0000000..6f0a422 --- /dev/null +++ b/XNCore_Win/XNConfigManager/XNConfigManager.cpp @@ -0,0 +1,408 @@ +/** + * @file XNScenarioManager.cpp + * @author jinchao + * @brief 运行环境描述管理器类源文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#include "XNScenarioManager.h" +#include "XNScenarioManager_p.h" +#include "XNFramework.h" +#include "XNDDSManager.h" +#include "XNThreadManager.h" +#include "XNModelManager.h" +#include "XNServiceManager.h" +#include +#include +#include +#include + +// 默认构造函数 +XNScenarioManager::XNScenarioManager() : XNBaseFrameObject(new XNScenarioManagerPrivate()) +{ + SetUniqueId(5); + SetObjectName("XNScenarioManager"); +} + +XNScenarioManager::~XNScenarioManager() +{ +} + +XNScenarioManager::XNScenarioManager(PrivateType *p) : XNBaseFrameObject(p) +{ +} + +// 获取运行环境名称 +const std::string &XNScenarioManager::GetSimName() +{ + T_D(); + return d->_ScenarioName; +} + +// 设置运行环境名称 +void XNScenarioManager::SetSimName(const std::string &simName) +{ + T_D(); + d->_ScenarioName = simName; +} + +// 初始化 +bool XNScenarioManager::Initialize() +{ + T_D(); + LOG_INFO("XNScenarioManager Initialize Success!"); + d->_status = XNFrameObjectStatus::Initialized; + return true; +} + +bool XNScenarioManager::PrepareForExecute() +{ + T_D(); + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("XNScenarioManager is prepared!"); + return true; +} + +// 运行环境配置文件解析 +bool XNScenarioManager::AnalysisScenarioXml(const std::string &XmlPath, uint32_t initialType) +{ + T_D(); + if (initialType == 0) { + return ParseScenarioXml(XmlPath); + } else { + return ParseConfig(XmlPath); + } +} + +// 解析运行环境描述文件 +bool XNScenarioManager::ParseScenarioXml(const std::string &XmlPath) +{ + T_D(); + std::ifstream file(XmlPath); + if (!file.is_open()) { + LOG_ERROR("0x2100 打开运行环境描述文件: %1出错,错误信息: %2", XmlPath, strerror(errno)); + return false; + } + tinyxml2::XMLDocument doc; + if (doc.LoadFile(XmlPath.c_str()) != tinyxml2::XML_SUCCESS) { + LOG_ERROR("0x2100 解析XML文件: %1 失败", XmlPath); + file.close(); + return false; + } + tinyxml2::XMLElement *root = doc.FirstChildElement("Scenario"); + // 读取环境信息 + tinyxml2::XMLElement *envInfo = root->FirstChildElement("Environment"); + std::string OSName = envInfo->Attribute("OSName"); + std::string version = envInfo->Attribute("Version"); + std::string kernel = envInfo->Attribute("RTXVersion"); + std::string planeName = envInfo->Attribute("PlaneName"); + // 设置工作目录 + std::string rootPath = envInfo->Attribute("WorkPath"); + GetFramework()->SetWorkPath(rootPath); + // 设置模型库目录 + std::string modelPath = rootPath + envInfo->Attribute("ModelsPath"); + GetFramework()->SetModelPath(modelPath); + // 设置服务库目录 + std::string servicePath = rootPath + envInfo->Attribute("ServicesPath"); + GetFramework()->SetServicePath(servicePath); + // 设置域ID + uint32_t domainID = std::stoul(envInfo->Attribute("DomainID")); + GetFramework()->GetDDSManager()->SetDomainID(domainID); + // 读取CPU亲和性 + std::string cpuAff = envInfo->Attribute("CPUAffinity"); + std::vector cpuAffList = XNSim::split(cpuAff, ","); + + //读取服务列表 + 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"); + std::string serviceVersion = service->Attribute("Version"); + libName = XNSim::getFileNameWithoutExt(libName); + std::string dynamicLibName = servicePath + "/lib" + libName + ".so." + serviceVersion; + // 加载动态库 + GetFramework()->GetServiceManager()->LoadService(dynamicLibName, libName, + serviceVersion, 0); + service = service->NextSiblingElement("Service"); + } + } + + // 读取模型分组 + tinyxml2::XMLElement *modelGroup = root->FirstChildElement("ModelGroup"); + while (modelGroup) { + // 读取模型分组名称 + std::string modelGroupName = modelGroup->Attribute("Name"); + // 读取模型分组频率 + double modelGroupFreq = std::stod(modelGroup->Attribute("Freq")); + // 读取模型分组优先级 + int modelGroupPriority = XNSim::safe_stoi(modelGroup->Attribute("Priority")); + if (modelGroupPriority > 99 || modelGroupPriority < 0) { + LOG_ERROR("0x2100 模型分组优先级设置错误,优先级值:%d", modelGroupPriority); + return false; + } + // 读取模型分组CPU亲和性 + std::string modelGroupCPUAff = modelGroup->Attribute("CPUAff"); + std::vector modelGroupCPUAffList = XNSim::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 (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); + + // 读取模型列表 + tinyxml2::XMLElement *model = modelGroup->FirstChildElement("Model"); + while (model) { + std::string modelName = model->Attribute("Name"); + std::string libName = model->Attribute("ClassName"); + std::string modelVersion = model->Attribute("Version"); + libName = XNSim::getFileNameWithoutExt(libName); + std::string dynamicLibName = modelPath + "/lib" + libName + ".so." + modelVersion; + // 加载动态库 + GetFramework()->GetModelManager()->LoadModel(dynamicLibName, libName, modelVersion, + planeName, 0, threadID); + model = model->NextSiblingElement("Model"); + } + + modelGroup = modelGroup->NextSiblingElement("ModelGroup"); + } + + return true; +} + +// 解析构型配置文件 +bool XNScenarioManager::ParseConfig(const std::string &ConfigID) +{ + T_D(); + // 获取数据库路径 + std::string XNCorePath = std::getenv("XNCore"); + if (XNCorePath.empty()) { + LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!"); + return false; + } + std::string dbPath = XNCorePath + "/database/XNSim.db"; + + // 打开数据库 + sqlite3 *db; + if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) { + LOG_ERROR("0x1016 打开数据库失败: %1", sqlite3_errmsg(db)); + return false; + } + + // 准备SQL语句 + std::string sql = "SELECT * FROM Configuration WHERE ConfID = ?"; + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { + LOG_ERROR("0x1017 准备SQL语句失败: %1", sqlite3_errmsg(db)); + sqlite3_close(db); + return false; + } + + // 绑定参数 + int configIdInt = XNSim::safe_stoi(ConfigID); + if (sqlite3_bind_int(stmt, 1, configIdInt) != SQLITE_OK) { + LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + + // 执行查询 + if (sqlite3_step(stmt) != SQLITE_ROW) { + LOG_ERROR("0x1019 未找到配置ID为%1的记录", ConfigID); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + std::string planeName = XNSim::getStringFromSqlite3(stmt, 1); + std::string osName = XNSim::getStringFromSqlite3(stmt, 3); + std::string version = XNSim::getStringFromSqlite3(stmt, 4); + std::string kernel = XNSim::getStringFromSqlite3(stmt, 5); + std::string rootPath = XNSim::getStringFromSqlite3(stmt, 7); + if (rootPath.empty()) { + LOG_WARNING("0x1020 未设置工作目录,使用默认工作目录: %1", XNCorePath); + rootPath = XNCorePath; + } + GetFramework()->SetWorkPath(rootPath); + // 设置模型库目录 + std::string modelPath = rootPath + XNSim::getStringFromSqlite3(stmt, 8); + if (modelPath.empty()) { + LOG_WARNING("0x1020 未设置模型库目录,使用默认模型库目录: %1/Models", XNCorePath); + modelPath = XNCorePath + "/Models"; + } + GetFramework()->SetModelPath(modelPath); + // 设置服务库目录 + std::string servicePath = rootPath + XNSim::getStringFromSqlite3(stmt, 9); + if (servicePath.empty()) { + LOG_WARNING("0x1020 未设置服务库目录,使用默认服务库目录: %1/Services", XNCorePath); + servicePath = XNCorePath + "/Services"; + } + GetFramework()->SetServicePath(servicePath); + // 设置域ID + uint32_t domainID = std::stoul(XNSim::getStringFromSqlite3(stmt, 10)); + if (domainID == 0 || domainID > 225) { + LOG_WARNING("0x1020 域ID设置错误,使用默认域ID: 10"); + domainID = 10; + } + GetFramework()->GetDDSManager()->SetDomainID(domainID); + // 读取CPU亲和性 + std::string cpuAff = XNSim::getStringFromSqlite3(stmt, 6); + std::vector cpuAffList = XNSim::split(cpuAff, ","); + + //查询LoadServices表读取服务信息 + std::string servicesSql = "SELECT * FROM LoadServices WHERE ConfID = ?"; + sqlite3_stmt *servicesStmt; + if (sqlite3_prepare_v2(db, servicesSql.c_str(), -1, &servicesStmt, nullptr) != SQLITE_OK) { + LOG_ERROR("0x1020 准备LoadServices查询语句失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + // 绑定参数 + if (sqlite3_bind_int(servicesStmt, 1, configIdInt) != SQLITE_OK) { + LOG_ERROR("0x1021 绑定LoadServices参数失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + + // 执行查询并处理结果 + while (sqlite3_step(servicesStmt) == SQLITE_ROW) { + // 获取服务信息 + std::string ClassName = XNSim::getStringFromSqlite3(servicesStmt, 1); + std::string ServiceVersion = XNSim::getStringFromSqlite3(servicesStmt, 2); + std::string ServiceName = XNSim::getStringFromSqlite3(servicesStmt, 3); + + ClassName = XNSim::getFileNameWithoutExt(ClassName); + std::string dynamicLibName = servicePath + "/lib" + ClassName + ".so." + ServiceVersion; + // 加载动态库 + GetFramework()->GetServiceManager()->LoadService(dynamicLibName, ClassName, ServiceVersion, + 1); + } + + // 查询LoadModelGroups表读取模型组信息 + std::string modelGroupsSql = "SELECT * FROM LoadModelGroups WHERE ConfID = ?"; + sqlite3_stmt *modelGroupsStmt; + if (sqlite3_prepare_v2(db, modelGroupsSql.c_str(), -1, &modelGroupsStmt, nullptr) + != SQLITE_OK) { + LOG_ERROR("0x1020 准备LoadModelGroups查询语句失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + + // 绑定参数 + if (sqlite3_bind_int(modelGroupsStmt, 1, configIdInt) != SQLITE_OK) { + LOG_ERROR("0x1021 绑定LoadModelGroups参数失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(modelGroupsStmt); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + + // 执行查询并处理结果 + while (sqlite3_step(modelGroupsStmt) == SQLITE_ROW) { + // 获取模型组信息 + std::string GroupID = XNSim::getStringFromSqlite3(modelGroupsStmt, 1); + std::string GroupName = XNSim::getStringFromSqlite3(modelGroupsStmt, 2); + double GroupFreq = std::stod(XNSim::getStringFromSqlite3(modelGroupsStmt, 3)); + uint32_t GroupPriority = XNSim::safe_stoi(XNSim::getStringFromSqlite3(modelGroupsStmt, 4)); + std::string GroupCPUAff = XNSim::getStringFromSqlite3(modelGroupsStmt, 5); + std::vector GroupCPUAffList = XNSim::split(GroupCPUAff, ","); + + // 验证CPU亲和性 + for (const auto &cpu : GroupCPUAffList) { + if (std::find(cpuAffList.begin(), cpuAffList.end(), cpu) == cpuAffList.end()) { + LOG_ERROR("0x2100 模型分组CPU亲和性设置错误,CPU亲和性值:%s,进程CPU亲和性值:%s", + cpu.c_str(), cpuAff.c_str()); + sqlite3_finalize(modelGroupsStmt); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + } + + int ThreadCpuAffinity = 0; + for (const auto &cpu : GroupCPUAffList) { + auto it = std::find(cpuAffList.begin(), cpuAffList.end(), cpu); + if (it != cpuAffList.end()) { + ThreadCpuAffinity |= 1 << std::distance(cpuAffList.begin(), it); + } + } + LOG_INFO("0x1021 添加线程池: %1", GroupName); + // 添加线程池 + uint32_t threadID = GetFramework()->GetThreadManager()->AddThreadPool( + GroupName, GroupFreq, GroupPriority, ThreadCpuAffinity); + + // 准备查询LoadModels表的SQL语句 + std::string modelsSql = "SELECT * FROM LoadModels WHERE GroupID = ?"; + sqlite3_stmt *modelsStmt = nullptr; + if (sqlite3_prepare_v2(db, modelsSql.c_str(), -1, &modelsStmt, nullptr) != SQLITE_OK) { + LOG_ERROR("0x1022 准备LoadModels查询语句失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(modelGroupsStmt); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + + // 绑定参数 + if (sqlite3_bind_int(modelsStmt, 1, XNSim::safe_stoi(GroupID)) != SQLITE_OK) { + LOG_ERROR("0x1023 绑定LoadModels参数失败: %1", sqlite3_errmsg(db)); + sqlite3_finalize(modelsStmt); + sqlite3_finalize(modelGroupsStmt); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return false; + } + + // 执行查询并处理结果 + while (sqlite3_step(modelsStmt) == SQLITE_ROW) { + // 获取模型信息 + std::string ClassName = XNSim::getStringFromSqlite3(modelsStmt, 1); + std::string ModelVersion = XNSim::getStringFromSqlite3(modelsStmt, 2); + std::string ModelName = XNSim::getStringFromSqlite3(modelsStmt, 3); + + ClassName = XNSim::getFileNameWithoutExt(ClassName); + std::string dynamicLibName = modelPath + "/lib" + ClassName + ".so." + ModelVersion; + // 加载动态库 + LOG_INFO("0x1021 加载模型: %1", dynamicLibName); + GetFramework()->GetModelManager()->LoadModel(dynamicLibName, ClassName, ModelVersion, + planeName, 1, threadID); + } + // 清理资源 + sqlite3_finalize(modelsStmt); + } + + // 清理资源 + sqlite3_finalize(modelGroupsStmt); + sqlite3_finalize(servicesStmt); + sqlite3_finalize(stmt); + sqlite3_close(db); + return true; +} diff --git a/XNCore_Win/XNConfigManager/XNConfigManager.h b/XNCore_Win/XNConfigManager/XNConfigManager.h new file mode 100644 index 0000000..b28bac4 --- /dev/null +++ b/XNCore_Win/XNConfigManager/XNConfigManager.h @@ -0,0 +1,98 @@ +/** + * @file XNScenarioDescriptor.h + * @author jinchao + * @brief 运行环境描述管理器类头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include + +namespace XNSim { +struct XNConfigManagerPrivate; + +/** + * @brief 构型管理器类 + * @details 主要负责解析构型配置来设置系统运行参数。 + */ +class XNConfigManager : public XNBaseFrameObject { + XN_METATYPE(XNConfigManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNConfigManager) +public: + /** + * @brief 构型管理器类默认构造函数 + */ + XNConfigManager(); + + /** + * @brief 构型管理器类析构函数 + */ + virtual ~XNConfigManager(); + +protected: + /** + * @brief 构型管理器类带参构造函数 + * @param p:私有结构体指针 + * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 + */ + XNConfigManager(PrivateType *p); + +public: + /** + * @brief 获取构型名称 + * @return const XNString&: 构型名称 + */ + const XN_STRING &GetSimName(); + + /** + * @brief 设置构型名称 + * @param simName: XNString类型,构型名称 + */ + void SetSimName(const XN_STRING &simName); + +public: + /** + * @brief 初始化构型管理器 + * @return true: 初始化成功 + * @return false: 初始化失败 + * @details 构型管理器的初始化接口函数 + */ + virtual XN_BOOL Initialize() override; + + /** + * @brief 仿真运行前最后处理 + * @note 构型管理器在系统运行开始前的准备工作 + */ + virtual XN_BOOL PrepareForExecute() override; + + /** + * @brief 构型配置文件解析 + * @param XmlPath: std::string类型,构型配置文件解析路径 + * @param initialType: uint32_t类型,初始化类型 + * @return true: 解析成功 + * @return false: 解析失败 + */ + virtual XN_BOOL AnalysisScenarioXml(const XN_STRING &XmlPath, + XN_UINT32 initialType); + +private: + /** + * @brief 解析构型配置文件 + * @param XmlPath: std::string类型,构型配置文件解析路径 + * @return true: 解析成功 + * @return false: 解析失败 + */ + XN_BOOL ParseScenarioXml(const XN_STRING &XmlPath); + + /** + * @brief 解析构型配置文件 + * @param ConfigID: std::string类型,构型配置文件在数据库中的ID + * @return true: 解析成功 + * @return false: 解析失败 + */ + XN_BOOL ParseConfig(const XN_STRING &ConfigID); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNConfigManager/XNConfigManager_p.h b/XNCore_Win/XNConfigManager/XNConfigManager_p.h new file mode 100644 index 0000000..62892f7 --- /dev/null +++ b/XNCore_Win/XNConfigManager/XNConfigManager_p.h @@ -0,0 +1,24 @@ +/** + * @file XNScenarioDescriptor_p.h + * @author jinchao + * @brief 运行环境描述管理器类私有头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include + +namespace XNSim { +/** + * @brief 运行环境描述管理器类私有结构体 + */ +struct XNScenarioManagerPrivate : public XNBaseFrameObjectPrivate { + /** + * @brief 运行环境名称 + */ + XN_STRING _ConfigName; +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNDDSInterface/CMakeLists.txt b/XNCore_Win/XNDDSInterface/CMakeLists.txt new file mode 100644 index 0000000..7d6dd39 --- /dev/null +++ b/XNCore_Win/XNDDSInterface/CMakeLists.txt @@ -0,0 +1,6 @@ +set(XNDDSINTERFACE_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNDDSInterface.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNDDSInterface.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNDDSINTERFACE_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNDDSInterface/XNDDSInterface.cpp b/XNCore_Win/XNDDSInterface/XNDDSInterface.cpp new file mode 100644 index 0000000..9c0a69c --- /dev/null +++ b/XNCore_Win/XNDDSInterface/XNDDSInterface.cpp @@ -0,0 +1,94 @@ +#include "XNDDSInterface.h" +#include "XNDDSManager/XNDDSManager.h" +#include "XNFramework/XNFramework.h" + +namespace XNSim { +XNByteArray XNDDSInterface::getUDPPackage() { + XNByteArray result; + + size_t currentPos = 0; + + // 复制头部 + result.append(header, headerSize); + currentPos = headerSize; + + // 复制数据 + { + std::lock_guard lock(dataMutex); + for (auto func : getByteArrayFunction) { + XNByteArray byteArray = func(); + size_t byteArraySize = byteArray.size(); + if (currentPos + byteArraySize <= MAX_UDP_PACKET_SIZE) { + result.append(byteArray); + currentPos += byteArraySize; // 使用实际返回的字节数组大小 + } else { + break; // 超出最大包大小 + } + } + } + + // 更新包大小 + if (currentPos >= 8 && currentPos < MAX_UDP_PACKET_SIZE) { + result[6] = static_cast((currentPos >> 8) & 0xFF); + result[7] = static_cast(currentPos & 0xFF); + } + + return result; +} + +void XNDDSInterface::setDataByUDPPackage(const XNByteArray &package) { + if (package.size() < headerSize) { + return; + } + + // 获取包大小 + uint16_t packageSize = (package[6] << 8) | package[7]; + if (packageSize > MAX_UDP_PACKET_SIZE) { + return; + } + + uint32_t currentPos = 8; + + // 设置数据 + { + std::lock_guard lock(outDataMutex); + clearOutData(); + for (auto &func : setByteArrayFunction) { + func(package, currentPos); + } + } + sendOutData(); +} + +std::unordered_map +XNDDSInterface::getStringData(const std::vector &varNames) { + std::unordered_map result; + + { + std::lock_guard lock(dataMutex); + for (const auto &varName : varNames) { + auto it = getDataFunction.find(varName); + if (it == getDataFunction.end()) { + continue; + } + result[varName] = it->second(); + } + } + + return result; +} + +void XNDDSInterface::setDataByString( + const std::unordered_map &data) { + std::lock_guard lock(outDataMutex); + clearOutData(); + for (const auto &[varName, value] : data) { + auto it = setDataFunction.find(varName); + if (it == setDataFunction.end()) { + continue; + } + it->second(value); + } + sendOutData(); +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNDDSInterface/XNDDSInterface.h b/XNCore_Win/XNDDSInterface/XNDDSInterface.h new file mode 100644 index 0000000..596d588 --- /dev/null +++ b/XNCore_Win/XNDDSInterface/XNDDSInterface.h @@ -0,0 +1,422 @@ +#pragma once + +#include "XNGlobalDefine/XNDefine.h" + +namespace XNSim { +// 定义UDP包的最大大小 +constexpr XN_SIZE MAX_UDP_PACKET_SIZE = 40000; + +using XNInterfaceToDataMap = std::unordered_map; +using XNInterfaceList = std::vector; +using XNGetDataFunction = std::function; +using XNSetDataFunction = std::function; +using XNGetByteArrayFunction = std::function; +using XNSetByteArrayFunction = std::function; +using XNGetDataFunctionMap = std::unordered_map; +using XNSetDataFunctionMap = std::unordered_map; +using XNGetByteArrayFunctionMap = std::vector; +using XNSetByteArrayFunctionMap = std::vector; + +class XNDDSInterface { +public: + XNDDSInterface() = default; + virtual ~XNDDSInterface() = default; + +public: + /** + * @brief 初始化 + * @param framework: 框架 + */ + virtual void Initialize(XNFrameworkPtr framework, XN_UINT32 modelID, + XN_UINT32 DDS_type) = 0; + + /** + * @brief 获取该接口的UDP包 + * @return 字节数组 + */ + XNByteArray getUDPPackage(); + + /** + * @brief 通过UDP包设置数据 + * @param package: UDP包 + */ + void setDataByUDPPackage(const XNByteArray &package); + + /** + * @brief 批量获取指定变量的数据 + * @param varNames: 变量名列表 + * @return: 变量名到数据的映射 + */ + XNInterfaceToDataMap getStringData(const XNInterfaceList &varNames); + + /** + * @brief 批量设置指定变量的数据 + * @param data: 变量名到数据的映射 + */ + void setDataByString(const XNInterfaceToDataMap &data); + +protected: + /** + * @brief 获取指定变量的字节数据,用于网络通信 + * @param data: 数据 + * @return 字节数组 + */ + template XNByteArray getByteArray(const XNDDSOptional &data) { + XNByteArray result(getTypeSize()); + + if constexpr (std::is_arithmetic_v) { + if (data) { + std::memcpy(result.data(), &data.value(), sizeof(T)); + } else { + T zero = 0; + std::memcpy(result.data(), &zero, sizeof(T)); + } + } else if constexpr (is_array_v) { + if (data) { + return getByteArrayFromStdArray(data.value()); + } else { + T zero = {}; + return getByteArrayFromStdArray(zero); + } + } else { + static_assert( + std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见XNDDSInterface.cpp:line 78"); + } + + return result; + } + + /** + * @brief 设置指定变量的字节数据,用于网络通信 + * @param data: 数据 + * @param byteArray: 字节数组 + */ + template + void setByteArray(XNDDSOptional &data, const XNByteArray &byteArray, + XN_UINT32 &pos) { + XN_UINT32 thisSize = getTypeSize(); + XNByteArray thisArray(thisSize); + if (pos + thisSize > byteArray.size()) { + return; + } + std::memcpy(thisArray.data(), byteArray.data() + pos, thisSize); + pos += thisSize; + + if constexpr (std::is_arithmetic_v) { + T temp; + std::memcpy(&temp, thisArray.data(), sizeof(T)); + data = temp; + } else if constexpr (is_array_v) { + if (!data) { + data = T{}; + } + setByteArrayFromStdArray(data.value(), thisArray); + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + + /** + * @brief 获取指定数组变量的字节数据,用于网络通信 + * @param data: 数据 + * @return 字节数组 + */ + template + XNByteArray getByteArrayFromStdArray(const std::array &data) { + XNByteArray result(getTypeSize() * N); + + for (XN_SIZE i = 0; i < N; ++i) { + if constexpr (std::is_arithmetic_v) { + std::memcpy(result.data() + i * getTypeSize(), &data[i], + getTypeSize()); + } else if constexpr (is_array_v) { + XNByteArray subArray = getByteArrayFromStdArray(data[i]); + std::memcpy(result.data() + i * getTypeSize(), subArray.data(), + getTypeSize()); + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + + return result; + } + + /** + * @brief 设置指定数组变量的字节数据,用于网络通信 + * @param data: 数据 + * @param byteArray: 字节数组 + */ + template + void setByteArrayFromStdArray(std::array &data, + const XNByteArray &byteArray) { + if (byteArray.size() < getTypeSize() * N) + return; + + for (XN_SIZE i = 0; i < N; ++i) { + if constexpr (std::is_arithmetic_v) { + std::memcpy(&data[i], byteArray.data() + i * getTypeSize(), + getTypeSize()); + } else if constexpr (is_array_v) { + XNByteArray subArray(byteArray.data() + i * getTypeSize(), + getTypeSize()); + setByteArrayFromStdArray(data[i], subArray); + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + } + + /** + * @brief 获取指定变量的字符串数据,用于JSON前端 + * @param data: 数据 + * @return: 数据(字符串格式) + */ + template std::string getString(const XNDDSOptional &data) { + if constexpr (std::is_arithmetic_v) { + if (data) { + return std::to_string(data.value()); + } else { + return "Unknown"; + } + } else if constexpr (is_array_v) { + if (data) { + return getStringFromStdArray(data.value()); + } else { + T zero = {}; + return getStringFromStdArray(zero); + } + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + return std::string(); + } + + /** + * @brief 通过字符串数据设置指定变量,用于JSON前端 + * @param data: 数据 + * @param value: 字符串数据 + */ + template + void setDataFromString(XNDDSOptional &data, const std::string &value) { + if constexpr (std::is_arithmetic_v) { + if constexpr (std::is_same_v || std::is_same_v) { + data = std::stod(value); + } else { + data = std::stoll(value); + } + } else if constexpr (is_array_v) { + // 解析输入字符串 + std::stringstream ss(value); + std::string item; + std::vector items; + while (std::getline(ss, item, ',')) { + items.push_back(item); + } + T temp; + setStdArrayFromString(temp, items, 0); + data = temp; + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + + /** + * @brief 获取指定数组变量的字符串数据,用于JSON前端 + * @param data: 数据 + * @return: 数据(字符串格式) + */ + template + std::string getStringFromStdArray(const std::array &data) { + std::stringstream ss; + for (XN_SIZE i = 0; i < N; ++i) { + if (i > 0) + ss << ","; + if constexpr (std::is_arithmetic_v) { + ss << data[i]; + } else if constexpr (is_array_v) { + ss << getStringFromStdArray(data[i]); + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + return ss.str(); + } + + /** + * @brief 通过字符串数据设置指定数组变量,用于JSON前端 + * @param data: 数据 + * @param value: 字符串数据,格式为"数字,数字,..." + * @param start_pos: 当前数组在输入字符串中的起始位置 + * @return 处理完当前数组后,下一个数组的起始位置 + * @throw std::runtime_error: 当输入数据格式不正确时抛出异常 + */ + template + size_t setStdArrayFromString(std::array &data, + const std::vector &value, + size_t start_pos = 0) { + // 递归处理每个元素 + for (XN_SIZE i = 0; i < N; ++i) { + try { + if constexpr (std::is_arithmetic_v) { + // 对于基本类型,直接转换 + if constexpr (std::is_same_v || std::is_same_v) { + data[i] = static_cast(std::stod(value[start_pos + i])); + } else { + data[i] = static_cast(std::stoll(value[start_pos + i])); + } + } else if constexpr (is_array_v) { + // 对于嵌套数组,递归处理 + start_pos = setStdArrayFromString(data[i], value, start_pos); + } else { + static_assert( + std::is_arithmetic_v || is_array_v, + "T 必须是算术类型或std::array类型,详见XNDDSInterface.cpp:line " + "275"); + } + } catch (const std::exception &e) { + throw std::runtime_error("无法解析第 " + std::to_string(i) + + " 个元素: " + e.what()); + } + } + return start_pos + N; + } + + template + void assign_value_get(const XNDDSOptional &data, T2 &model_data) { + if (data) { + auto temp = data.value(); + if constexpr (std::is_arithmetic_v) { + static_assert(std::is_arithmetic_v, + "模板参数T2必须是算术类型,详见" + XN_STRING(__FILE__) + + ":" + XN_STRING(__LINE__)); + static_assert(std::is_convertible_v, + "模板参数T1必须可以转换为T2类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + model_data = temp; + } else if constexpr (is_array_v) { + XN_SIZE arraySize = array_size_v; + for (XN_SIZE i = 0; i < arraySize; ++i) { + auto temp2 = temp[i]; + using array_type = typename T1::value_type; + if constexpr (std::is_arithmetic_v) { + model_data[i] = temp2; + } else if constexpr (is_array_v) { + XN_SIZE arraySize2 = array_size_v; + using sub_array_type = typename array_type::value_type; + if constexpr (std::is_arithmetic_v) { + for (XN_SIZE j = 0; j < arraySize2; ++j) { + model_data[i][j] = temp2[j]; + } + } else { + static_assert(std::is_arithmetic_v, + "模板参数T1是std::" + "array类型时,它的数组嵌套不能超过两层,详见" + + XN_STRING(__FILE__) + ":" + + XN_STRING(__LINE__)); + } + } else { + static_assert(std::is_arithmetic_v || + is_array_v, + "模板参数T1是std::array类型时,它的value_" + "type必须是算术类型或std::" + "array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "模板参数T1必须是算术类型或std::" + "array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + } + + template + void assign_value_set(XNDDSOptional &data, const T2 &model_data) { + if constexpr (std::is_arithmetic_v) { + static_assert(std::is_arithmetic_v, "模板参数T2必须是算术类型,详见" + + XN_STRING(__FILE__) + ":" + + XN_STRING(__LINE__)); + static_assert(std::is_convertible_v, + "模板参数T2必须可以转换为T1类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + data = model_data; + } else if constexpr (is_array_v) { + T1 temp; + XN_SIZE arraySize = array_size_v; + using array_type = typename T1::value_type; + for (XN_SIZE i = 0; i < arraySize; ++i) { + if constexpr (std::is_arithmetic_v) { + temp[i] = model_data[i]; + } else if constexpr (is_array_v) { + XN_SIZE arraySize2 = array_size_v; + using sub_array_type = typename array_type::value_type; + if constexpr (std::is_arithmetic_v) { + for (XN_SIZE j = 0; j < arraySize2; ++j) { + temp[i][j] = model_data[i][j]; + } + } else { + static_assert(std::is_arithmetic_v, + "模板参数T1是std::" + "array类型时,它的数组嵌套不能超过两层,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } else { + static_assert(std::is_arithmetic_v || + is_array_v, + "模板参数T1是std::array类型时,它的value_" + "type必须是算术类型或std::" + "array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + data = temp; + } else { + static_assert(std::is_arithmetic_v || is_array_v, + "模板参数T1必须是算术类型或std::" + "array类型,详见" + + XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__)); + } + } + + virtual void clearOutData() {} + virtual void sendOutData() {} + +protected: + XNGetDataFunctionMap getDataFunction; + XNSetDataFunctionMap setDataFunction; + XNGetByteArrayFunctionMap getByteArrayFunction; + XNSetByteArrayFunctionMap setByteArrayFunction; + XN_MUTEX dataMutex; + XN_MUTEX outDataMutex; + XN_UINT8 header[8]{0}; // 固定大小的头部 + XN_SIZE headerSize = 8; + XNDDSDataWriterPtr dataWriter; +}; +} // namespace XNSim + +#define MAP_DATA_FUNC(NAME) \ + getDataFunction[#NAME] = [this]() { return getString(data.NAME()); }; \ + setDataFunction[#NAME] = [this](const XN_STRING &value) { \ + setDataFromString(out_data.NAME(), value); \ + }; \ + getByteArrayFunction.push_back( \ + [this]() { return getByteArray(data.NAME()); }); \ + setByteArrayFunction.push_back( \ + [this](const XNByteArray &byteArray, XN_UINT32 &pos) { \ + setByteArray(out_data.NAME(), byteArray, pos); \ + }); diff --git a/XNCore_Win/XNDDSManager/CMakeLists.txt b/XNCore_Win/XNDDSManager/CMakeLists.txt new file mode 100644 index 0000000..9bfa20c --- /dev/null +++ b/XNCore_Win/XNDDSManager/CMakeLists.txt @@ -0,0 +1,6 @@ +set(XNDDSMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNDDSManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNDDSManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNDDSMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNDDSManager/XNDDSManager.cpp b/XNCore_Win/XNDDSManager/XNDDSManager.cpp new file mode 100644 index 0000000..87fc4f7 --- /dev/null +++ b/XNCore_Win/XNDDSManager/XNDDSManager.cpp @@ -0,0 +1,40 @@ +#include "XNDDSManager.h" + +namespace XNSim { +XNDDSManager::XNDDSManager() : XNBaseFrameObject(new XNDDSManagerPrivate()) { + SetUniqueId(enumValue(XNCoreObjectID::DDSManager)); + SetObjectName("XNDDSManager"); +} + +XNDDSManager::~XNDDSManager() {} + +XNDDSManager::XNDDSManager(PrivateType *p) : XNBaseFrameObject(p) {} + +XN_BOOL XNDDSManager::Initialize() { + T_D(); + d->_status = XNFrameObjectStatus::Initialized; + d->participant_ = nullptr; + d->topics_.clear(); + LOG_INFO("DDS管理器初始化成功!"); + return true; +} + +XN_BOOL XNDDSManager::PrepareForExecute() { + T_D(); + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("DDS管理器准备就绪!"); + return true; +} + +void XNDDSManager::SetDomainID(XN_UINT32 domainID) { + T_D(); + XNDDSParticipantQos participantQos; + participantQos.name("XNDDSManager"); + d->participant_ = + XN_DDS::DomainParticipantFactory::get_instance()->create_participant( + domainID, participantQos); + if (d->participant_ == nullptr) { + LOG_ERROR("0x2130 DDS管理器创建域参与者失败!"); + } +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNDDSManager/XNDDSManager.h b/XNCore_Win/XNDDSManager/XNDDSManager.h new file mode 100644 index 0000000..a2b5283 --- /dev/null +++ b/XNCore_Win/XNDDSManager/XNDDSManager.h @@ -0,0 +1,126 @@ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject.h" +#include "XNBaseFrameObject/XNBaseFrameObject_p.h" + +namespace XNSim { +struct XNDDSManagerPrivate : public XNBaseFrameObjectPrivate { + XNDDSParticipantPtr participant_; + XNDDSTopicMap topics_; + std::mutex mutex_; +}; + +class XNDDSManager : public XNBaseFrameObject { + XN_METATYPE(XNDDSManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNDDSManager) +public: + XNDDSManager(); + ~XNDDSManager(); + +protected: + XNDDSManager(PrivateType *p); + +public: + virtual XN_BOOL Initialize() override; + + virtual XN_BOOL PrepareForExecute() override; + + void SetDomainID(XN_UINT32 domainID); + +public: + template + XNDDSDataWriterPtr RegisterPublisher(const XN_STRING &topicName, + XN_UINT32 publisherID) { + T_D(); + std::lock_guard lock(d->mutex_); + if (d->topics_.find(topicName) == d->topics_.end()) { + d->topics_[topicName] = TopicInfo(); + TopicInfo &tmp = d->topics_[topicName]; + XNDDSTypeSupport typeSupport(new T()); + typeSupport.register_type(d->participant_); + tmp.topic = d->participant_->create_topic( + topicName, typeSupport.get_type_name(), XN_DDS::TOPIC_QOS_DEFAULT); + if (tmp.topic == nullptr) { + LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName); + d->topics_.erase(topicName); + return nullptr; + } + } + TopicInfo &tmp = d->topics_[topicName]; + tmp.publishers_[publisherID] = PublisherInfo(); + tmp.publishers_[publisherID].publisher = d->participant_->create_publisher( + XN_DDS::PUBLISHER_QOS_DEFAULT, nullptr); + if (tmp.publishers_[publisherID].publisher == nullptr) { + LOG_ERROR("0x2131 Create Publisher %1 for Topic %2 Failed!", publisherID, + topicName); + return nullptr; + } + + // 设置数据写入器QoS策略 + XNDDSDataWriterQos dataWriterQos; + // 设置数据写入器的历史记录策略, 只保留最新的一个数据 + // dataWriterQos.history().kind = FAST_DDS_MACRO::KEEP_LAST_HISTORY_QOS; + // dataWriterQos.history().depth = 1; + // 设置数据写入器的可靠性策略, 使用最佳努力可靠性 + // dataWriterQos.reliability().kind = + // FAST_DDS_MACRO::BEST_EFFORT_RELIABILITY_QOS; 设置数据写入器的持久性策略, + // 使用瞬态本地持久性 + dataWriterQos.durability().kind = XN_DDS::VOLATILE_DURABILITY_QOS; + // 设置数据写入器的生命周期策略, 设置为5秒 + dataWriterQos.lifespan().duration = XN_DDS::Duration_t(5, 0); + + tmp.publishers_[publisherID].dataWriter = + tmp.publishers_[publisherID].publisher->create_datawriter( + tmp.topic, dataWriterQos, nullptr); + if (tmp.publishers_[publisherID].dataWriter == nullptr) { + LOG_ERROR("0x2132 Create DataWriter %1 for Topic %2 Failed!", publisherID, + topicName); + return nullptr; + } + LOG_INFO("0x2133 Create Publisher %1 for Topic %2 Success!", publisherID, + topicName); + return tmp.publishers_[publisherID].dataWriter; + } + + template + void RegisterSubscriber(const XN_STRING &topicName, XN_UINT32 subscriberID, + XNDDSCallBack fun) { + T_D(); + std::lock_guard lock(d->mutex_); + if (d->topics_.find(topicName) == d->topics_.end()) { + d->topics_[topicName] = TopicInfo(); + TopicInfo &tmp = d->topics_[topicName]; + XNDDSTypeSupport typeSupport(new T()); + typeSupport.register_type(d->participant_); + tmp.topic = d->participant_->create_topic( + topicName, typeSupport.get_type_name(), XN_DDS::TOPIC_QOS_DEFAULT); + if (tmp.topic == nullptr) { + LOG_ERROR("0x2130 Create Topic %1 Failed!", topicName); + d->topics_.erase(topicName); + return; + } + } + TopicInfo &tmp = d->topics_[topicName]; + tmp.subscribers_[subscriberID] = SubscriberInfo(); + tmp.subscribers_[subscriberID].subscriber = + d->participant_->create_subscriber(XN_DDS::SUBSCRIBER_QOS_DEFAULT, + nullptr); + if (tmp.subscribers_[subscriberID].subscriber == nullptr) { + LOG_ERROR("0x2135 Create Subscriber %1 for Topic %2 Failed!", + subscriberID, topicName); + } + XN_DDS::DataReaderQos dataReaderQos; + dataReaderQos.durability().kind = XN_DDS::VOLATILE_DURABILITY_QOS; + XN_DDS::DataReaderListener *listener = + new DataReaderListenerImpl(fun); + tmp.subscribers_[subscriberID].dataReader = + tmp.subscribers_[subscriberID].subscriber->create_datareader( + tmp.topic, dataReaderQos, listener); + if (tmp.subscribers_[subscriberID].dataReader == nullptr) { + LOG_ERROR("0x2136 Create DataReader %1 for Topic %2 Failed!", + subscriberID, topicName); + } + LOG_INFO("0x2137 Create Subscriber %1 for Topic %2 Success!", subscriberID, + topicName); + } +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNEventManager/CMakeLists.txt b/XNCore_Win/XNEventManager/CMakeLists.txt new file mode 100644 index 0000000..e2a2015 --- /dev/null +++ b/XNCore_Win/XNEventManager/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNEVENTMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNEventManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNEventManager_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNEventManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNEVENTMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNEventManager/XNEventManager.cpp b/XNCore_Win/XNEventManager/XNEventManager.cpp new file mode 100644 index 0000000..3ff07d4 --- /dev/null +++ b/XNCore_Win/XNEventManager/XNEventManager.cpp @@ -0,0 +1,296 @@ +#include "XNEventManager.h" +#include "XNEventManager_p.h" +#include "XNFramework.h" +#include +#include + + +// 构造函数 +XNEventManager::XNEventManager() + : XNBaseFrameObject(new XNEventManagerPrivate()) { + // 设置唯一标识符 + SetUniqueId(enumValue(XNCoreObjectID::EventManager)); + // 设置对象名称 + 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(PrivateType *p) : XNBaseFrameObject(p) {} + +// 修改注册事件处理器的实现 +int XNEventManager::RegisterEventHandler(const std::string &eventName, + XNEventCallback callback, + uint32_t objectId, bool async, + XNEvent::Priority priority) { + T_D(); + if (eventName.empty() || !callback) { + LOG_WARNING("Invalid event name or callback!"); + return -1; + } + + std::lock_guard locker(d->eventMutex); + + // 生成新的本地ID + d->localIdCounter = (d->localIdCounter + 1) & 0xFFFF; + if (d->localIdCounter == 0) + d->localIdCounter = 1; // 避免为0 + + // 创建处理器信息 + EventHandlerInfo handlerInfo; + handlerInfo.callback = callback; + handlerInfo.objectId = objectId; + handlerInfo.localId = d->localIdCounter; + handlerInfo.isAsync = async; + handlerInfo.priority = priority; + // 计算全局处理器ID + int handlerId = handlerInfo.GetHandlerId(); + + // 添加处理器信息到事件列表 + d->eventHandlers[eventName].push_back(handlerInfo); + // 添加反向映射 + d->handlerToEvent[handlerId] = eventName; + + 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 std::string &eventName, + int handlerId) { + T_D(); + std::lock_guard locker(d->eventMutex); + + // 如果指定了事件名称,先验证事件是否存在 + if (!eventName.empty()) { + auto it = d->eventHandlers.find(eventName); + if (it == d->eventHandlers.end()) { + LOG_WARNING("Event " + eventName + " not found!"); + return false; + } + + // 查找并移除指定的处理器 + 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.empty()) { + d->eventHandlers.erase(it); + } + return true; + } + 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()) { + std::string eventToRemove = eventIt->second; + auto &handlers = d->eventHandlers[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.empty()) { + d->eventHandlers.erase(eventToRemove); + } + return true; + } + } + + LOG_WARNING("Handler ID " + std::to_string(handlerId) + " not found!"); + return false; +} + +// 修改触发事件的实现 +void XNEventManager::TriggerEvent(const std::string &eventName, + const std::any &eventData, bool forceAsync, + XNEvent::Priority priority) { + T_D(); + std::list handlers; + { + std::lock_guard locker(d->eventMutex); + auto it = d->eventHandlers.find(eventName); + if (it == d->eventHandlers.end()) { + return; + } + handlers = it->second; + } + + for (const auto &handler : handlers) { + if (forceAsync || handler.isAsync) { + if (priority == XNEvent::Priority::RealTime) { + // 创建实时任务 + RTEventTask *task = + new RTEventTask(eventName, eventData, handler.callback, this); + d->rtManager.addTask(task); + } else { + // 普通异步任务使用线程池 + std::lock_guard lock(d->taskMutex); + d->taskQueue.push( + new AsyncEventTask(eventName, eventData, handler.callback, this)); + d->taskCond.notify_one(); + } + } else { + // 同步执行 + try { + handler.callback(eventData); + EventProcessed(eventName, true); + } catch (const std::exception &e) { + LOG_ERROR("Exception in handler " + + std::to_string(handler.GetHandlerId()) + " for event " + + eventName + ": " + e.what()); + EventProcessed(eventName, false); + } + } + } +} + +void XNEventManager::SetMaxThreadCount(int count) { + T_D(); + std::lock_guard lock(d->taskMutex); + // 停止现有线程 + d->running = false; + d->taskCond.notify_all(); + for (auto &thread : d->workerThreads) { + if (thread.joinable()) { + thread.join(); + } + } + d->workerThreads.clear(); + + // 创建新线程 + d->running = true; + for (int i = 0; i < count; ++i) { + d->workerThreads.emplace_back([this, d]() { + while (d->running) { + BaseEventTask *task = nullptr; + { + std::unique_lock lock(d->taskMutex); + d->taskCond.wait( + lock, [this, d] { return !d->taskQueue.empty() || !d->running; }); + if (!d->running) { + break; + } + task = d->taskQueue.front(); + d->taskQueue.pop(); + } + if (task) { + task->execute(); + delete task; + } + } + }); + } + LOG_INFO("Set thread pool max thread count to " + std::to_string(count)); +} + +int XNEventManager::GetMaxThreadCount() const { + T_D(); + std::lock_guard lock(d->taskMutex); + return d->workerThreads.size(); +} + +void XNEventManager::WaitForAsyncEvents() { + T_D(); + std::unique_lock lock(d->taskMutex); + d->taskCond.wait(lock, [this, d] { return d->taskQueue.empty(); }); + LOG_INFO("All async events have been processed"); +} + +// 初始化事件管理器 +bool XNEventManager::Initialize() { + T_D(); + // 配置普通线程池 + SetMaxThreadCount(std::thread::hardware_concurrency()); + + // 配置实时线程池 + SetRTThreadPoolConfig(2, // 最大线程数 + sched_get_priority_min(SCHED_FIFO), // 最小优先级 + sched_get_priority_max(SCHED_FIFO)); // 最大优先级 + + LOG_INFO("XNEventManager Initialize Success!"); + d->_status = XNFrameObjectStatus::Initialized; + return true; +} + +// 准备执行 +bool XNEventManager::PrepareForExecute() { + T_D(); + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("XNEventManager is prepared!"); + return true; +} + +void XNEventManager::SetRTThreadPoolConfig(int maxThreads, int minPriority, + int maxPriority) { + T_D(); + d->rtManager.stop(); + + XNFrameworkPtr framework = GetFramework(); + if (!framework) { + LOG_WARNING("XNFramework is nullptr!"); + return; + } + + uint32_t cpuAffinity = framework->GetCpuAffinity(); + + // 找到最后一个可用的CPU + int lastCpu = -1; + for (int i = 0; i < 32; i++) { // 假设最多32个CPU + if (cpuAffinity & (1u << i)) { + lastCpu = i; + } + } + + if (lastCpu < 0) { + LOG_WARNING("No available CPU found in affinity mask, using default CPU 1"); + lastCpu = 1; + } else { + LOG_INFO("RT thread bound to CPU " + std::to_string(lastCpu)); + } + + d->rtManager.start(maxThreads, maxPriority, lastCpu); +} + +void XNEventManager::EventProcessed(const std::string &eventName, + bool success) { + T_D(); + // 这里可以添加事件处理完成的回调逻辑 + // LOG_INFO("Event " + eventName + " processed " + (success ? "successfully" : + // "with error")); +} diff --git a/XNCore_Win/XNEventManager/XNEventManager.h b/XNCore_Win/XNEventManager/XNEventManager.h new file mode 100644 index 0000000..0a49468 --- /dev/null +++ b/XNCore_Win/XNEventManager/XNEventManager.h @@ -0,0 +1,80 @@ +#pragma once +#include + +namespace XNSim { +// 事件优先级定义 +namespace XNEvent { +enum class Priority { + RealTime = 0, // 实时优先级 + High = 1, // 高优先级 + Normal = 2, // 普通优先级 + Low = 3 // 低优先级 +}; +} + +// 前向声明私有类 +struct XNEventManagerPrivate; + +// 事件管理器类,继承自XNBaseFrameObject +class XNEventManager : public XNBaseFrameObject { + XN_METATYPE(XNEventManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNEventManager) +public: + // 构造函数,创建事件管理器实例 + XNEventManager(); + // 析构函数 + ~XNEventManager(); + + // 注册事件处理器 + // @param eventName: 事件名称 + // @param callback: 事件处理回调函数 + // @param objectId: 对象ID + // @param async: 是否异步处理该事件 + // @param priority: 事件优先级 + // @return: 返回处理器ID,失败返回-1 + XN_INT32 + RegisterEventHandler(const XN_STRING &eventName, XNEventCallback callback, + XN_UINT32 objectId, XN_BOOL async = false, + XNEvent::Priority priority = XNEvent::Priority::Normal); + // 移除事件处理器 + // @param eventName: 事件名称 + // @param handlerId: 处理器ID + // @return: 移除是否成功 + XN_BOOL RemoveEventHandler(const XN_STRING &eventName, XN_INT32 handlerId); + // 触发指定事件 + // @param eventName: 要触发的事件名称 + // @param eventData: 事件携带的数据 + // @param forceAsync: 强制异步处理 + // @param priority: 事件优先级 + void TriggerEvent(const XN_STRING &eventName, + const XN_ANY &eventData = XN_ANY(), + XN_BOOL forceAsync = false, + XNEvent::Priority priority = XNEvent::Priority::Normal); + + // 设置线程池最大线程数 + void SetMaxThreadCount(XN_UINT32 count); + + // 获取线程池最大线程数 + XN_UINT32 GetMaxThreadCount() const; + + // 等待所有异步事件处理完成 + void WaitForAsyncEvents(); + + // 设置实时线程池参数 + void SetRTThreadPoolConfig(XN_UINT32 maxThreads, XN_UINT32 minPriority, + XN_UINT32 maxPriority); + + // 事件处理完成回调 + void EventProcessed(const XN_STRING &eventName, XN_BOOL success); + +protected: + // 保护构造函数,用于继承实现 + XNEventManager(PrivateType *p); + +public: + // 初始化事件管理器 + virtual XN_BOOL Initialize() override; + // 准备执行 + virtual XN_BOOL PrepareForExecute() override; +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNEventManager/XNEventManager_p.h b/XNCore_Win/XNEventManager/XNEventManager_p.h new file mode 100644 index 0000000..a381b4b --- /dev/null +++ b/XNCore_Win/XNEventManager/XNEventManager_p.h @@ -0,0 +1,242 @@ +#pragma once +#include "XNBaseFrameObject_p.h" +#include "XNEventManager.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 事件处理器信息结构 +struct EventHandlerInfo { + std::function callback; // 回调函数 + uint32_t objectId; // 对象ID + uint32_t localId; // 本地ID + bool isAsync; // 是否异步处理 + XNEvent::Priority priority; // 事件优先级 + uint32_t threadPriority; // 线程优先级 + + // 获取全局处理器ID + uint32_t GetHandlerId() const { return (objectId << 16) | (localId & 0xFFFF); } + + // 从全局处理器ID中提取对象ID + static uint32_t GetObjectId(uint32_t handlerId) { return handlerId >> 16; } + + // 从全局处理器ID中提取本地ID + static uint32_t GetLocalId(uint32_t handlerId) { return handlerId & 0xFFFF; } +}; + +// 事件任务基类 +class BaseEventTask +{ +public: + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + BaseEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) + : eventName(name), eventData(data), eventCallback(callback), eventManager(manager) + { + } + virtual ~BaseEventTask() = default; + + /** + * @brief 执行任务 + */ + virtual void execute() = 0; + +protected: + std::string eventName; + std::any eventData; + std::function eventCallback; + XNEventManager *eventManager; +}; + +// 异步事件任务 +class AsyncEventTask : public BaseEventTask +{ +public: + /** + * @brief 构造函数 + * @param name 事件名称 + * @param data 事件数据 + * @param callback 回调函数 + * @param manager 事件管理器指针 + */ + AsyncEventTask(const std::string &name, const std::any &data, + std::function callback, XNEventManager *manager) + : BaseEventTask(name, data, callback, manager) + { + } + + /** + * @brief 执行任务 + */ + void execute() override + { + try { + eventCallback(eventData); + if (eventManager) { + eventManager->EventProcessed(eventName, true); + } + } catch (const std::exception &e) { + LOG_ERROR("Async event handler exception for " + eventName + ": " + e.what()); + if (eventManager) { + 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 callback, XNEventManager *manager) + : BaseEventTask(name, data, callback, manager) + { + } + + /** + * @brief 执行任务 + */ + void execute() override + { + try { + eventCallback(eventData); + if (eventManager) { + eventManager->EventProcessed(eventName, true); + } + } catch (const std::exception &e) { + LOG_ERROR("RT event handler exception for " + eventName + ": " + e.what()); + if (eventManager) { + eventManager->EventProcessed(eventName, false); + } + } + } +}; + +// 实时线程管理器 +class RTThreadManager +{ +public: + RTThreadManager() : running(false) {} + ~RTThreadManager() { stop(); } + + void start(int threadCount, int priority, int cpuCore) + { + running = true; + for (int i = 0; i < threadCount; ++i) { + pthread_t thread; + pthread_create(&thread, nullptr, threadFunction, this); + + // 设置线程优先级 + struct sched_param param; + param.sched_priority = priority; + pthread_setschedparam(thread, SCHED_FIFO, ¶m); + + // 设置CPU亲和性 + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(cpuCore, &cpuset); + pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset); + + threads.push_back(thread); + } + } + + void stop() + { + running = false; + taskCond.notify_all(); + for (auto thread : threads) { + pthread_join(thread, nullptr); + } + threads.clear(); + } + + void addTask(RTEventTask *task) + { + std::lock_guard lock(taskMutex); + taskQueue.push(task); + taskCond.notify_one(); + } + +private: + static void *threadFunction(void *arg) + { + auto manager = static_cast(arg); + manager->processTask(); + return nullptr; + } + + void processTask() + { + while (running) { + RTEventTask *task = nullptr; + { + std::unique_lock lock(taskMutex); + taskCond.wait(lock, [this] { return !taskQueue.empty() || !running; }); + if (!running) + break; + task = taskQueue.front(); + taskQueue.pop(); + } + if (task) { + task->execute(); + delete task; + } + } + } + + bool running; + std::vector threads; + std::queue taskQueue; + std::mutex taskMutex; + std::condition_variable taskCond; +}; + +// 事件管理器的私有实现类 +struct XNEventManagerPrivate : public XNBaseFrameObjectPrivate { + // 存储事件及其对应的处理器信息列表 + // key: 事件名称 + // value: 该事件对应的所有处理器信息列表 + std::map> eventHandlers; + + // 处理器ID到事件名称的反向映射,用于快速查找 + std::map handlerToEvent; + + // 本地ID计数器 + int localIdCounter = 0; + + // 互斥锁,用于保护事件处理器表的线程安全访问 + std::mutex eventMutex; + + // 线程池相关 + std::vector workerThreads; + std::queue taskQueue; + std::mutex taskMutex; + std::condition_variable taskCond; + bool running = true; + + RTThreadManager rtManager; +}; diff --git a/XNCore_Win/XNFramework/CMakeLists.txt b/XNCore_Win/XNFramework/CMakeLists.txt new file mode 100644 index 0000000..e61a07e --- /dev/null +++ b/XNCore_Win/XNFramework/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNFRAMEWORK_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNFramework.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNFramework_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNFramework.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNFRAMEWORK_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNFramework/XNFramework.cpp b/XNCore_Win/XNFramework/XNFramework.cpp new file mode 100644 index 0000000..5b4a633 --- /dev/null +++ b/XNCore_Win/XNFramework/XNFramework.cpp @@ -0,0 +1,213 @@ +#include "XNFramework.h" +#include "XNFramework_p.h" + +#include "XNConfigManager/XNConfigManager.h" +#include "XNDDSManager/XNDDSManager.h" +#include "XNEventManager/XNEventManager.h" +#include "XNModelManager/XNModelManager.h" +#include "XNServiceManager/XNServiceManager.h" +#include "XNThreadManager/XNThreadManager.h" +#include "XNTimeManager/XNTimeManager.h" + +namespace XNSim { +XNFramework::XNFramework() : XNObject(new XNFrameworkPrivate()) { + SetObjectName("XNFramework"); + SetUniqueId(1); + T_D(); + d->timeManager = std::make_shared(); + d->threadManager = std::make_shared(); + d->configManager = std::make_shared(); + d->ddsManager = std::make_shared(); + d->modelManager = std::make_shared(); + d->serviceManager = std::make_shared(); + d->eventManager = std::make_shared(); +} + +XNFramework::XNFramework(PrivateType *p) : XNObject(p) {} + +XNFramework::~XNFramework() {} + +XN_STRING XNFramework::GetWorkPath() { + T_D(); + return d->workPath; +} + +void XNFramework::SetWorkPath(const XN_STRING &workPath) { + T_D(); + d->workPath = workPath; +} + +XN_STRING XNFramework::GetModelPath() { + T_D(); + return d->modelPath; +} + +void XNFramework::SetModelPath(const XN_STRING &modelPath) { + T_D(); + d->modelPath = modelPath; +} + +XN_STRING XNFramework::GetServicePath() { + T_D(); + return d->servicePath; +} + +void XNFramework::SetServicePath(const XN_STRING &servicePath) { + T_D(); + d->servicePath = servicePath; +} + +XN_UINT32 XNFramework::GetCpuAffinity() { + T_D(); + return d->uCpuAffinity; +} + +void XNFramework::SetCpuAffinity(XN_UINT32 cpuAffinity) { + T_D(); + d->uCpuAffinity = cpuAffinity; +} + +XN_BOOL XNFramework::Initialize(XN_UINT32 initialType) { + T_D(); + LOG_INFO("D01054001:主框架正在初始化..."); + d->ddsManager->SetFramework(XN_THISPTR); + d->timeManager->SetFramework(XN_THISPTR); + d->threadManager->SetFramework(XN_THISPTR); + d->configManager->SetFramework(XN_THISPTR); + d->modelManager->SetFramework(XN_THISPTR); + d->serviceManager->SetFramework(XN_THISPTR); + d->eventManager->SetFramework(XN_THISPTR); + XN_BOOL ret = d->eventManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052001:主框架初始化失败!"); + return false; + } + ret = d->timeManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052002:主框架初始化失败!"); + return false; + } + ret = d->ddsManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052003:主框架初始化失败!"); + return false; + } + ret = d->serviceManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052004:主框架初始化失败!"); + return false; + } + ret = d->threadManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052005:主框架初始化失败!"); + return false; + } + ret = d->modelManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052006:主框架初始化失败!"); + return false; + } + ret = d->configManager->Initialize(); + if (!ret) { + LOG_ERROR("B01052007:主框架初始化失败!"); + return false; + } + LOG_INFO("D01054002:主框架初始化成功!"); + LOG_INFO("D01054003:开始解析构型文件 ..."); + ret = d->configManager->AnalysisScenarioXml(d->scenarioXml, initialType); + if (!ret) { + LOG_ERROR("B01052008:主框架解析构型文件失败!"); + return false; + } + LOG_INFO("D01054004:解析构型文件成功!"); + return true; +} + +XN_BOOL XNFramework::PrepareForExecute() { + T_D(); + + XN_BOOL ret = d->eventManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + ret = d->timeManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + ret = d->ddsManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + ret = d->serviceManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + ret = d->threadManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + ret = d->modelManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + ret = d->configManager->PrepareForExecute(); + if (!ret) { + LOG_ERROR("XNFramework PrepareForExecute Failed!"); + return false; + } + LOG_INFO("XNCore is prepared for execute! Simulation will start soon..."); + return true; +} + +void XNFramework::SetScenarioXml(const XN_STRING &scenarioXml) { + T_D(); + d->scenarioXml = scenarioXml; +} + +void XNFramework::SimControl(XN_UINT32 objectId, SimControlCmd cmd) { + T_D(); + d->timeManager->SimControl(objectId, cmd); + d->threadManager->SimControl(objectId, cmd); +} + +XNTimeManagerPtr XNFramework::GetTimeManager() { + T_D(); + return d->timeManager; +} + +XNThreadManagerPtr XNFramework::GetThreadManager() { + T_D(); + return d->threadManager; +} + +XNConfigManagerPtr XNFramework::GetConfigManager() { + T_D(); + return d->configManager; +} + +XNDDSManagerPtr XNFramework::GetDDSManager() { + T_D(); + return d->ddsManager; +} + +XNEventManagerPtr XNFramework::GetEventManager() { + T_D(); + return d->eventManager; +} + +XNModelManagerPtr XNFramework::GetModelManager() { + T_D(); + return d->modelManager; +} + +XNServiceManagerPtr XNFramework::GetServiceManager() { + T_D(); + return d->serviceManager; +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNFramework/XNFramework.h b/XNCore_Win/XNFramework/XNFramework.h new file mode 100644 index 0000000..ca6f8ef --- /dev/null +++ b/XNCore_Win/XNFramework/XNFramework.h @@ -0,0 +1,169 @@ +/** + * @file XNFramework.h + * @author jinchao + * @brief 框架类 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ +#pragma once + +#include "XNObject/XNObject.h" + +namespace XNSim { +struct XNFrameworkPrivate; + +/** + * @brief 框架类 + */ +class XNCORE_EXPORT XNFramework : public XNObject { + /** + * @brief 宏定义,用于禁用拷贝构造函数 + */ + XN_METATYPE(XNFramework, XNObject) + + /** + * @brief 宏定义,用于声明私有数据成员 + */ + XN_DECLARE_PRIVATE(XNFramework) +public: + /** + * @brief 构造函数 + * @param parent 父对象 + */ + 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 构型管理器 + */ + XNConfigManagerPtr GetConfigManager(); + + /** + * @brief 获取服务管理器 + * @return 服务管理器 + */ + XNServiceManagerPtr GetServiceManager(); + + /** + * @brief 获取线程管理器 + * @return 线程管理器 + */ + XNThreadManagerPtr GetThreadManager(); + + /** + * @brief 获取时间管理器 + * @return 时间管理器 + */ + XNTimeManagerPtr GetTimeManager(); + + /** + * @brief 获取工作路径 + * @return 工作路径 + */ + XN_STRING GetWorkPath(); + + /** + * @brief 设置工作路径 + * @param workPath 工作路径 + */ + void SetWorkPath(const XN_STRING &workPath); + + /** + * @brief 获取模型库路径 + * @return 模型库路径 + */ + XN_STRING GetModelPath(); + + /** + * @brief 设置模型库路径 + * @param modelPath 模型库路径 + */ + void SetModelPath(const XN_STRING &modelPath); + + /** + * @brief 获取服务库路径 + * @return 服务库路径 + */ + XN_STRING GetServicePath(); + + /** + * @brief 设置服务库路径 + * @param servicePath 服务库路径 + */ + void SetServicePath(const XN_STRING &servicePath); + + /** + * @brief 获取CPU亲和性 + * @return CPU亲和性 + */ + XN_UINT32 GetCpuAffinity(); + + /** + * @brief 设置CPU亲和性 + * @param cpuAffinity CPU亲和性 + */ + void SetCpuAffinity(XN_UINT32 cpuAffinity); + + /** + * @brief 设置场景XML + * @param scenarioXml 场景XML + */ + void SetScenarioXml(const XN_STRING &scenarioXml); + + /** + * @brief 准备执行 + * @return true: 准备成功 + * @return false: 准备失败 + */ + bool PrepareForExecute(); + + /** + * @brief 仿真控制 + * @param objectId 对象ID + * @param cmd 命令 + */ + void SimControl(XN_UINT32 objectId, SimControlCmd cmd); + + /** + * @brief 初始化 + * @param initialType 初始化类型 + * @return true: 初始化成功 + * @return false: 初始化失败 + */ + XN_BOOL Initialize(XN_UINT32 initialType); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNFramework/XNFramework_p.h b/XNCore_Win/XNFramework/XNFramework_p.h new file mode 100644 index 0000000..1453e59 --- /dev/null +++ b/XNCore_Win/XNFramework/XNFramework_p.h @@ -0,0 +1,87 @@ +/** + * @file XNFramework_p.h + * @author jinchao + * @brief 框架类的私有数据成员 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ + +#pragma once + +#include "XNObject/XNObject_p.h" + +namespace XNSim { +/** + * @brief 框架类的私有数据成员 + */ +struct XNFrameworkPrivate : public XNObjectPrivate { + + /** + * @brief DDS管理器 + */ + XNDDSManagerPtr ddsManager; + + /** + * @brief 事件管理器 + */ + XNEventManagerPtr eventManager; + + /** + * @brief 模型管理器 + */ + XNModelManagerPtr modelManager; + + /** + * @brief 构型管理器 + */ + XNConfigManagerPtr configManager; + + /** + * @brief 服务管理器 + */ + XNServiceManagerPtr serviceManager; + + /** + * @brief 线程管理器 + */ + XNThreadManagerPtr threadManager; + + /** + * @brief 时间管理器 + */ + XNTimeManagerPtr timeManager; + + /** + * @brief 工作路径 + */ + XN_STRING workPath; + + /** + * @brief 模型路径 + */ + XN_STRING modelPath; + + /** + * @brief 服务路径 + */ + XN_STRING servicePath; + + /** + * @brief CPU亲和性 + */ + XN_UINT32 uCpuAffinity; + + /** + * @brief 场景XML + */ + XN_STRING scenarioXml; + + /** + * @brief 构型ID + */ + XN_UINT32 configId; +}; +} // namespace XNSim diff --git a/XNCore_Win/XNGlobalDefine/CMakeLists.txt b/XNCore_Win/XNGlobalDefine/CMakeLists.txt new file mode 100644 index 0000000..b5c728d --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/CMakeLists.txt @@ -0,0 +1,20 @@ +set(XNGLOBALDEFINE_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNByteArray.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNCore_global.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNDataBase.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNDDS.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNDefine.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNEnum.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNFile.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNJson.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNMemory.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNMeta.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNString.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNThread.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNTime.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNType.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNTypeTraits.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNXml.h +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNGLOBALDEFINE_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNByteArray.h b/XNCore_Win/XNGlobalDefine/XNByteArray.h new file mode 100644 index 0000000..e11e6c5 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNByteArray.h @@ -0,0 +1,100 @@ +#pragma once + +#include "XNCore_global.h" +#include "XNType.h" +#include + +namespace XNSim { +/** + * @brief 自定义字节数组容器类 + * @details 提供类似QByteArray的功能,用于处理二进制数据 + */ +class XNByteArray { +public: + XNByteArray() = default; + explicit XNByteArray(XN_SIZE size) : data_(size) {} + + /** + * @brief 从原始数据构造 + * @param buffer 原始数据缓冲区 + * @param size 数据大小 + */ + XNByteArray(const XN_UINT8 *buffer, XN_SIZE size) + : data_(buffer, buffer + size) {} + + /** + * @brief 获取数据指针 + * @return 数据指针 + */ + XN_UINT8 *data() { return data_.data(); } + + /** + * @brief 获取常量数据指针 + * @return 常量数据指针 + */ + const XN_UINT8 *data() const { return data_.data(); } + + /** + * @brief 获取数据大小 + * @return 数据大小 + */ + XN_SIZE size() const { return data_.size(); } + + /** + * @brief 调整大小 + * @param size 新大小 + */ + void resize(XN_SIZE size) { data_.resize(size); } + + /** + * @brief 清空数据 + */ + void clear() { data_.clear(); } + + /** + * @brief 追加数据 + * @param buffer 要追加的数据 + * @param size 数据大小 + */ + void append(const XN_UINT8 *buffer, XN_SIZE size) { + XN_SIZE oldSize = data_.size(); + data_.resize(oldSize + size); + std::memcpy(data_.data() + oldSize, buffer, size); + } + + /** + * @brief 追加另一个XNByteArray + * @param other 要追加的XNByteArray + */ + void append(const XNByteArray &other) { append(other.data(), other.size()); } + + /** + * @brief 获取指定位置的字节 + * @param index 索引 + * @return 字节值 + */ + XN_UINT8 &operator[](XN_SIZE index) { return data_[index]; } + + /** + * @brief 获取指定位置的字节(常量版本) + * @param index 索引 + * @return 字节值 + */ + const XN_UINT8 &operator[](XN_SIZE index) const { return data_[index]; } + + /** + * @brief 检查是否为空 + * @return 是否为空 + */ + XN_BOOL isEmpty() const { return data_.empty(); } + + /** + * @brief 预分配空间 + * @param size 要预分配的大小 + */ + void reserve(XN_SIZE size) { data_.reserve(size); } + +private: + std::vector data_; +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNCore_global.h b/XNCore_Win/XNGlobalDefine/XNCore_global.h new file mode 100644 index 0000000..50def5d --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNCore_global.h @@ -0,0 +1,42 @@ +#pragma once + +// 导出宏定义 +#if defined(_WIN32) +#if defined(XNCORE_LIBRARY) +#define XNCORE_EXPORT __declspec(dllexport) +#else +#define XNCORE_EXPORT __declspec(dllimport) +#endif +#elif defined(__linux__) +#if defined(XNCORE_LIBRARY) +#define XNCORE_EXPORT __attribute__((visibility("default"))) +#else +#define XNCORE_EXPORT __attribute__((visibility("default"))) +#endif +#endif + +// 内联宏定义 +#if defined(_WIN32) +#define FORCEINLINE __forceinline +#else +#define FORCEINLINE __attribute__((always_inline)) +#endif + +// 平台相关头文件 +#if defined(_WIN32) +#define XN_WINDOWS +#include +#include +#include +#elif defined(__linux__) +#define XN_LINUX +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif diff --git a/XNCore_Win/XNGlobalDefine/XNDDS.h b/XNCore_Win/XNGlobalDefine/XNDDS.h new file mode 100644 index 0000000..1c708de --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNDDS.h @@ -0,0 +1,76 @@ +#pragma once + +// FastDDS头文件 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// FastDDS宏定义 +#define XN_DDS eprosima::fastdds::dds +namespace XNSim { +template using XNDDSOptional = eprosima::fastcdr::optional; + +using XNDDSParticipantPtr = XN_DDS::DomainParticipant *; +using XNDDSPublisherPtr = XN_DDS::Publisher *; +using XNDDSSubscriberPtr = XN_DDS::Subscriber *; +using XNDDSTopicPtr = XN_DDS::Topic *; +using XNDDSDataWriterPtr = XN_DDS::DataWriter *; +using XNDDSDataReaderPtr = XN_DDS::DataReader *; +using XNDDSTypeSupport = XN_DDS::TypeSupport; +using XNDDSDataWriterQos = XN_DDS::DataWriterQos; +using XNDDSDataReaderQos = XN_DDS::DataReaderQos; +using XNDDSParticipantQos = XN_DDS::DomainParticipantQos; +using XNDDSTopicQos = XN_DDS::TopicQos; +using XNDDSPublisherQos = XN_DDS::PublisherQos; +using XNDDSSubscriberQos = XN_DDS::SubscriberQos; + +using XNDDSPublisherMap = std::unordered_map; +using XNDDSSubscriberMap = std::unordered_map; +using XNDDSDataWriterMap = std::unordered_map; + +struct PublisherInfo { + XNDDSPublisherPtr publisher; + XNDDSDataWriterPtr dataWriter; +}; + +struct SubscriberInfo { + XNDDSSubscriberPtr subscriber; + XNDDSDataReaderPtr dataReader; +}; + +struct TopicInfo { + XNDDSTopicPtr topic; + XNDDSPublisherMap publishers_; + XNDDSSubscriberMap subscribers_; +}; + +using XNDDSTopicMap = std::unordered_map; + +template using XNDDSCallBack = std::function; + +template +class DataReaderListenerImpl : public XN_DDS::DataReaderListener { +public: + DataReaderListenerImpl(XNDDSCallBack callback) : callback_(callback) {} + + void on_data_available(XNDDSDataReaderPtr reader) override { + XN_DDS::SampleInfo info; + if (reader->take_next_sample(&data_, &info) == XN_DDS::RETCODE_OK && + info.valid_data) { + callback_(data_); + } + } + +private: + T data_; + XNDDSCallBack callback_; +}; + +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNDataBase.h b/XNCore_Win/XNGlobalDefine/XNDataBase.h new file mode 100644 index 0000000..0ec9eb4 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNDataBase.h @@ -0,0 +1,60 @@ +#pragma once + +// sqlite3头文件 +#include "XNCore_global.h" +#include "XNString.h" +#include "XNType.h" +#include + +namespace XNSim { +using XN_DB = sqlite3; +using XN_DB_PTR = XN_DB *; +using XN_DB_STMT = sqlite3_stmt; +using XN_DB_STMT_PTR = XN_DB_STMT *; + +FORCEINLINE XN_DB_PTR openDatabase(const XN_STRING &dbPath) { + sqlite3 *db; + if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) { + return nullptr; + } + return db; +} + +FORCEINLINE XN_INT32 closeDatabase(XN_DB_PTR db) { return sqlite3_close(db); } + +FORCEINLINE XN_DB_STMT_PTR prepareSql(XN_DB_PTR db, const XN_STRING &sql) { + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { + return nullptr; + } + return stmt; +} + +FORCEINLINE void finalizeSql(XN_DB_STMT_PTR stmt) { sqlite3_finalize(stmt); } + +FORCEINLINE XN_BOOL bindText(XN_DB_STMT_PTR stmt, XN_INT32 index, + const XN_STRING &text) { + if (sqlite3_bind_text(stmt, index, text.c_str(), text.length(), nullptr) != + SQLITE_OK) { + return false; + } + return true; +} + +FORCEINLINE XN_BOOL stepSql(XN_DB_STMT_PTR stmt) { + if (sqlite3_step(stmt) != SQLITE_ROW) { + return false; + } + return true; +} + +FORCEINLINE XN_STRING getStringFromSqlite3(XN_DB_STMT_PTR stmt, + XN_INT32 column) { + const char *text = + reinterpret_cast(sqlite3_column_text(stmt, column)); + if (text == nullptr) { + return ""; + } + return XN_STRING(text); +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNDefine.h b/XNCore_Win/XNGlobalDefine/XNDefine.h new file mode 100644 index 0000000..81e692b --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNDefine.h @@ -0,0 +1,46 @@ +#pragma once + +#include "XNByteArray.h" +#include "XNCore_global.h" +#include "XNDDS.h" +#include "XNDataBase.h" +#include "XNDynamicLoad.h" +#include "XNEnum.h" +#include "XNFile.h" +#include "XNJson.h" +#include "XNMemory.h" +#include "XNMeta.h" +#include "XNString.h" +#include "XNThread.h" +#include "XNTime.h" +#include "XNType.h" +#include "XNTypeTraits.h" +#include "XNXml.h" + + +// 标准库头文件 +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief 默认基频定义,单位 Hz + */ +#define BASE_RUN_FREQ 100.0 + +/** + * @brief 默认基础运行间隔定义 单位纳秒 + */ +#define BASE_RUN_INTER (1.0E9 / BASE_RUN_FREQ) + +#define XN_MODEL_ID_SIZE 10000 +#define XN_MODEL_ID_START 10000 +#define XN_MODEL_ID_END 19999 +#define XN_SERVICE_ID_SIZE 10000 +#define XN_SERVICE_ID_START 20000 +#define XN_SERVICE_ID_END 29999 \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNDynamicLoad.h b/XNCore_Win/XNGlobalDefine/XNDynamicLoad.h new file mode 100644 index 0000000..c11d743 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNDynamicLoad.h @@ -0,0 +1,49 @@ +#pragma once + +#include "XNCore_global.h" +#include "XNString.h" + +namespace XNSim { +#ifdef XN_WINDOWS +using XN_HANDLE = HMODULE; +using XN_FARPROC = FARPROC; +#else +using XN_HANDLE = void *; +using XN_FARPROC = void *; +#endif + +FORCEINLINE XN_HANDLE loadLibrary(const XN_STRING &libPath) { +#ifdef XN_WINDOWS + return LoadLibrary(libPath.c_str()); +#else + return dlopen(libPath.c_str(), RTLD_LAZY); +#endif +} + +FORCEINLINE XN_FARPROC getSymbol(XN_HANDLE handle, const XN_STRING &symbol) { +#ifdef XN_WINDOWS + return GetProcAddress(handle, symbol.c_str()); +#else + return dlsym(handle, symbol.c_str()); +#endif +} + +FORCEINLINE XN_STRING LoadError() { +#ifdef XN_WINDOWS + return To_XNString(GetLastError()); +#else + return To_XNString(dlerror()); +#endif +} + +FORCEINLINE void closeLibrary(XN_HANDLE handle) { +#ifdef XN_WINDOWS + FreeLibrary(handle); +#else + dlclose(handle); +#endif + + LoadError(); +} + +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNEnum.h b/XNCore_Win/XNGlobalDefine/XNEnum.h new file mode 100644 index 0000000..1a792d6 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNEnum.h @@ -0,0 +1,142 @@ +#pragma once + +namespace XNSim { +/** + * @brief 系统运行状态枚举类 + */ +enum class RunStatus { + /** + * @brief 未开始 + */ + NotStart = 0, + /** + * @brief 运行中 + */ + Runing, + /** + * @brief 暂停 + */ + Suspend, + /** + * @brief 中止 + */ + Aborted, + /** + * @brief 结束 + */ + Finished +}; + +/** + * @brief 仿真控制命令枚举类 + */ +enum class SimControlCmd { + /** + * @brief 开始 + */ + Start = 0, + /** + * @brief 继续 + */ + Continue, + /** + * @brief 暂停 + */ + Suspend, + /** + * @brief 中止 + */ + Abort +}; + +/** + * @brief 运行频率族枚举类 + */ +enum class FreqLevel { + /** + * @brief 基础频率 + */ + BaseFreq = 0, // 120/100/60 Hz + /** + * @brief 半频 + */ + HalfFreq, // 60/50/30 Hz + /** + * @brief 四分之一频 + */ + QuarterFreq, // 30/25/15 Hz + /** + * @brief 八分之一频 + */ + EighthFreq, // 15/12.5/7.5 Hz + /** + * @brief 十六分之一频 + */ + SixteenthFreq, // 7.5/6.25/3.75 Hz + /** + * @brief 三十二分之一频 + */ + ThirtyTwothFreq, // 3.75/3.125/1.875 Hz +}; + +/** + * @brief 框架对象状态枚举 + */ +enum class XNFrameObjectStatus { + /** + * @brief 未初始化 + */ + NotReady = 0, + /** + * @brief 已初始化 + */ + Initialized, + /** + * @brief 已准备好 + */ + Ready, + /** + * @brief 未知 + */ + Unknown +}; + +enum class XNCoreObjectID { + /** + * @brief 框架对象 + */ + Framework = 0, + /** + * @brief 模型管理器 + */ + ModelManager, + /** + * @brief 时间管理器 + */ + TimeManager = 2, + /** + * @brief 线程管理器 + */ + ThreadManager = 3, + /** + * @brief 服务管理器 + */ + ServiceManager = 4, + /** + * @brief 构型管理器 + */ + ConfigManager = 5, + /** + * @brief 模型管理器 + */ + ModelManager = 6, + /** + * @brief 事件管理器 + */ + EventManager = 7, + /** + * @brief DDS管理器 + */ + DDSManager = 8 +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNFile.h b/XNCore_Win/XNGlobalDefine/XNFile.h new file mode 100644 index 0000000..bf9ae5f --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNFile.h @@ -0,0 +1,41 @@ +#pragma once + +#include "XNCore_global.h" +#include "XNString.h" +#include "XNType.h" +#include +#include + +namespace XNSim { +using XN_PATH = std::filesystem::path; +// 流相关类型别名 +using XN_OFSTREAM = std::ofstream; +using XN_IFSTREAM = std::ifstream; +using XN_FSTREAM = std::fstream; + +FORCEINLINE XN_PATH getCurrentPath() { return std::filesystem::current_path(); } + +FORCEINLINE bool isExist(const XN_PATH &path) { + return std::filesystem::exists(path); +} + +FORCEINLINE bool isDirectory(const XN_PATH &path) { + return std::filesystem::is_directory(path); +} + +FORCEINLINE void createDirectory(const XN_PATH &path) { + std::filesystem::create_directories(path); +} + +FORCEINLINE XN_STRING getFileNameWithoutExt(const XN_STRING &path) { + XN_SIZE lastDot = path.find_last_of('.'); + if (lastDot != XN_STRING::npos) { + return path.substr(0, lastDot); + } + return path; +} + +FORCEINLINE XN_STRING getEnv(const XN_STRING &name) { + return std::getenv(name.c_str()); +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNJson.h b/XNCore_Win/XNGlobalDefine/XNJson.h new file mode 100644 index 0000000..6b6d2a3 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNJson.h @@ -0,0 +1,17 @@ +#pragma once + +// json头文件 +#include "XNCore_global.h" +#include "XNString.h" +#include + +namespace XNSim { +// json类型别名 +using XN_JSON = nlohmann::json; + +FORCEINLINE XN_JSON parseJson(const XN_STRING &jsonStr) { + return XN_JSON::parse(jsonStr); +} + +FORCEINLINE XN_STRING toJson(const XN_JSON &json) { return json.dump(); } +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNMemory.h b/XNCore_Win/XNGlobalDefine/XNMemory.h new file mode 100644 index 0000000..37fa3c9 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNMemory.h @@ -0,0 +1,42 @@ +#pragma once + +#include "XNCore_global.h" +#include + +namespace XNSim { +template +using XN_ENABLE_SHARED_FROM_THIS = std::enable_shared_from_this; + +// 静态指针类型转换辅助函数 +template +FORCEINLINE ToType XNStaticCastHelper(const FromType &from) { + return std::static_pointer_cast(from); +} + +// 动态指针类型转换辅助函数 +template +FORCEINLINE ToType XNCastHelper(const FromType &from) { + return std::dynamic_pointer_cast(from); +} + +} // namespace XNSim + +// 静态类型转换宏 +#define XN_CAST(from, to) XNStaticCastHelper(from) + +// 获取当前对象的智能指针 +#define XN_THISPTR std::static_pointer_cast(shared_from_this()) + +// 类智能指针声明宏 +#define XNCLASS_PTR_DECLARE(a) \ + using a##Ptr = std::shared_ptr; \ + using a##WPtr = std::weak_ptr; \ + using a##UPtr = std::unique_ptr; \ + using a##ConsPtr = std::shared_ptr; + +// 结构体智能指针声明宏 +#define XNSTRUCT_PTR_DECLARE(a) \ + using a##Ptr = std::shared_ptr; \ + using a##WPtr = std::weak_ptr; \ + using a##UPtr = std::unique_ptr; \ + using a##ConsPtr = std::shared_ptr; \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNMeta.h b/XNCore_Win/XNGlobalDefine/XNMeta.h new file mode 100644 index 0000000..6d59099 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNMeta.h @@ -0,0 +1,45 @@ +#pragma once + +#include "XNCore_global.h" + +namespace XNSim { +// 空类宏 +struct XNNullClass {}; +} // namespace XNSim + +// 禁止拷贝构造和赋值宏 +#define XN_NOCOPYABLE(Class) \ +public: \ + using NoCopyable = Class; \ + \ +private: \ + Class(const Class &) = delete; \ + Class &operator=(const Class &) = delete; + +// 声明私有类宏 +#define XN_DECLARE_PRIVATE(Class) \ + XN_NOCOPYABLE(Class) \ +protected: \ + friend class Class##Private; \ + inline Class##Private *GetPP() const { \ + return reinterpret_cast(_Private_Ptr); \ + } \ + using PrivateType = Class##Private; + +// 获取私有类指针宏 +#define T_D() PrivateType *const d = GetPP() + +// 元类型声明宏 +#define XN_METATYPE_P(cls) \ +public: \ + using ThisType = cls; \ + using SuperType = XNSim::XNNullClass; + +// 元类型声明宏 +#define XN_METATYPE(cls, sup) \ +public: \ + using ThisType = cls; \ + using SuperType = sup; + +// 忽略参数宏 +#define XN_UNUSED(x) (void)x \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNString.h b/XNCore_Win/XNGlobalDefine/XNString.h new file mode 100644 index 0000000..bc9caa8 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNString.h @@ -0,0 +1,73 @@ +#pragma once +#include "XNCore_global.h" +#include "XNType.h" +#include +#include + +namespace XNSim { +// 字符串类型抽象 +using XN_STRING = std::string; +using XN_WSTRING = std::wstring; +using XN_STRINGLIST = std::vector; +using XN_WSTRINGLIST = std::vector; +// 字符串转换辅助函数 +template FORCEINLINE XN_STRING To_XNString(const T &value) { + return std::to_string(value); +} + +template FORCEINLINE XN_WSTRING To_XNWString(const T &value) { + return std::to_wstring(value); +} + +FORCEINLINE XN_STRINGLIST XNSplit(const XN_STRING &str, + const XN_STRING &delim) { + XN_STRINGLIST tokens; + XN_SIZE prev = 0, pos = 0; + do { + pos = str.find(delim, prev); + if (pos == XN_STRING::npos) + pos = str.length(); + XN_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; +} + +FORCEINLINE XN_INT32 XNSafe_stoi(const XN_STRING &str, + XN_INT32 defaultValue = 0) { + if (str.empty()) { + return defaultValue; + } + try { + return std::stoi(str); + } catch (const std::exception &) { + return defaultValue; + } +} + +FORCEINLINE XN_DOUBLE XNSafe_stod(const XN_STRING &str, + XN_DOUBLE defaultValue = 0) { + if (str.empty()) { + return defaultValue; + } + try { + return std::stod(str); + } catch (const std::exception &) { + return defaultValue; + } +} + +FORCEINLINE XN_INT64 XNSafe_stoll(const XN_STRING &str, + XN_INT64 defaultValue = 0) { + if (str.empty()) { + return defaultValue; + } + try { + return std::stoll(str); + } catch (const std::exception &) { + return defaultValue; + } +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNThread.h b/XNCore_Win/XNGlobalDefine/XNThread.h new file mode 100644 index 0000000..17026a3 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNThread.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#ifdef XN_LINUX +#include +#endif + +namespace XNSim { +// 线程相关抽象 +using XN_MUTEX = std::mutex; + +#ifdef XN_WINDOWS +using XN_THREAD = std::thread; +using XN_THREAD_MUTEX = std::unique_lock; +using XN_THREAD_CV = std::condition_variable; +#endif + +#ifdef XN_LINUX +using XN_THREAD = pthread_t; +using XN_THREAD_MUTEX = pthread_mutex_t; +using XN_THREAD_CV = pthread_cond_t; +using XN_THREAD_ATTR = pthread_attr_t; +using XN_THREAD_SCHED_PARAM = sched_param; +#endif + +FORCEINLINE void XNThreadMutexLock(XN_THREAD_MUTEX *mutex) { +#ifdef XN_WINDOWS + mutex->lock(); +#endif +#ifdef XN_LINUX + pthread_mutex_lock(mutex); +#endif +} + +FORCEINLINE void XNThreadMutexUnlock(XN_THREAD_MUTEX *mutex) { +#ifdef XN_WINDOWS + mutex->unlock(); +#endif +#ifdef XN_LINUX + pthread_mutex_unlock(mutex); +#endif +} + +FORCEINLINE void XNThreadCVWait(XN_THREAD_CV *cv, XN_THREAD_MUTEX *mutex) { +#ifdef XN_WINDOWS + cv->wait(*mutex); +#endif +#ifdef XN_LINUX + pthread_cond_wait(cv, mutex); +#endif +} + +FORCEINLINE void XNThreadCVNotifyOne(XN_THREAD_CV *cv) { +#ifdef XN_WINDOWS + cv->notify_one(); +#endif +#ifdef XN_LINUX + pthread_cond_signal(cv); +#endif +} + +FORCEINLINE void XNThreadCVNotifyAll(XN_THREAD_CV *cv) { +#ifdef XN_WINDOWS + cv->notify_all(); +#endif +#ifdef XN_LINUX + pthread_cond_broadcast(cv); +#endif +} + +FORCEINLINE void XNThreadJoin(XN_THREAD &thread) { +#ifdef XN_WINDOWS + thread.join(); +#endif +#ifdef XN_LINUX + pthread_join(thread, NULL); +#endif +} + +FORCEINLINE void XNThreadDetach(XN_THREAD &thread) { +#ifdef XN_WINDOWS + thread.detach(); +#endif +#ifdef XN_LINUX + pthread_detach(thread); +#endif +} + +FORCEINLINE XN_UINT32 XNThreadGetID() { +#ifdef XN_WINDOWS + return GetCurrentThreadId(); +#endif +#ifdef XN_LINUX + return pthread_self(); +#endif +} + +// 模型周期性回调函数类型别名 +using XNCallBack = std::function; + +// 事件回调函数类型别名 +using XNEventCallback = std::function; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNTime.h b/XNCore_Win/XNGlobalDefine/XNTime.h new file mode 100644 index 0000000..642321e --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNTime.h @@ -0,0 +1,99 @@ +#pragma once + +#include "XNCore_global.h" +#include "XNString.h" +#include "XNType.h" +#include +#include +#include +#include + +namespace XNSim { + +// 系统时间点类型别名 +using XNTimePoint = std::chrono::system_clock::time_point; + +/** + * @brief 将ISO格式的时间字符串转换为系统时间点 + * @param timeStr ISO格式的时间字符串 (YYYY-MM-DDTHH:mm:ss) + * @return 系统时间点 + */ +FORCEINLINE XNTimePoint parseISOTime(const XN_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; +} + +struct PERIOD_INFO; + +#ifdef XN_WINDOWS +using XN_TIMESPEC = LARGE_INTEGER; + +FORCEINLINE void getCurrentRTTime(XN_TIMESPEC *time) { + QueryPerformanceCounter(time); +} + +FORCEINLINE double calculateRTTime(XN_TIMESPEC *now, XN_TIMESPEC *last) { + XN_TIMESPEC freq; + QueryPerformanceFrequency(&freq); + XN_INT64 ns = (now->QuadPart - last->QuadPart) * 1000000LL / freq.QuadPart; + return (double)ns / 1.0E9; +} + +FORCEINLINE void sleepToNextRTTime(PERIOD_INFO *pinfo) { + XN_TIMESPEC freq; + QueryPerformanceFrequency(&freq); + auto now = pinfo->next_period; + pinfo->next_period.QuadPart += (pinfo->period_ns * freq.QuadPart) / 1000000LL; + XN_INT64 ns = + (pinfo->next_period.QuadPart - now.QuadPart) * 1000000LL / freq.QuadPart; + Sleep(ns / 1000); +} +#endif + +#ifdef XN_LINUX +using XN_TIMESPEC = timespec; + +FORCEINLINE void getCurrentRTTime(XN_TIMESPEC *time) { + clock_gettime(CLOCK_MONOTONIC, time); +} + +FORCEINLINE double calculateRTTime(XN_TIMESPEC *now, XN_TIMESPEC *last) { + double seconds = (double)(now->tv_sec - last->tv_sec) + + (double)(now->tv_nsec - last->tv_nsec) / 1.0E9; + return seconds; +} + +FORCEINLINE void sleepToNextRTTime(PERIOD_INFO *pinfo) { + // 睡眠时间步进 + pinfo->next_period.tv_nsec += pinfo->period_ns; + + // 睡眠时间整理 + while (pinfo->next_period.tv_nsec >= 1000000000) { + pinfo->next_period.tv_sec++; + pinfo->next_period.tv_nsec -= 1000000000; + } + + // 执行纳秒睡眠 + clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &pinfo->next_period, NULL); +} +#endif + +/** + * @brief 纳秒睡眠相关时间结构体 + * @details 用于线程睡眠时间控制 + */ +struct PERIOD_INFO { + /** + * @brief 系统提供的时间记录结构体,精确到纳秒 + */ + XN_TIMESPEC next_period; + /** + * @brief 睡眠时长,单位纳秒 + */ + XN_INT64 period_ns; +}; + +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNType.h b/XNCore_Win/XNGlobalDefine/XNType.h new file mode 100644 index 0000000..1d95cf5 --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNType.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace XNSim { +// 基础类型抽象 +using XN_INT8 = int8_t; +using XN_UINT8 = uint8_t; +using XN_INT16 = int16_t; +using XN_UINT16 = uint16_t; +using XN_INT32 = int32_t; +using XN_UINT32 = uint32_t; +using XN_INT64 = int64_t; +using XN_UINT64 = uint64_t; +using XN_FLOAT = float; +using XN_DOUBLE = double; +using XN_BOOL = bool; +using XN_SIZE = size_t; + +using XNAsignedIDFlag = std::vector; + +using XN_ANY = std::any; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNTypeTraits.h b/XNCore_Win/XNGlobalDefine/XNTypeTraits.h new file mode 100644 index 0000000..55ec59d --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNTypeTraits.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include + +namespace XNSim { + +// 类型检查 +template +inline constexpr bool is_same_v = std::is_same_v; + +// 算术类型检查 +template +inline constexpr bool is_arithmetic_v = std::is_arithmetic_v; + +// 可转换类型检查 +template +inline constexpr bool is_convertible_v = std::is_convertible_v; + +// 数组类型检查 +namespace TypeTraits { +template struct is_std_array : std::false_type {}; + +template +struct is_std_array> : std::true_type {}; +} // namespace TypeTraits + +// 数组类型检查简化使用 +template +inline constexpr bool is_array_v = TypeTraits::is_std_array::value; + +// 获取数组大小 +namespace TypeTraits { +template +struct array_size : std::integral_constant {}; + +template +struct array_size> : std::integral_constant {}; +} // namespace TypeTraits + +// 获取数组大小简化使用 +template +inline constexpr std::size_t array_size_v = TypeTraits::array_size::value; + +// 获取类型大小 +template constexpr size_t getTypeSize() { + if constexpr (is_array_v) { + // 对于std::array,计算所有元素的总大小 + return getTypeSize() * array_size_v; + } else { + return sizeof(T); + } +} + +// 获取数组总大小 +template constexpr std::size_t arrayTotalSize(const T &arr) { + if constexpr (is_array_v) { + // 对于std::array,计算所有元素的总大小 + return getTypeSize() * array_size_v; + } else { + return 1; + } +} + +// 枚举值获取函数 +template +constexpr typename std::underlying_type::type enumValue(T e) { + return static_cast::type>(e); +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNGlobalDefine/XNXml.h b/XNCore_Win/XNGlobalDefine/XNXml.h new file mode 100644 index 0000000..99591ac --- /dev/null +++ b/XNCore_Win/XNGlobalDefine/XNXml.h @@ -0,0 +1,43 @@ +#pragma once + +// tinyxml2头文件 +#include "XNCore_global.h" +#include "XNString.h" +#include + +namespace XNSim { +using XN_XMLDocument = tinyxml2::XMLDocument; +using XN_XMLElement = tinyxml2::XMLElement; + +FORCEINLINE XN_INT32 LoadXmlFile(const XN_STRING &filePath, + XN_XMLDocument &doc) { + if (doc.LoadFile(filePath.c_str()) != tinyxml2::XML_SUCCESS) { + return -1; + } + return 0; +} + +FORCEINLINE XN_XMLElement *GetRootElement(XN_XMLDocument &doc) { + return doc.RootElement(); +} + +FORCEINLINE XN_XMLElement *GetFirstChildElement(XN_XMLElement *element, + const XN_STRING &name) { + return element->FirstChildElement(name.c_str()); +} + +FORCEINLINE XN_STRING GetFirstChildElementText(XN_XMLElement *element, + const XN_STRING &name) { + return XN_STRING(GetFirstChildElement(element, name)->GetText()); +} + +FORCEINLINE XN_XMLElement *GetNextSiblingElement(XN_XMLElement *element, + const XN_STRING &name) { + return element->NextSiblingElement(name.c_str()); +} + +FORCEINLINE XN_STRING GetAttribute(XN_XMLElement *element, + const XN_STRING &name) { + return XN_STRING(element->Attribute(name.c_str())); +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNIDL/CMakeLists.txt b/XNCore_Win/XNIDL/CMakeLists.txt new file mode 100644 index 0000000..c811d79 --- /dev/null +++ b/XNCore_Win/XNIDL/CMakeLists.txt @@ -0,0 +1,11 @@ +set(XNIDL_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatus.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatusCdrAux.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatusCdrAux.ipp + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatusPubSubTypes.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatusPubSubTypes.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatusTypeObjectSupport.cxx + ${CMAKE_CURRENT_SOURCE_DIR}/XNSimStatusTypeObjectSupport.hpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNIDL_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNIDL/XNSimStatus.hpp b/XNCore_Win/XNIDL/XNSimStatus.hpp new file mode 100644 index 0000000..011ee59 --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatus.hpp @@ -0,0 +1,1760 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatus.hpp + * This header file contains the declaration of the described types in the IDL file. + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_HPP +#define FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_HPP + +#include +#include +#include +#include + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#if defined(XNSIMSTATUS_SOURCE) +#define XNSIMSTATUS_DllAPI __declspec( dllexport ) +#else +#define XNSIMSTATUS_DllAPI __declspec( dllimport ) +#endif // XNSIMSTATUS_SOURCE +#else +#define XNSIMSTATUS_DllAPI +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define XNSIMSTATUS_DllAPI +#endif // _WIN32 + +namespace XNSim { + +namespace XNSimStatus { + +/*! + * @brief This class represents the structure XNCoreStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ +class XNCoreStatus +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport XNCoreStatus() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~XNCoreStatus() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object XNCoreStatus that will be copied. + */ + eProsima_user_DllExport XNCoreStatus( + const XNCoreStatus& x) + { + m_XNFWStatus = x.m_XNFWStatus; + + m_XNTMStatus = x.m_XNTMStatus; + + m_XNEMStatus = x.m_XNEMStatus; + + m_XNSDStatus = x.m_XNSDStatus; + + m_XNThMStatus = x.m_XNThMStatus; + + m_XNMMStatus = x.m_XNMMStatus; + + m_XNSMStatus = x.m_XNSMStatus; + + m_XNDMStatus = x.m_XNDMStatus; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object XNCoreStatus that will be copied. + */ + eProsima_user_DllExport XNCoreStatus( + XNCoreStatus&& x) noexcept + { + m_XNFWStatus = x.m_XNFWStatus; + m_XNTMStatus = x.m_XNTMStatus; + m_XNEMStatus = x.m_XNEMStatus; + m_XNSDStatus = x.m_XNSDStatus; + m_XNThMStatus = x.m_XNThMStatus; + m_XNMMStatus = x.m_XNMMStatus; + m_XNSMStatus = x.m_XNSMStatus; + m_XNDMStatus = x.m_XNDMStatus; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object XNCoreStatus that will be copied. + */ + eProsima_user_DllExport XNCoreStatus& operator =( + const XNCoreStatus& x) + { + + m_XNFWStatus = x.m_XNFWStatus; + + m_XNTMStatus = x.m_XNTMStatus; + + m_XNEMStatus = x.m_XNEMStatus; + + m_XNSDStatus = x.m_XNSDStatus; + + m_XNThMStatus = x.m_XNThMStatus; + + m_XNMMStatus = x.m_XNMMStatus; + + m_XNSMStatus = x.m_XNSMStatus; + + m_XNDMStatus = x.m_XNDMStatus; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object XNCoreStatus that will be copied. + */ + eProsima_user_DllExport XNCoreStatus& operator =( + XNCoreStatus&& x) noexcept + { + + m_XNFWStatus = x.m_XNFWStatus; + m_XNTMStatus = x.m_XNTMStatus; + m_XNEMStatus = x.m_XNEMStatus; + m_XNSDStatus = x.m_XNSDStatus; + m_XNThMStatus = x.m_XNThMStatus; + m_XNMMStatus = x.m_XNMMStatus; + m_XNSMStatus = x.m_XNSMStatus; + m_XNDMStatus = x.m_XNDMStatus; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x XNCoreStatus object to compare. + */ + eProsima_user_DllExport bool operator ==( + const XNCoreStatus& x) const + { + return (m_XNFWStatus == x.m_XNFWStatus && + m_XNTMStatus == x.m_XNTMStatus && + m_XNEMStatus == x.m_XNEMStatus && + m_XNSDStatus == x.m_XNSDStatus && + m_XNThMStatus == x.m_XNThMStatus && + m_XNMMStatus == x.m_XNMMStatus && + m_XNSMStatus == x.m_XNSMStatus && + m_XNDMStatus == x.m_XNDMStatus); + } + + /*! + * @brief Comparison operator. + * @param x XNCoreStatus object to compare. + */ + eProsima_user_DllExport bool operator !=( + const XNCoreStatus& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member XNFWStatus + * @param _XNFWStatus New value for member XNFWStatus + */ + eProsima_user_DllExport void XNFWStatus( + int32_t _XNFWStatus) + { + m_XNFWStatus = _XNFWStatus; + } + + /*! + * @brief This function returns the value of member XNFWStatus + * @return Value of member XNFWStatus + */ + eProsima_user_DllExport int32_t XNFWStatus() const + { + return m_XNFWStatus; + } + + /*! + * @brief This function returns a reference to member XNFWStatus + * @return Reference to member XNFWStatus + */ + eProsima_user_DllExport int32_t& XNFWStatus() + { + return m_XNFWStatus; + } + + + /*! + * @brief This function sets a value in member XNTMStatus + * @param _XNTMStatus New value for member XNTMStatus + */ + eProsima_user_DllExport void XNTMStatus( + int32_t _XNTMStatus) + { + m_XNTMStatus = _XNTMStatus; + } + + /*! + * @brief This function returns the value of member XNTMStatus + * @return Value of member XNTMStatus + */ + eProsima_user_DllExport int32_t XNTMStatus() const + { + return m_XNTMStatus; + } + + /*! + * @brief This function returns a reference to member XNTMStatus + * @return Reference to member XNTMStatus + */ + eProsima_user_DllExport int32_t& XNTMStatus() + { + return m_XNTMStatus; + } + + + /*! + * @brief This function sets a value in member XNEMStatus + * @param _XNEMStatus New value for member XNEMStatus + */ + eProsima_user_DllExport void XNEMStatus( + int32_t _XNEMStatus) + { + m_XNEMStatus = _XNEMStatus; + } + + /*! + * @brief This function returns the value of member XNEMStatus + * @return Value of member XNEMStatus + */ + eProsima_user_DllExport int32_t XNEMStatus() const + { + return m_XNEMStatus; + } + + /*! + * @brief This function returns a reference to member XNEMStatus + * @return Reference to member XNEMStatus + */ + eProsima_user_DllExport int32_t& XNEMStatus() + { + return m_XNEMStatus; + } + + + /*! + * @brief This function sets a value in member XNSDStatus + * @param _XNSDStatus New value for member XNSDStatus + */ + eProsima_user_DllExport void XNSDStatus( + int32_t _XNSDStatus) + { + m_XNSDStatus = _XNSDStatus; + } + + /*! + * @brief This function returns the value of member XNSDStatus + * @return Value of member XNSDStatus + */ + eProsima_user_DllExport int32_t XNSDStatus() const + { + return m_XNSDStatus; + } + + /*! + * @brief This function returns a reference to member XNSDStatus + * @return Reference to member XNSDStatus + */ + eProsima_user_DllExport int32_t& XNSDStatus() + { + return m_XNSDStatus; + } + + + /*! + * @brief This function sets a value in member XNThMStatus + * @param _XNThMStatus New value for member XNThMStatus + */ + eProsima_user_DllExport void XNThMStatus( + int32_t _XNThMStatus) + { + m_XNThMStatus = _XNThMStatus; + } + + /*! + * @brief This function returns the value of member XNThMStatus + * @return Value of member XNThMStatus + */ + eProsima_user_DllExport int32_t XNThMStatus() const + { + return m_XNThMStatus; + } + + /*! + * @brief This function returns a reference to member XNThMStatus + * @return Reference to member XNThMStatus + */ + eProsima_user_DllExport int32_t& XNThMStatus() + { + return m_XNThMStatus; + } + + + /*! + * @brief This function sets a value in member XNMMStatus + * @param _XNMMStatus New value for member XNMMStatus + */ + eProsima_user_DllExport void XNMMStatus( + int32_t _XNMMStatus) + { + m_XNMMStatus = _XNMMStatus; + } + + /*! + * @brief This function returns the value of member XNMMStatus + * @return Value of member XNMMStatus + */ + eProsima_user_DllExport int32_t XNMMStatus() const + { + return m_XNMMStatus; + } + + /*! + * @brief This function returns a reference to member XNMMStatus + * @return Reference to member XNMMStatus + */ + eProsima_user_DllExport int32_t& XNMMStatus() + { + return m_XNMMStatus; + } + + + /*! + * @brief This function sets a value in member XNSMStatus + * @param _XNSMStatus New value for member XNSMStatus + */ + eProsima_user_DllExport void XNSMStatus( + int32_t _XNSMStatus) + { + m_XNSMStatus = _XNSMStatus; + } + + /*! + * @brief This function returns the value of member XNSMStatus + * @return Value of member XNSMStatus + */ + eProsima_user_DllExport int32_t XNSMStatus() const + { + return m_XNSMStatus; + } + + /*! + * @brief This function returns a reference to member XNSMStatus + * @return Reference to member XNSMStatus + */ + eProsima_user_DllExport int32_t& XNSMStatus() + { + return m_XNSMStatus; + } + + + /*! + * @brief This function sets a value in member XNDMStatus + * @param _XNDMStatus New value for member XNDMStatus + */ + eProsima_user_DllExport void XNDMStatus( + int32_t _XNDMStatus) + { + m_XNDMStatus = _XNDMStatus; + } + + /*! + * @brief This function returns the value of member XNDMStatus + * @return Value of member XNDMStatus + */ + eProsima_user_DllExport int32_t XNDMStatus() const + { + return m_XNDMStatus; + } + + /*! + * @brief This function returns a reference to member XNDMStatus + * @return Reference to member XNDMStatus + */ + eProsima_user_DllExport int32_t& XNDMStatus() + { + return m_XNDMStatus; + } + + + +private: + + int32_t m_XNFWStatus{0}; + int32_t m_XNTMStatus{0}; + int32_t m_XNEMStatus{0}; + int32_t m_XNSDStatus{0}; + int32_t m_XNThMStatus{0}; + int32_t m_XNMMStatus{0}; + int32_t m_XNSMStatus{0}; + int32_t m_XNDMStatus{0}; + +}; +/*! + * @brief This class represents the structure XNEngineStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ +class XNEngineStatus +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport XNEngineStatus() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~XNEngineStatus() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object XNEngineStatus that will be copied. + */ + eProsima_user_DllExport XNEngineStatus( + const XNEngineStatus& x) + { + m_XNEngineName = x.m_XNEngineName; + + m_XNEngineID = x.m_XNEngineID; + + m_XNEngineSt = x.m_XNEngineSt; + + m_XNEngineAff = x.m_XNEngineAff; + + m_XNThCnt = x.m_XNThCnt; + + m_XNCoreSt = x.m_XNCoreSt; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object XNEngineStatus that will be copied. + */ + eProsima_user_DllExport XNEngineStatus( + XNEngineStatus&& x) noexcept + { + m_XNEngineName = std::move(x.m_XNEngineName); + m_XNEngineID = x.m_XNEngineID; + m_XNEngineSt = x.m_XNEngineSt; + m_XNEngineAff = x.m_XNEngineAff; + m_XNThCnt = x.m_XNThCnt; + m_XNCoreSt = std::move(x.m_XNCoreSt); + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object XNEngineStatus that will be copied. + */ + eProsima_user_DllExport XNEngineStatus& operator =( + const XNEngineStatus& x) + { + + m_XNEngineName = x.m_XNEngineName; + + m_XNEngineID = x.m_XNEngineID; + + m_XNEngineSt = x.m_XNEngineSt; + + m_XNEngineAff = x.m_XNEngineAff; + + m_XNThCnt = x.m_XNThCnt; + + m_XNCoreSt = x.m_XNCoreSt; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object XNEngineStatus that will be copied. + */ + eProsima_user_DllExport XNEngineStatus& operator =( + XNEngineStatus&& x) noexcept + { + + m_XNEngineName = std::move(x.m_XNEngineName); + m_XNEngineID = x.m_XNEngineID; + m_XNEngineSt = x.m_XNEngineSt; + m_XNEngineAff = x.m_XNEngineAff; + m_XNThCnt = x.m_XNThCnt; + m_XNCoreSt = std::move(x.m_XNCoreSt); + return *this; + } + + /*! + * @brief Comparison operator. + * @param x XNEngineStatus object to compare. + */ + eProsima_user_DllExport bool operator ==( + const XNEngineStatus& x) const + { + return (m_XNEngineName == x.m_XNEngineName && + m_XNEngineID == x.m_XNEngineID && + m_XNEngineSt == x.m_XNEngineSt && + m_XNEngineAff == x.m_XNEngineAff && + m_XNThCnt == x.m_XNThCnt && + m_XNCoreSt == x.m_XNCoreSt); + } + + /*! + * @brief Comparison operator. + * @param x XNEngineStatus object to compare. + */ + eProsima_user_DllExport bool operator !=( + const XNEngineStatus& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member XNEngineName + * @param _XNEngineName New value to be copied in member XNEngineName + */ + eProsima_user_DllExport void XNEngineName( + const std::string& _XNEngineName) + { + m_XNEngineName = _XNEngineName; + } + + /*! + * @brief This function moves the value in member XNEngineName + * @param _XNEngineName New value to be moved in member XNEngineName + */ + eProsima_user_DllExport void XNEngineName( + std::string&& _XNEngineName) + { + m_XNEngineName = std::move(_XNEngineName); + } + + /*! + * @brief This function returns a constant reference to member XNEngineName + * @return Constant reference to member XNEngineName + */ + eProsima_user_DllExport const std::string& XNEngineName() const + { + return m_XNEngineName; + } + + /*! + * @brief This function returns a reference to member XNEngineName + * @return Reference to member XNEngineName + */ + eProsima_user_DllExport std::string& XNEngineName() + { + return m_XNEngineName; + } + + + /*! + * @brief This function sets a value in member XNEngineID + * @param _XNEngineID New value for member XNEngineID + */ + eProsima_user_DllExport void XNEngineID( + int32_t _XNEngineID) + { + m_XNEngineID = _XNEngineID; + } + + /*! + * @brief This function returns the value of member XNEngineID + * @return Value of member XNEngineID + */ + eProsima_user_DllExport int32_t XNEngineID() const + { + return m_XNEngineID; + } + + /*! + * @brief This function returns a reference to member XNEngineID + * @return Reference to member XNEngineID + */ + eProsima_user_DllExport int32_t& XNEngineID() + { + return m_XNEngineID; + } + + + /*! + * @brief This function sets a value in member XNEngineSt + * @param _XNEngineSt New value for member XNEngineSt + */ + eProsima_user_DllExport void XNEngineSt( + int32_t _XNEngineSt) + { + m_XNEngineSt = _XNEngineSt; + } + + /*! + * @brief This function returns the value of member XNEngineSt + * @return Value of member XNEngineSt + */ + eProsima_user_DllExport int32_t XNEngineSt() const + { + return m_XNEngineSt; + } + + /*! + * @brief This function returns a reference to member XNEngineSt + * @return Reference to member XNEngineSt + */ + eProsima_user_DllExport int32_t& XNEngineSt() + { + return m_XNEngineSt; + } + + + /*! + * @brief This function sets a value in member XNEngineAff + * @param _XNEngineAff New value for member XNEngineAff + */ + eProsima_user_DllExport void XNEngineAff( + int32_t _XNEngineAff) + { + m_XNEngineAff = _XNEngineAff; + } + + /*! + * @brief This function returns the value of member XNEngineAff + * @return Value of member XNEngineAff + */ + eProsima_user_DllExport int32_t XNEngineAff() const + { + return m_XNEngineAff; + } + + /*! + * @brief This function returns a reference to member XNEngineAff + * @return Reference to member XNEngineAff + */ + eProsima_user_DllExport int32_t& XNEngineAff() + { + return m_XNEngineAff; + } + + + /*! + * @brief This function sets a value in member XNThCnt + * @param _XNThCnt New value for member XNThCnt + */ + eProsima_user_DllExport void XNThCnt( + int32_t _XNThCnt) + { + m_XNThCnt = _XNThCnt; + } + + /*! + * @brief This function returns the value of member XNThCnt + * @return Value of member XNThCnt + */ + eProsima_user_DllExport int32_t XNThCnt() const + { + return m_XNThCnt; + } + + /*! + * @brief This function returns a reference to member XNThCnt + * @return Reference to member XNThCnt + */ + eProsima_user_DllExport int32_t& XNThCnt() + { + return m_XNThCnt; + } + + + /*! + * @brief This function copies the value in member XNCoreSt + * @param _XNCoreSt New value to be copied in member XNCoreSt + */ + eProsima_user_DllExport void XNCoreSt( + const XNCoreStatus& _XNCoreSt) + { + m_XNCoreSt = _XNCoreSt; + } + + /*! + * @brief This function moves the value in member XNCoreSt + * @param _XNCoreSt New value to be moved in member XNCoreSt + */ + eProsima_user_DllExport void XNCoreSt( + XNCoreStatus&& _XNCoreSt) + { + m_XNCoreSt = std::move(_XNCoreSt); + } + + /*! + * @brief This function returns a constant reference to member XNCoreSt + * @return Constant reference to member XNCoreSt + */ + eProsima_user_DllExport const XNCoreStatus& XNCoreSt() const + { + return m_XNCoreSt; + } + + /*! + * @brief This function returns a reference to member XNCoreSt + * @return Reference to member XNCoreSt + */ + eProsima_user_DllExport XNCoreStatus& XNCoreSt() + { + return m_XNCoreSt; + } + + + +private: + + std::string m_XNEngineName; + int32_t m_XNEngineID{0}; + int32_t m_XNEngineSt{0}; + int32_t m_XNEngineAff{0}; + int32_t m_XNThCnt{0}; + XNCoreStatus m_XNCoreSt; + +}; +/*! + * @brief This class represents the structure XNThreadStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ +class XNThreadStatus +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport XNThreadStatus() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~XNThreadStatus() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object XNThreadStatus that will be copied. + */ + eProsima_user_DllExport XNThreadStatus( + const XNThreadStatus& x) + { + m_XNThreadName = x.m_XNThreadName; + + m_XNThreadID = x.m_XNThreadID; + + m_XNThreadSt = x.m_XNThreadSt; + + m_XNThreadAff = x.m_XNThreadAff; + + m_XNThreadPro = x.m_XNThreadPro; + + m_XNThRunCnt = x.m_XNThRunCnt; + + m_XNThCurFreq = x.m_XNThCurFreq; + + m_XNThSetFreq = x.m_XNThSetFreq; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object XNThreadStatus that will be copied. + */ + eProsima_user_DllExport XNThreadStatus( + XNThreadStatus&& x) noexcept + { + m_XNThreadName = std::move(x.m_XNThreadName); + m_XNThreadID = x.m_XNThreadID; + m_XNThreadSt = x.m_XNThreadSt; + m_XNThreadAff = x.m_XNThreadAff; + m_XNThreadPro = x.m_XNThreadPro; + m_XNThRunCnt = x.m_XNThRunCnt; + m_XNThCurFreq = x.m_XNThCurFreq; + m_XNThSetFreq = x.m_XNThSetFreq; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object XNThreadStatus that will be copied. + */ + eProsima_user_DllExport XNThreadStatus& operator =( + const XNThreadStatus& x) + { + + m_XNThreadName = x.m_XNThreadName; + + m_XNThreadID = x.m_XNThreadID; + + m_XNThreadSt = x.m_XNThreadSt; + + m_XNThreadAff = x.m_XNThreadAff; + + m_XNThreadPro = x.m_XNThreadPro; + + m_XNThRunCnt = x.m_XNThRunCnt; + + m_XNThCurFreq = x.m_XNThCurFreq; + + m_XNThSetFreq = x.m_XNThSetFreq; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object XNThreadStatus that will be copied. + */ + eProsima_user_DllExport XNThreadStatus& operator =( + XNThreadStatus&& x) noexcept + { + + m_XNThreadName = std::move(x.m_XNThreadName); + m_XNThreadID = x.m_XNThreadID; + m_XNThreadSt = x.m_XNThreadSt; + m_XNThreadAff = x.m_XNThreadAff; + m_XNThreadPro = x.m_XNThreadPro; + m_XNThRunCnt = x.m_XNThRunCnt; + m_XNThCurFreq = x.m_XNThCurFreq; + m_XNThSetFreq = x.m_XNThSetFreq; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x XNThreadStatus object to compare. + */ + eProsima_user_DllExport bool operator ==( + const XNThreadStatus& x) const + { + return (m_XNThreadName == x.m_XNThreadName && + m_XNThreadID == x.m_XNThreadID && + m_XNThreadSt == x.m_XNThreadSt && + m_XNThreadAff == x.m_XNThreadAff && + m_XNThreadPro == x.m_XNThreadPro && + m_XNThRunCnt == x.m_XNThRunCnt && + m_XNThCurFreq == x.m_XNThCurFreq && + m_XNThSetFreq == x.m_XNThSetFreq); + } + + /*! + * @brief Comparison operator. + * @param x XNThreadStatus object to compare. + */ + eProsima_user_DllExport bool operator !=( + const XNThreadStatus& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member XNThreadName + * @param _XNThreadName New value to be copied in member XNThreadName + */ + eProsima_user_DllExport void XNThreadName( + const std::string& _XNThreadName) + { + m_XNThreadName = _XNThreadName; + } + + /*! + * @brief This function moves the value in member XNThreadName + * @param _XNThreadName New value to be moved in member XNThreadName + */ + eProsima_user_DllExport void XNThreadName( + std::string&& _XNThreadName) + { + m_XNThreadName = std::move(_XNThreadName); + } + + /*! + * @brief This function returns a constant reference to member XNThreadName + * @return Constant reference to member XNThreadName + */ + eProsima_user_DllExport const std::string& XNThreadName() const + { + return m_XNThreadName; + } + + /*! + * @brief This function returns a reference to member XNThreadName + * @return Reference to member XNThreadName + */ + eProsima_user_DllExport std::string& XNThreadName() + { + return m_XNThreadName; + } + + + /*! + * @brief This function sets a value in member XNThreadID + * @param _XNThreadID New value for member XNThreadID + */ + eProsima_user_DllExport void XNThreadID( + int32_t _XNThreadID) + { + m_XNThreadID = _XNThreadID; + } + + /*! + * @brief This function returns the value of member XNThreadID + * @return Value of member XNThreadID + */ + eProsima_user_DllExport int32_t XNThreadID() const + { + return m_XNThreadID; + } + + /*! + * @brief This function returns a reference to member XNThreadID + * @return Reference to member XNThreadID + */ + eProsima_user_DllExport int32_t& XNThreadID() + { + return m_XNThreadID; + } + + + /*! + * @brief This function sets a value in member XNThreadSt + * @param _XNThreadSt New value for member XNThreadSt + */ + eProsima_user_DllExport void XNThreadSt( + int32_t _XNThreadSt) + { + m_XNThreadSt = _XNThreadSt; + } + + /*! + * @brief This function returns the value of member XNThreadSt + * @return Value of member XNThreadSt + */ + eProsima_user_DllExport int32_t XNThreadSt() const + { + return m_XNThreadSt; + } + + /*! + * @brief This function returns a reference to member XNThreadSt + * @return Reference to member XNThreadSt + */ + eProsima_user_DllExport int32_t& XNThreadSt() + { + return m_XNThreadSt; + } + + + /*! + * @brief This function sets a value in member XNThreadAff + * @param _XNThreadAff New value for member XNThreadAff + */ + eProsima_user_DllExport void XNThreadAff( + int32_t _XNThreadAff) + { + m_XNThreadAff = _XNThreadAff; + } + + /*! + * @brief This function returns the value of member XNThreadAff + * @return Value of member XNThreadAff + */ + eProsima_user_DllExport int32_t XNThreadAff() const + { + return m_XNThreadAff; + } + + /*! + * @brief This function returns a reference to member XNThreadAff + * @return Reference to member XNThreadAff + */ + eProsima_user_DllExport int32_t& XNThreadAff() + { + return m_XNThreadAff; + } + + + /*! + * @brief This function sets a value in member XNThreadPro + * @param _XNThreadPro New value for member XNThreadPro + */ + eProsima_user_DllExport void XNThreadPro( + int32_t _XNThreadPro) + { + m_XNThreadPro = _XNThreadPro; + } + + /*! + * @brief This function returns the value of member XNThreadPro + * @return Value of member XNThreadPro + */ + eProsima_user_DllExport int32_t XNThreadPro() const + { + return m_XNThreadPro; + } + + /*! + * @brief This function returns a reference to member XNThreadPro + * @return Reference to member XNThreadPro + */ + eProsima_user_DllExport int32_t& XNThreadPro() + { + return m_XNThreadPro; + } + + + /*! + * @brief This function sets a value in member XNThRunCnt + * @param _XNThRunCnt New value for member XNThRunCnt + */ + eProsima_user_DllExport void XNThRunCnt( + uint64_t _XNThRunCnt) + { + m_XNThRunCnt = _XNThRunCnt; + } + + /*! + * @brief This function returns the value of member XNThRunCnt + * @return Value of member XNThRunCnt + */ + eProsima_user_DllExport uint64_t XNThRunCnt() const + { + return m_XNThRunCnt; + } + + /*! + * @brief This function returns a reference to member XNThRunCnt + * @return Reference to member XNThRunCnt + */ + eProsima_user_DllExport uint64_t& XNThRunCnt() + { + return m_XNThRunCnt; + } + + + /*! + * @brief This function sets a value in member XNThCurFreq + * @param _XNThCurFreq New value for member XNThCurFreq + */ + eProsima_user_DllExport void XNThCurFreq( + double _XNThCurFreq) + { + m_XNThCurFreq = _XNThCurFreq; + } + + /*! + * @brief This function returns the value of member XNThCurFreq + * @return Value of member XNThCurFreq + */ + eProsima_user_DllExport double XNThCurFreq() const + { + return m_XNThCurFreq; + } + + /*! + * @brief This function returns a reference to member XNThCurFreq + * @return Reference to member XNThCurFreq + */ + eProsima_user_DllExport double& XNThCurFreq() + { + return m_XNThCurFreq; + } + + + /*! + * @brief This function sets a value in member XNThSetFreq + * @param _XNThSetFreq New value for member XNThSetFreq + */ + eProsima_user_DllExport void XNThSetFreq( + double _XNThSetFreq) + { + m_XNThSetFreq = _XNThSetFreq; + } + + /*! + * @brief This function returns the value of member XNThSetFreq + * @return Value of member XNThSetFreq + */ + eProsima_user_DllExport double XNThSetFreq() const + { + return m_XNThSetFreq; + } + + /*! + * @brief This function returns a reference to member XNThSetFreq + * @return Reference to member XNThSetFreq + */ + eProsima_user_DllExport double& XNThSetFreq() + { + return m_XNThSetFreq; + } + + + +private: + + std::string m_XNThreadName; + int32_t m_XNThreadID{0}; + int32_t m_XNThreadSt{0}; + int32_t m_XNThreadAff{0}; + int32_t m_XNThreadPro{0}; + uint64_t m_XNThRunCnt{0}; + double m_XNThCurFreq{0.0}; + double m_XNThSetFreq{0.0}; + +}; +/*! + * @brief This class represents the structure XNModelStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ +class XNModelStatus +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport XNModelStatus() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~XNModelStatus() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object XNModelStatus that will be copied. + */ + eProsima_user_DllExport XNModelStatus( + const XNModelStatus& x) + { + m_XNModelName = x.m_XNModelName; + + m_XNModelID = x.m_XNModelID; + + m_XNModelSt = x.m_XNModelSt; + + m_XNModelThID = x.m_XNModelThID; + + m_XNModelNode = x.m_XNModelNode; + + m_XNModelPro = x.m_XNModelPro; + + m_XNModelRunCnt = x.m_XNModelRunCnt; + + m_XNMdlCurFreq = x.m_XNMdlCurFreq; + + m_XNMdlSetFreq = x.m_XNMdlSetFreq; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object XNModelStatus that will be copied. + */ + eProsima_user_DllExport XNModelStatus( + XNModelStatus&& x) noexcept + { + m_XNModelName = std::move(x.m_XNModelName); + m_XNModelID = x.m_XNModelID; + m_XNModelSt = x.m_XNModelSt; + m_XNModelThID = x.m_XNModelThID; + m_XNModelNode = x.m_XNModelNode; + m_XNModelPro = x.m_XNModelPro; + m_XNModelRunCnt = x.m_XNModelRunCnt; + m_XNMdlCurFreq = x.m_XNMdlCurFreq; + m_XNMdlSetFreq = x.m_XNMdlSetFreq; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object XNModelStatus that will be copied. + */ + eProsima_user_DllExport XNModelStatus& operator =( + const XNModelStatus& x) + { + + m_XNModelName = x.m_XNModelName; + + m_XNModelID = x.m_XNModelID; + + m_XNModelSt = x.m_XNModelSt; + + m_XNModelThID = x.m_XNModelThID; + + m_XNModelNode = x.m_XNModelNode; + + m_XNModelPro = x.m_XNModelPro; + + m_XNModelRunCnt = x.m_XNModelRunCnt; + + m_XNMdlCurFreq = x.m_XNMdlCurFreq; + + m_XNMdlSetFreq = x.m_XNMdlSetFreq; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object XNModelStatus that will be copied. + */ + eProsima_user_DllExport XNModelStatus& operator =( + XNModelStatus&& x) noexcept + { + + m_XNModelName = std::move(x.m_XNModelName); + m_XNModelID = x.m_XNModelID; + m_XNModelSt = x.m_XNModelSt; + m_XNModelThID = x.m_XNModelThID; + m_XNModelNode = x.m_XNModelNode; + m_XNModelPro = x.m_XNModelPro; + m_XNModelRunCnt = x.m_XNModelRunCnt; + m_XNMdlCurFreq = x.m_XNMdlCurFreq; + m_XNMdlSetFreq = x.m_XNMdlSetFreq; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x XNModelStatus object to compare. + */ + eProsima_user_DllExport bool operator ==( + const XNModelStatus& x) const + { + return (m_XNModelName == x.m_XNModelName && + m_XNModelID == x.m_XNModelID && + m_XNModelSt == x.m_XNModelSt && + m_XNModelThID == x.m_XNModelThID && + m_XNModelNode == x.m_XNModelNode && + m_XNModelPro == x.m_XNModelPro && + m_XNModelRunCnt == x.m_XNModelRunCnt && + m_XNMdlCurFreq == x.m_XNMdlCurFreq && + m_XNMdlSetFreq == x.m_XNMdlSetFreq); + } + + /*! + * @brief Comparison operator. + * @param x XNModelStatus object to compare. + */ + eProsima_user_DllExport bool operator !=( + const XNModelStatus& x) const + { + return !(*this == x); + } + + /*! + * @brief This function copies the value in member XNModelName + * @param _XNModelName New value to be copied in member XNModelName + */ + eProsima_user_DllExport void XNModelName( + const std::string& _XNModelName) + { + m_XNModelName = _XNModelName; + } + + /*! + * @brief This function moves the value in member XNModelName + * @param _XNModelName New value to be moved in member XNModelName + */ + eProsima_user_DllExport void XNModelName( + std::string&& _XNModelName) + { + m_XNModelName = std::move(_XNModelName); + } + + /*! + * @brief This function returns a constant reference to member XNModelName + * @return Constant reference to member XNModelName + */ + eProsima_user_DllExport const std::string& XNModelName() const + { + return m_XNModelName; + } + + /*! + * @brief This function returns a reference to member XNModelName + * @return Reference to member XNModelName + */ + eProsima_user_DllExport std::string& XNModelName() + { + return m_XNModelName; + } + + + /*! + * @brief This function sets a value in member XNModelID + * @param _XNModelID New value for member XNModelID + */ + eProsima_user_DllExport void XNModelID( + int32_t _XNModelID) + { + m_XNModelID = _XNModelID; + } + + /*! + * @brief This function returns the value of member XNModelID + * @return Value of member XNModelID + */ + eProsima_user_DllExport int32_t XNModelID() const + { + return m_XNModelID; + } + + /*! + * @brief This function returns a reference to member XNModelID + * @return Reference to member XNModelID + */ + eProsima_user_DllExport int32_t& XNModelID() + { + return m_XNModelID; + } + + + /*! + * @brief This function sets a value in member XNModelSt + * @param _XNModelSt New value for member XNModelSt + */ + eProsima_user_DllExport void XNModelSt( + int32_t _XNModelSt) + { + m_XNModelSt = _XNModelSt; + } + + /*! + * @brief This function returns the value of member XNModelSt + * @return Value of member XNModelSt + */ + eProsima_user_DllExport int32_t XNModelSt() const + { + return m_XNModelSt; + } + + /*! + * @brief This function returns a reference to member XNModelSt + * @return Reference to member XNModelSt + */ + eProsima_user_DllExport int32_t& XNModelSt() + { + return m_XNModelSt; + } + + + /*! + * @brief This function sets a value in member XNModelThID + * @param _XNModelThID New value for member XNModelThID + */ + eProsima_user_DllExport void XNModelThID( + int32_t _XNModelThID) + { + m_XNModelThID = _XNModelThID; + } + + /*! + * @brief This function returns the value of member XNModelThID + * @return Value of member XNModelThID + */ + eProsima_user_DllExport int32_t XNModelThID() const + { + return m_XNModelThID; + } + + /*! + * @brief This function returns a reference to member XNModelThID + * @return Reference to member XNModelThID + */ + eProsima_user_DllExport int32_t& XNModelThID() + { + return m_XNModelThID; + } + + + /*! + * @brief This function sets a value in member XNModelNode + * @param _XNModelNode New value for member XNModelNode + */ + eProsima_user_DllExport void XNModelNode( + int32_t _XNModelNode) + { + m_XNModelNode = _XNModelNode; + } + + /*! + * @brief This function returns the value of member XNModelNode + * @return Value of member XNModelNode + */ + eProsima_user_DllExport int32_t XNModelNode() const + { + return m_XNModelNode; + } + + /*! + * @brief This function returns a reference to member XNModelNode + * @return Reference to member XNModelNode + */ + eProsima_user_DllExport int32_t& XNModelNode() + { + return m_XNModelNode; + } + + + /*! + * @brief This function sets a value in member XNModelPro + * @param _XNModelPro New value for member XNModelPro + */ + eProsima_user_DllExport void XNModelPro( + int32_t _XNModelPro) + { + m_XNModelPro = _XNModelPro; + } + + /*! + * @brief This function returns the value of member XNModelPro + * @return Value of member XNModelPro + */ + eProsima_user_DllExport int32_t XNModelPro() const + { + return m_XNModelPro; + } + + /*! + * @brief This function returns a reference to member XNModelPro + * @return Reference to member XNModelPro + */ + eProsima_user_DllExport int32_t& XNModelPro() + { + return m_XNModelPro; + } + + + /*! + * @brief This function sets a value in member XNModelRunCnt + * @param _XNModelRunCnt New value for member XNModelRunCnt + */ + eProsima_user_DllExport void XNModelRunCnt( + uint64_t _XNModelRunCnt) + { + m_XNModelRunCnt = _XNModelRunCnt; + } + + /*! + * @brief This function returns the value of member XNModelRunCnt + * @return Value of member XNModelRunCnt + */ + eProsima_user_DllExport uint64_t XNModelRunCnt() const + { + return m_XNModelRunCnt; + } + + /*! + * @brief This function returns a reference to member XNModelRunCnt + * @return Reference to member XNModelRunCnt + */ + eProsima_user_DllExport uint64_t& XNModelRunCnt() + { + return m_XNModelRunCnt; + } + + + /*! + * @brief This function sets a value in member XNMdlCurFreq + * @param _XNMdlCurFreq New value for member XNMdlCurFreq + */ + eProsima_user_DllExport void XNMdlCurFreq( + double _XNMdlCurFreq) + { + m_XNMdlCurFreq = _XNMdlCurFreq; + } + + /*! + * @brief This function returns the value of member XNMdlCurFreq + * @return Value of member XNMdlCurFreq + */ + eProsima_user_DllExport double XNMdlCurFreq() const + { + return m_XNMdlCurFreq; + } + + /*! + * @brief This function returns a reference to member XNMdlCurFreq + * @return Reference to member XNMdlCurFreq + */ + eProsima_user_DllExport double& XNMdlCurFreq() + { + return m_XNMdlCurFreq; + } + + + /*! + * @brief This function sets a value in member XNMdlSetFreq + * @param _XNMdlSetFreq New value for member XNMdlSetFreq + */ + eProsima_user_DllExport void XNMdlSetFreq( + double _XNMdlSetFreq) + { + m_XNMdlSetFreq = _XNMdlSetFreq; + } + + /*! + * @brief This function returns the value of member XNMdlSetFreq + * @return Value of member XNMdlSetFreq + */ + eProsima_user_DllExport double XNMdlSetFreq() const + { + return m_XNMdlSetFreq; + } + + /*! + * @brief This function returns a reference to member XNMdlSetFreq + * @return Reference to member XNMdlSetFreq + */ + eProsima_user_DllExport double& XNMdlSetFreq() + { + return m_XNMdlSetFreq; + } + + + +private: + + std::string m_XNModelName; + int32_t m_XNModelID{0}; + int32_t m_XNModelSt{0}; + int32_t m_XNModelThID{0}; + int32_t m_XNModelNode{0}; + int32_t m_XNModelPro{0}; + uint64_t m_XNModelRunCnt{0}; + double m_XNMdlCurFreq{0.0}; + double m_XNMdlSetFreq{0.0}; + +}; + +} // namespace XNSimStatus +namespace XNSimControl { + +/*! + * @brief This class represents the structure XNRuntimeControl defined by the user in the IDL file. + * @ingroup XNSimStatus + */ +class XNRuntimeControl +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport XNRuntimeControl() + { + } + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~XNRuntimeControl() + { + } + + /*! + * @brief Copy constructor. + * @param x Reference to the object XNRuntimeControl that will be copied. + */ + eProsima_user_DllExport XNRuntimeControl( + const XNRuntimeControl& x) + { + m_XNSimCmd = x.m_XNSimCmd; + + m_XNThrCmd = x.m_XNThrCmd; + + } + + /*! + * @brief Move constructor. + * @param x Reference to the object XNRuntimeControl that will be copied. + */ + eProsima_user_DllExport XNRuntimeControl( + XNRuntimeControl&& x) noexcept + { + m_XNSimCmd = x.m_XNSimCmd; + m_XNThrCmd = x.m_XNThrCmd; + } + + /*! + * @brief Copy assignment. + * @param x Reference to the object XNRuntimeControl that will be copied. + */ + eProsima_user_DllExport XNRuntimeControl& operator =( + const XNRuntimeControl& x) + { + + m_XNSimCmd = x.m_XNSimCmd; + + m_XNThrCmd = x.m_XNThrCmd; + + return *this; + } + + /*! + * @brief Move assignment. + * @param x Reference to the object XNRuntimeControl that will be copied. + */ + eProsima_user_DllExport XNRuntimeControl& operator =( + XNRuntimeControl&& x) noexcept + { + + m_XNSimCmd = x.m_XNSimCmd; + m_XNThrCmd = x.m_XNThrCmd; + return *this; + } + + /*! + * @brief Comparison operator. + * @param x XNRuntimeControl object to compare. + */ + eProsima_user_DllExport bool operator ==( + const XNRuntimeControl& x) const + { + return (m_XNSimCmd == x.m_XNSimCmd && + m_XNThrCmd == x.m_XNThrCmd); + } + + /*! + * @brief Comparison operator. + * @param x XNRuntimeControl object to compare. + */ + eProsima_user_DllExport bool operator !=( + const XNRuntimeControl& x) const + { + return !(*this == x); + } + + /*! + * @brief This function sets a value in member XNSimCmd + * @param _XNSimCmd New value for member XNSimCmd + */ + eProsima_user_DllExport void XNSimCmd( + int32_t _XNSimCmd) + { + m_XNSimCmd = _XNSimCmd; + } + + /*! + * @brief This function returns the value of member XNSimCmd + * @return Value of member XNSimCmd + */ + eProsima_user_DllExport int32_t XNSimCmd() const + { + return m_XNSimCmd; + } + + /*! + * @brief This function returns a reference to member XNSimCmd + * @return Reference to member XNSimCmd + */ + eProsima_user_DllExport int32_t& XNSimCmd() + { + return m_XNSimCmd; + } + + + /*! + * @brief This function sets a value in member XNThrCmd + * @param _XNThrCmd New value for member XNThrCmd + */ + eProsima_user_DllExport void XNThrCmd( + int32_t _XNThrCmd) + { + m_XNThrCmd = _XNThrCmd; + } + + /*! + * @brief This function returns the value of member XNThrCmd + * @return Value of member XNThrCmd + */ + eProsima_user_DllExport int32_t XNThrCmd() const + { + return m_XNThrCmd; + } + + /*! + * @brief This function returns a reference to member XNThrCmd + * @return Reference to member XNThrCmd + */ + eProsima_user_DllExport int32_t& XNThrCmd() + { + return m_XNThrCmd; + } + + + +private: + + int32_t m_XNSimCmd{0}; + int32_t m_XNThrCmd{0}; + +}; + +} // namespace XNSimControl + +} // namespace XNSim + +#endif // _FAST_DDS_GENERATED_XNSIM_XNSIMCONTROL_XNSIMSTATUS_HPP_ + + diff --git a/XNCore_Win/XNIDL/XNSimStatus.idl b/XNCore_Win/XNIDL/XNSimStatus.idl new file mode 100644 index 0000000..d236536 --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatus.idl @@ -0,0 +1,67 @@ +module XNSim +{ + module XNSimStatus + { + //内核加载状态,内置类型,不能用作主题 + @nested + struct XNCoreStatus + { + long XNFWStatus; //主框架加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNTMStatus; //时间管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNEMStatus; //事件管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNSDStatus; //场景管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNThMStatus; //线程管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNMMStatus; //模型管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNSMStatus; //服务管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + long XNDMStatus; //DDS管理器加载状态 0-未加载 1-初始化完成 2-正常 其它-异常 + }; + + //引擎状态主题 + struct XNEngineStatus + { + string XNEngineName; //引擎名称 + long XNEngineID; //引擎ID + long XNEngineSt; //引擎状态 0-未开始 1-运行中 2-暂停 3-终止 其它-未知状态 + long XNEngineAff; //引擎CPU亲和性 + long XNThCnt; //线程数量 + XNCoreStatus XNCoreSt; //内核状态 + }; + + //线程状态主题 + struct XNThreadStatus + { + string XNThreadName; //线程名称 + long XNThreadID; //线程ID + long XNThreadSt; //线程状态 0-未开始 1-运行中 2-暂停 3-终止 其它-未知状态 + long XNThreadAff; //线程CPU亲和性 + long XNThreadPro; //线程优先级 + unsigned long long XNThRunCnt; //线程运行周期数 + double XNThCurFreq; //线程实时频率,单位Hz + double XNThSetFreq; //线程设置频率,单位Hz + }; + + //模型状态主题 + struct XNModelStatus + { + string XNModelName; //模型名称 + long XNModelID; //模型ID + long XNModelSt; //模型状态主题 + long XNModelThID; //模型所属线程ID + long XNModelNode; //模型运行节点 + long XNModelPro; //模型运行优先级 + unsigned long long XNModelRunCnt; //模型运行周期数 + double XNMdlCurFreq; //模型实时频率,单位Hz + double XNMdlSetFreq; //模型设置频率,单位Hz + }; + }; + + module XNSimControl + { + //仿真运行控制主题 + struct XNRuntimeControl + { + long XNSimCmd; //仿真控制指令 0-无指令 1-暂停 2-继续 3-终止 + long XNThrCmd; //线程控制指令 从低位到高位,每两个二进制位控制一个线程的运行:00-无指令,01- 暂停,10-继续,11-结束 + }; + }; +}; \ No newline at end of file diff --git a/XNCore_Win/XNIDL/XNSimStatusCdrAux.hpp b/XNCore_Win/XNIDL/XNSimStatusCdrAux.hpp new file mode 100644 index 0000000..e1c93d7 --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatusCdrAux.hpp @@ -0,0 +1,74 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatusCdrAux.hpp + * This source file contains some definitions of CDR related functions. + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_HPP +#define FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_HPP + +#include "XNSimStatus.hpp" + +constexpr uint32_t XNSim_XNSimStatus_XNCoreStatus_max_cdr_typesize {36UL}; +constexpr uint32_t XNSim_XNSimStatus_XNCoreStatus_max_key_cdr_typesize {0UL}; + +constexpr uint32_t XNSim_XNSimStatus_XNModelStatus_max_cdr_typesize {312UL}; +constexpr uint32_t XNSim_XNSimStatus_XNModelStatus_max_key_cdr_typesize {0UL}; + +constexpr uint32_t XNSim_XNSimStatus_XNThreadStatus_max_cdr_typesize {304UL}; +constexpr uint32_t XNSim_XNSimStatus_XNThreadStatus_max_key_cdr_typesize {0UL}; + +constexpr uint32_t XNSim_XNSimControl_XNRuntimeControl_max_cdr_typesize {12UL}; +constexpr uint32_t XNSim_XNSimControl_XNRuntimeControl_max_key_cdr_typesize {0UL}; + +constexpr uint32_t XNSim_XNSimStatus_XNEngineStatus_max_cdr_typesize {316UL}; +constexpr uint32_t XNSim_XNSimStatus_XNEngineStatus_max_key_cdr_typesize {0UL}; + + +namespace eprosima { +namespace fastcdr { + +class Cdr; +class CdrSizeCalculator; + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNCoreStatus& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNEngineStatus& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNThreadStatus& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNModelStatus& data); + +eProsima_user_DllExport void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimControl::XNRuntimeControl& data); + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_HPP + diff --git a/XNCore_Win/XNIDL/XNSimStatusCdrAux.ipp b/XNCore_Win/XNIDL/XNSimStatusCdrAux.ipp new file mode 100644 index 0000000..3eac23d --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatusCdrAux.ipp @@ -0,0 +1,756 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatusCdrAux.ipp + * This source file contains some declarations of CDR related functions. + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_IPP +#define FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_IPP + +#include "XNSimStatusCdrAux.hpp" + +#include +#include + + +#include +using namespace eprosima::fastcdr::exception; + +namespace eprosima { +namespace fastcdr { + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const XNSim::XNSimStatus::XNCoreStatus& data, + size_t& current_alignment) +{ + using namespace XNSim::XNSimStatus; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.XNFWStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.XNTMStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.XNEMStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.XNSDStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.XNThMStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(5), + data.XNMMStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(6), + data.XNSMStatus(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(7), + data.XNDMStatus(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNCoreStatus& data) +{ + using namespace XNSim::XNSimStatus; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.XNFWStatus() + << eprosima::fastcdr::MemberId(1) << data.XNTMStatus() + << eprosima::fastcdr::MemberId(2) << data.XNEMStatus() + << eprosima::fastcdr::MemberId(3) << data.XNSDStatus() + << eprosima::fastcdr::MemberId(4) << data.XNThMStatus() + << eprosima::fastcdr::MemberId(5) << data.XNMMStatus() + << eprosima::fastcdr::MemberId(6) << data.XNSMStatus() + << eprosima::fastcdr::MemberId(7) << data.XNDMStatus() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + XNSim::XNSimStatus::XNCoreStatus& data) +{ + using namespace XNSim::XNSimStatus; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.XNFWStatus(); + break; + + case 1: + dcdr >> data.XNTMStatus(); + break; + + case 2: + dcdr >> data.XNEMStatus(); + break; + + case 3: + dcdr >> data.XNSDStatus(); + break; + + case 4: + dcdr >> data.XNThMStatus(); + break; + + case 5: + dcdr >> data.XNMMStatus(); + break; + + case 6: + dcdr >> data.XNSMStatus(); + break; + + case 7: + dcdr >> data.XNDMStatus(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNCoreStatus& data) +{ + using namespace XNSim::XNSimStatus; + + static_cast(scdr); + static_cast(data); + scdr << data.XNFWStatus(); + + scdr << data.XNTMStatus(); + + scdr << data.XNEMStatus(); + + scdr << data.XNSDStatus(); + + scdr << data.XNThMStatus(); + + scdr << data.XNMMStatus(); + + scdr << data.XNSMStatus(); + + scdr << data.XNDMStatus(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const XNSim::XNSimStatus::XNEngineStatus& data, + size_t& current_alignment) +{ + using namespace XNSim::XNSimStatus; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.XNEngineName(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.XNEngineID(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.XNEngineSt(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.XNEngineAff(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.XNThCnt(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(5), + data.XNCoreSt(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNEngineStatus& data) +{ + using namespace XNSim::XNSimStatus; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.XNEngineName() + << eprosima::fastcdr::MemberId(1) << data.XNEngineID() + << eprosima::fastcdr::MemberId(2) << data.XNEngineSt() + << eprosima::fastcdr::MemberId(3) << data.XNEngineAff() + << eprosima::fastcdr::MemberId(4) << data.XNThCnt() + << eprosima::fastcdr::MemberId(5) << data.XNCoreSt() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + XNSim::XNSimStatus::XNEngineStatus& data) +{ + using namespace XNSim::XNSimStatus; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.XNEngineName(); + break; + + case 1: + dcdr >> data.XNEngineID(); + break; + + case 2: + dcdr >> data.XNEngineSt(); + break; + + case 3: + dcdr >> data.XNEngineAff(); + break; + + case 4: + dcdr >> data.XNThCnt(); + break; + + case 5: + dcdr >> data.XNCoreSt(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNEngineStatus& data) +{ + using namespace XNSim::XNSimStatus; + extern void serialize_key( + Cdr& scdr, + const XNSim::XNSimStatus::XNCoreStatus& data); + + + static_cast(scdr); + static_cast(data); + scdr << data.XNEngineName(); + + scdr << data.XNEngineID(); + + scdr << data.XNEngineSt(); + + scdr << data.XNEngineAff(); + + scdr << data.XNThCnt(); + + serialize_key(scdr, data.XNCoreSt()); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const XNSim::XNSimStatus::XNThreadStatus& data, + size_t& current_alignment) +{ + using namespace XNSim::XNSimStatus; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.XNThreadName(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.XNThreadID(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.XNThreadSt(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.XNThreadAff(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.XNThreadPro(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(5), + data.XNThRunCnt(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(6), + data.XNThCurFreq(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(7), + data.XNThSetFreq(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNThreadStatus& data) +{ + using namespace XNSim::XNSimStatus; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.XNThreadName() + << eprosima::fastcdr::MemberId(1) << data.XNThreadID() + << eprosima::fastcdr::MemberId(2) << data.XNThreadSt() + << eprosima::fastcdr::MemberId(3) << data.XNThreadAff() + << eprosima::fastcdr::MemberId(4) << data.XNThreadPro() + << eprosima::fastcdr::MemberId(5) << data.XNThRunCnt() + << eprosima::fastcdr::MemberId(6) << data.XNThCurFreq() + << eprosima::fastcdr::MemberId(7) << data.XNThSetFreq() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + XNSim::XNSimStatus::XNThreadStatus& data) +{ + using namespace XNSim::XNSimStatus; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.XNThreadName(); + break; + + case 1: + dcdr >> data.XNThreadID(); + break; + + case 2: + dcdr >> data.XNThreadSt(); + break; + + case 3: + dcdr >> data.XNThreadAff(); + break; + + case 4: + dcdr >> data.XNThreadPro(); + break; + + case 5: + dcdr >> data.XNThRunCnt(); + break; + + case 6: + dcdr >> data.XNThCurFreq(); + break; + + case 7: + dcdr >> data.XNThSetFreq(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNThreadStatus& data) +{ + using namespace XNSim::XNSimStatus; + + static_cast(scdr); + static_cast(data); + scdr << data.XNThreadName(); + + scdr << data.XNThreadID(); + + scdr << data.XNThreadSt(); + + scdr << data.XNThreadAff(); + + scdr << data.XNThreadPro(); + + scdr << data.XNThRunCnt(); + + scdr << data.XNThCurFreq(); + + scdr << data.XNThSetFreq(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const XNSim::XNSimStatus::XNModelStatus& data, + size_t& current_alignment) +{ + using namespace XNSim::XNSimStatus; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.XNModelName(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.XNModelID(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(2), + data.XNModelSt(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(3), + data.XNModelThID(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(4), + data.XNModelNode(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(5), + data.XNModelPro(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(6), + data.XNModelRunCnt(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(7), + data.XNMdlCurFreq(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(8), + data.XNMdlSetFreq(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNModelStatus& data) +{ + using namespace XNSim::XNSimStatus; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.XNModelName() + << eprosima::fastcdr::MemberId(1) << data.XNModelID() + << eprosima::fastcdr::MemberId(2) << data.XNModelSt() + << eprosima::fastcdr::MemberId(3) << data.XNModelThID() + << eprosima::fastcdr::MemberId(4) << data.XNModelNode() + << eprosima::fastcdr::MemberId(5) << data.XNModelPro() + << eprosima::fastcdr::MemberId(6) << data.XNModelRunCnt() + << eprosima::fastcdr::MemberId(7) << data.XNMdlCurFreq() + << eprosima::fastcdr::MemberId(8) << data.XNMdlSetFreq() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + XNSim::XNSimStatus::XNModelStatus& data) +{ + using namespace XNSim::XNSimStatus; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.XNModelName(); + break; + + case 1: + dcdr >> data.XNModelID(); + break; + + case 2: + dcdr >> data.XNModelSt(); + break; + + case 3: + dcdr >> data.XNModelThID(); + break; + + case 4: + dcdr >> data.XNModelNode(); + break; + + case 5: + dcdr >> data.XNModelPro(); + break; + + case 6: + dcdr >> data.XNModelRunCnt(); + break; + + case 7: + dcdr >> data.XNMdlCurFreq(); + break; + + case 8: + dcdr >> data.XNMdlSetFreq(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimStatus::XNModelStatus& data) +{ + using namespace XNSim::XNSimStatus; + + static_cast(scdr); + static_cast(data); + scdr << data.XNModelName(); + + scdr << data.XNModelID(); + + scdr << data.XNModelSt(); + + scdr << data.XNModelThID(); + + scdr << data.XNModelNode(); + + scdr << data.XNModelPro(); + + scdr << data.XNModelRunCnt(); + + scdr << data.XNMdlCurFreq(); + + scdr << data.XNMdlSetFreq(); + +} + + +template<> +eProsima_user_DllExport size_t calculate_serialized_size( + eprosima::fastcdr::CdrSizeCalculator& calculator, + const XNSim::XNSimControl::XNRuntimeControl& data, + size_t& current_alignment) +{ + using namespace XNSim::XNSimControl; + + static_cast(data); + + eprosima::fastcdr::EncodingAlgorithmFlag previous_encoding = calculator.get_encoding(); + size_t calculated_size {calculator.begin_calculate_type_serialized_size( + eprosima::fastcdr::CdrVersion::XCDRv2 == calculator.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + current_alignment)}; + + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(0), + data.XNSimCmd(), current_alignment); + + calculated_size += calculator.calculate_member_serialized_size(eprosima::fastcdr::MemberId(1), + data.XNThrCmd(), current_alignment); + + + calculated_size += calculator.end_calculate_type_serialized_size(previous_encoding, current_alignment); + + return calculated_size; +} + +template<> +eProsima_user_DllExport void serialize( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimControl::XNRuntimeControl& data) +{ + using namespace XNSim::XNSimControl; + + eprosima::fastcdr::Cdr::state current_state(scdr); + scdr.begin_serialize_type(current_state, + eprosima::fastcdr::CdrVersion::XCDRv2 == scdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR); + + scdr + << eprosima::fastcdr::MemberId(0) << data.XNSimCmd() + << eprosima::fastcdr::MemberId(1) << data.XNThrCmd() +; + scdr.end_serialize_type(current_state); +} + +template<> +eProsima_user_DllExport void deserialize( + eprosima::fastcdr::Cdr& cdr, + XNSim::XNSimControl::XNRuntimeControl& data) +{ + using namespace XNSim::XNSimControl; + + cdr.deserialize_type(eprosima::fastcdr::CdrVersion::XCDRv2 == cdr.get_cdr_version() ? + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2 : + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR, + [&data](eprosima::fastcdr::Cdr& dcdr, const eprosima::fastcdr::MemberId& mid) -> bool + { + bool ret_value = true; + switch (mid.id) + { + case 0: + dcdr >> data.XNSimCmd(); + break; + + case 1: + dcdr >> data.XNThrCmd(); + break; + + default: + ret_value = false; + break; + } + return ret_value; + }); +} + +void serialize_key( + eprosima::fastcdr::Cdr& scdr, + const XNSim::XNSimControl::XNRuntimeControl& data) +{ + using namespace XNSim::XNSimControl; + + static_cast(scdr); + static_cast(data); + scdr << data.XNSimCmd(); + + scdr << data.XNThrCmd(); + +} + + + +} // namespace fastcdr +} // namespace eprosima + +#endif // FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_IPP + diff --git a/XNCore_Win/XNIDL/XNSimStatusPubSubTypes.cxx b/XNCore_Win/XNIDL/XNSimStatusPubSubTypes.cxx new file mode 100644 index 0000000..76390b5 --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatusPubSubTypes.cxx @@ -0,0 +1,955 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatusPubSubTypes.cpp + * This header file contains the implementation of the serialization functions. + * + * This file was generated by the tool fastddsgen. + */ + +#include "XNSimStatusPubSubTypes.hpp" + +#include +#include + +#include "XNSimStatusCdrAux.hpp" +#include "XNSimStatusTypeObjectSupport.hpp" + +using SerializedPayload_t = eprosima::fastdds::rtps::SerializedPayload_t; +using InstanceHandle_t = eprosima::fastdds::rtps::InstanceHandle_t; +using DataRepresentationId_t = eprosima::fastdds::dds::DataRepresentationId_t; + +namespace XNSim { + namespace XNSimStatus { + XNCoreStatusPubSubType::XNCoreStatusPubSubType() + { + set_name("XNSim::XNSimStatus::XNCoreStatus"); + uint32_t type_size = XNSim_XNSimStatus_XNCoreStatus_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; + uint32_t key_length = XNSim_XNSimStatus_XNCoreStatus_max_key_cdr_typesize > 16 ? XNSim_XNSimStatus_XNCoreStatus_max_key_cdr_typesize : 16; + key_buffer_ = reinterpret_cast(malloc(key_length)); + memset(key_buffer_, 0, key_length); + } + + XNCoreStatusPubSubType::~XNCoreStatusPubSubType() + { + if (key_buffer_ != nullptr) + { + free(key_buffer_); + } + } + + bool XNCoreStatusPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) + { + const XNCoreStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0,0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; + } + + bool XNCoreStatusPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) + { + try + { + // Convert DATA to pointer of your type + XNCoreStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; + } + + uint32_t XNCoreStatusPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) + { + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } + } + + void* XNCoreStatusPubSubType::create_data() + { + return reinterpret_cast(new XNCoreStatus()); + } + + void XNCoreStatusPubSubType::delete_data( + void* data) + { + delete(reinterpret_cast(data)); + } + + bool XNCoreStatusPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + XNCoreStatus data; + if (deserialize(payload, static_cast(&data))) + { + return compute_key(static_cast(&data), handle, force_md5); + } + + return false; + } + + bool XNCoreStatusPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + const XNCoreStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(key_buffer_), + XNSim_XNSimStatus_XNCoreStatus_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); + ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); + eprosima::fastcdr::serialize_key(ser, *p_type); + if (force_md5 || XNSim_XNSimStatus_XNCoreStatus_max_key_cdr_typesize > 16) + { + md5_.init(); + md5_.update(key_buffer_, static_cast(ser.get_serialized_data_length())); + md5_.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = key_buffer_[i]; + } + } + return true; + } + + void XNCoreStatusPubSubType::register_type_object_representation() + { + register_XNCoreStatus_type_identifier(type_identifiers_); + } + + XNEngineStatusPubSubType::XNEngineStatusPubSubType() + { + set_name("XNSim::XNSimStatus::XNEngineStatus"); + uint32_t type_size = XNSim_XNSimStatus_XNEngineStatus_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; + uint32_t key_length = XNSim_XNSimStatus_XNEngineStatus_max_key_cdr_typesize > 16 ? XNSim_XNSimStatus_XNEngineStatus_max_key_cdr_typesize : 16; + key_buffer_ = reinterpret_cast(malloc(key_length)); + memset(key_buffer_, 0, key_length); + } + + XNEngineStatusPubSubType::~XNEngineStatusPubSubType() + { + if (key_buffer_ != nullptr) + { + free(key_buffer_); + } + } + + bool XNEngineStatusPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) + { + const XNEngineStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0,0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; + } + + bool XNEngineStatusPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) + { + try + { + // Convert DATA to pointer of your type + XNEngineStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; + } + + uint32_t XNEngineStatusPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) + { + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } + } + + void* XNEngineStatusPubSubType::create_data() + { + return reinterpret_cast(new XNEngineStatus()); + } + + void XNEngineStatusPubSubType::delete_data( + void* data) + { + delete(reinterpret_cast(data)); + } + + bool XNEngineStatusPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + XNEngineStatus data; + if (deserialize(payload, static_cast(&data))) + { + return compute_key(static_cast(&data), handle, force_md5); + } + + return false; + } + + bool XNEngineStatusPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + const XNEngineStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(key_buffer_), + XNSim_XNSimStatus_XNEngineStatus_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); + ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); + eprosima::fastcdr::serialize_key(ser, *p_type); + if (force_md5 || XNSim_XNSimStatus_XNEngineStatus_max_key_cdr_typesize > 16) + { + md5_.init(); + md5_.update(key_buffer_, static_cast(ser.get_serialized_data_length())); + md5_.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = key_buffer_[i]; + } + } + return true; + } + + void XNEngineStatusPubSubType::register_type_object_representation() + { + register_XNEngineStatus_type_identifier(type_identifiers_); + } + + XNThreadStatusPubSubType::XNThreadStatusPubSubType() + { + set_name("XNSim::XNSimStatus::XNThreadStatus"); + uint32_t type_size = XNSim_XNSimStatus_XNThreadStatus_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; + uint32_t key_length = XNSim_XNSimStatus_XNThreadStatus_max_key_cdr_typesize > 16 ? XNSim_XNSimStatus_XNThreadStatus_max_key_cdr_typesize : 16; + key_buffer_ = reinterpret_cast(malloc(key_length)); + memset(key_buffer_, 0, key_length); + } + + XNThreadStatusPubSubType::~XNThreadStatusPubSubType() + { + if (key_buffer_ != nullptr) + { + free(key_buffer_); + } + } + + bool XNThreadStatusPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) + { + const XNThreadStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0,0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; + } + + bool XNThreadStatusPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) + { + try + { + // Convert DATA to pointer of your type + XNThreadStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; + } + + uint32_t XNThreadStatusPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) + { + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } + } + + void* XNThreadStatusPubSubType::create_data() + { + return reinterpret_cast(new XNThreadStatus()); + } + + void XNThreadStatusPubSubType::delete_data( + void* data) + { + delete(reinterpret_cast(data)); + } + + bool XNThreadStatusPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + XNThreadStatus data; + if (deserialize(payload, static_cast(&data))) + { + return compute_key(static_cast(&data), handle, force_md5); + } + + return false; + } + + bool XNThreadStatusPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + const XNThreadStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(key_buffer_), + XNSim_XNSimStatus_XNThreadStatus_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); + ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); + eprosima::fastcdr::serialize_key(ser, *p_type); + if (force_md5 || XNSim_XNSimStatus_XNThreadStatus_max_key_cdr_typesize > 16) + { + md5_.init(); + md5_.update(key_buffer_, static_cast(ser.get_serialized_data_length())); + md5_.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = key_buffer_[i]; + } + } + return true; + } + + void XNThreadStatusPubSubType::register_type_object_representation() + { + register_XNThreadStatus_type_identifier(type_identifiers_); + } + + XNModelStatusPubSubType::XNModelStatusPubSubType() + { + set_name("XNSim::XNSimStatus::XNModelStatus"); + uint32_t type_size = XNSim_XNSimStatus_XNModelStatus_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; + uint32_t key_length = XNSim_XNSimStatus_XNModelStatus_max_key_cdr_typesize > 16 ? XNSim_XNSimStatus_XNModelStatus_max_key_cdr_typesize : 16; + key_buffer_ = reinterpret_cast(malloc(key_length)); + memset(key_buffer_, 0, key_length); + } + + XNModelStatusPubSubType::~XNModelStatusPubSubType() + { + if (key_buffer_ != nullptr) + { + free(key_buffer_); + } + } + + bool XNModelStatusPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) + { + const XNModelStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0,0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; + } + + bool XNModelStatusPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) + { + try + { + // Convert DATA to pointer of your type + XNModelStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; + } + + uint32_t XNModelStatusPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) + { + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } + } + + void* XNModelStatusPubSubType::create_data() + { + return reinterpret_cast(new XNModelStatus()); + } + + void XNModelStatusPubSubType::delete_data( + void* data) + { + delete(reinterpret_cast(data)); + } + + bool XNModelStatusPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + XNModelStatus data; + if (deserialize(payload, static_cast(&data))) + { + return compute_key(static_cast(&data), handle, force_md5); + } + + return false; + } + + bool XNModelStatusPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + const XNModelStatus* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(key_buffer_), + XNSim_XNSimStatus_XNModelStatus_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); + ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); + eprosima::fastcdr::serialize_key(ser, *p_type); + if (force_md5 || XNSim_XNSimStatus_XNModelStatus_max_key_cdr_typesize > 16) + { + md5_.init(); + md5_.update(key_buffer_, static_cast(ser.get_serialized_data_length())); + md5_.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = key_buffer_[i]; + } + } + return true; + } + + void XNModelStatusPubSubType::register_type_object_representation() + { + register_XNModelStatus_type_identifier(type_identifiers_); + } + + } // namespace XNSimStatus + + namespace XNSimControl { + XNRuntimeControlPubSubType::XNRuntimeControlPubSubType() + { + set_name("XNSim::XNSimControl::XNRuntimeControl"); + uint32_t type_size = XNSim_XNSimControl_XNRuntimeControl_max_cdr_typesize; + type_size += static_cast(eprosima::fastcdr::Cdr::alignment(type_size, 4)); /* possible submessage alignment */ + max_serialized_type_size = type_size + 4; /*encapsulation*/ + is_compute_key_provided = false; + uint32_t key_length = XNSim_XNSimControl_XNRuntimeControl_max_key_cdr_typesize > 16 ? XNSim_XNSimControl_XNRuntimeControl_max_key_cdr_typesize : 16; + key_buffer_ = reinterpret_cast(malloc(key_length)); + memset(key_buffer_, 0, key_length); + } + + XNRuntimeControlPubSubType::~XNRuntimeControlPubSubType() + { + if (key_buffer_ != nullptr) + { + free(key_buffer_); + } + } + + bool XNRuntimeControlPubSubType::serialize( + const void* const data, + SerializedPayload_t& payload, + DataRepresentationId_t data_representation) + { + const XNRuntimeControl* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.max_size); + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 : eprosima::fastcdr::CdrVersion::XCDRv2); + payload.encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + ser.set_encoding_flag( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR : + eprosima::fastcdr::EncodingAlgorithmFlag::DELIMIT_CDR2); + + try + { + // Serialize encapsulation + ser.serialize_encapsulation(); + // Serialize the object. + ser << *p_type; + ser.set_dds_cdr_options({0,0}); + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + // Get the serialized length + payload.length = static_cast(ser.get_serialized_data_length()); + return true; + } + + bool XNRuntimeControlPubSubType::deserialize( + SerializedPayload_t& payload, + void* data) + { + try + { + // Convert DATA to pointer of your type + XNRuntimeControl* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(payload.data), payload.length); + + // Object that deserializes the data. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN); + + // Deserialize encapsulation. + deser.read_encapsulation(); + payload.encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + // Deserialize the object. + deser >> *p_type; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return false; + } + + return true; + } + + uint32_t XNRuntimeControlPubSubType::calculate_serialized_size( + const void* const data, + DataRepresentationId_t data_representation) + { + try + { + eprosima::fastcdr::CdrSizeCalculator calculator( + data_representation == DataRepresentationId_t::XCDR_DATA_REPRESENTATION ? + eprosima::fastcdr::CdrVersion::XCDRv1 :eprosima::fastcdr::CdrVersion::XCDRv2); + size_t current_alignment {0}; + return static_cast(calculator.calculate_serialized_size( + *static_cast(data), current_alignment)) + + 4u /*encapsulation*/; + } + catch (eprosima::fastcdr::exception::Exception& /*exception*/) + { + return 0; + } + } + + void* XNRuntimeControlPubSubType::create_data() + { + return reinterpret_cast(new XNRuntimeControl()); + } + + void XNRuntimeControlPubSubType::delete_data( + void* data) + { + delete(reinterpret_cast(data)); + } + + bool XNRuntimeControlPubSubType::compute_key( + SerializedPayload_t& payload, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + XNRuntimeControl data; + if (deserialize(payload, static_cast(&data))) + { + return compute_key(static_cast(&data), handle, force_md5); + } + + return false; + } + + bool XNRuntimeControlPubSubType::compute_key( + const void* const data, + InstanceHandle_t& handle, + bool force_md5) + { + if (!is_compute_key_provided) + { + return false; + } + + const XNRuntimeControl* p_type = static_cast(data); + + // Object that manages the raw buffer. + eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast(key_buffer_), + XNSim_XNSimControl_XNRuntimeControl_max_key_cdr_typesize); + + // Object that serializes the data. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS, eprosima::fastcdr::CdrVersion::XCDRv2); + ser.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR2); + eprosima::fastcdr::serialize_key(ser, *p_type); + if (force_md5 || XNSim_XNSimControl_XNRuntimeControl_max_key_cdr_typesize > 16) + { + md5_.init(); + md5_.update(key_buffer_, static_cast(ser.get_serialized_data_length())); + md5_.finalize(); + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = md5_.digest[i]; + } + } + else + { + for (uint8_t i = 0; i < 16; ++i) + { + handle.value[i] = key_buffer_[i]; + } + } + return true; + } + + void XNRuntimeControlPubSubType::register_type_object_representation() + { + register_XNRuntimeControl_type_identifier(type_identifiers_); + } + + } // namespace XNSimControl + +} // namespace XNSim + + +// Include auxiliary functions like for serializing/deserializing. +#include "XNSimStatusCdrAux.ipp" diff --git a/XNCore_Win/XNIDL/XNSimStatusPubSubTypes.hpp b/XNCore_Win/XNIDL/XNSimStatusPubSubTypes.hpp new file mode 100644 index 0000000..5b0fb1a --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatusPubSubTypes.hpp @@ -0,0 +1,456 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatusPubSubTypes.hpp + * This header file contains the declaration of the serialization functions. + * + * This file was generated by the tool fastddsgen. + */ + + +#ifndef FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_PUBSUBTYPES_HPP +#define FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_PUBSUBTYPES_HPP + +#include +#include +#include +#include +#include + +#include "XNSimStatus.hpp" + + +#if !defined(FASTDDS_GEN_API_VER) || (FASTDDS_GEN_API_VER != 3) +#error \ + Generated XNSimStatus is not compatible with current installed Fast DDS. Please, regenerate it with fastddsgen. +#endif // FASTDDS_GEN_API_VER + +namespace XNSim +{ + namespace XNSimStatus + { + + /*! + * @brief This class represents the TopicDataType of the type XNCoreStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ + class XNCoreStatusPubSubType : public eprosima::fastdds::dds::TopicDataType + { + public: + + typedef XNCoreStatus type; + + eProsima_user_DllExport XNCoreStatusPubSubType(); + + eProsima_user_DllExport ~XNCoreStatusPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return true; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + #ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + private: + + eprosima::fastdds::MD5 md5_; + unsigned char* key_buffer_; + + }; + + /*! + * @brief This class represents the TopicDataType of the type XNEngineStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ + class XNEngineStatusPubSubType : public eprosima::fastdds::dds::TopicDataType + { + public: + + typedef XNEngineStatus type; + + eProsima_user_DllExport XNEngineStatusPubSubType(); + + eProsima_user_DllExport ~XNEngineStatusPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + #ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + private: + + eprosima::fastdds::MD5 md5_; + unsigned char* key_buffer_; + + }; + + /*! + * @brief This class represents the TopicDataType of the type XNThreadStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ + class XNThreadStatusPubSubType : public eprosima::fastdds::dds::TopicDataType + { + public: + + typedef XNThreadStatus type; + + eProsima_user_DllExport XNThreadStatusPubSubType(); + + eProsima_user_DllExport ~XNThreadStatusPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + #ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + private: + + eprosima::fastdds::MD5 md5_; + unsigned char* key_buffer_; + + }; + + /*! + * @brief This class represents the TopicDataType of the type XNModelStatus defined by the user in the IDL file. + * @ingroup XNSimStatus + */ + class XNModelStatusPubSubType : public eprosima::fastdds::dds::TopicDataType + { + public: + + typedef XNModelStatus type; + + eProsima_user_DllExport XNModelStatusPubSubType(); + + eProsima_user_DllExport ~XNModelStatusPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + #ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + private: + + eprosima::fastdds::MD5 md5_; + unsigned char* key_buffer_; + + }; + } // namespace XNSimStatus + namespace XNSimControl + { + + /*! + * @brief This class represents the TopicDataType of the type XNRuntimeControl defined by the user in the IDL file. + * @ingroup XNSimStatus + */ + class XNRuntimeControlPubSubType : public eprosima::fastdds::dds::TopicDataType + { + public: + + typedef XNRuntimeControl type; + + eProsima_user_DllExport XNRuntimeControlPubSubType(); + + eProsima_user_DllExport ~XNRuntimeControlPubSubType() override; + + eProsima_user_DllExport bool serialize( + const void* const data, + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool deserialize( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + void* data) override; + + eProsima_user_DllExport uint32_t calculate_serialized_size( + const void* const data, + eprosima::fastdds::dds::DataRepresentationId_t data_representation) override; + + eProsima_user_DllExport bool compute_key( + eprosima::fastdds::rtps::SerializedPayload_t& payload, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport bool compute_key( + const void* const data, + eprosima::fastdds::rtps::InstanceHandle_t& ihandle, + bool force_md5 = false) override; + + eProsima_user_DllExport void* create_data() override; + + eProsima_user_DllExport void delete_data( + void* data) override; + + //Register TypeObject representation in Fast DDS TypeObjectRegistry + eProsima_user_DllExport void register_type_object_representation() override; + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + eProsima_user_DllExport inline bool is_bounded() const override + { + return true; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_BOUNDED + + #ifdef TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + eProsima_user_DllExport inline bool is_plain( + eprosima::fastdds::dds::DataRepresentationId_t data_representation) const override + { + static_cast(data_representation); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_IS_PLAIN + + #ifdef TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + eProsima_user_DllExport inline bool construct_sample( + void* memory) const override + { + static_cast(memory); + return false; + } + + #endif // TOPIC_DATA_TYPE_API_HAS_CONSTRUCT_SAMPLE + + private: + + eprosima::fastdds::MD5 md5_; + unsigned char* key_buffer_; + + }; + } // namespace XNSimControl +} // namespace XNSim + +#endif // FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_PUBSUBTYPES_HPP + diff --git a/XNCore_Win/XNIDL/XNSimStatusTypeObjectSupport.cxx b/XNCore_Win/XNIDL/XNSimStatusTypeObjectSupport.cxx new file mode 100644 index 0000000..06cf852 --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatusTypeObjectSupport.cxx @@ -0,0 +1,1214 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatusTypeObjectSupport.cxx + * Source file containing the implementation to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen. + */ + +#include "XNSimStatusTypeObjectSupport.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "XNSimStatus.hpp" + + +using namespace eprosima::fastdds::dds::xtypes; + +namespace XNSim { +namespace XNSimStatus { +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_XNCoreStatus_type_identifier( + TypeIdentifierPair& type_ids_XNCoreStatus) +{ + + ReturnCode_t return_code_XNCoreStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNCoreStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "XNSim::XNSimStatus::XNCoreStatus", type_ids_XNCoreStatus); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNCoreStatus) + { + StructTypeFlag struct_flags_XNCoreStatus = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + true, false); + QualifiedTypeName type_name_XNCoreStatus = "XNSim::XNSimStatus::XNCoreStatus"; + eprosima::fastcdr::optional type_ann_builtin_XNCoreStatus; + eprosima::fastcdr::optional ann_custom_XNCoreStatus; + AppliedAnnotationSeq tmp_ann_custom_XNCoreStatus; + eprosima::fastcdr::optional verbatim_XNCoreStatus; + if (!tmp_ann_custom_XNCoreStatus.empty()) + { + ann_custom_XNCoreStatus = tmp_ann_custom_XNCoreStatus; + } + + CompleteTypeDetail detail_XNCoreStatus = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_XNCoreStatus, ann_custom_XNCoreStatus, type_name_XNCoreStatus.to_string()); + CompleteStructHeader header_XNCoreStatus; + header_XNCoreStatus = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_XNCoreStatus); + CompleteStructMemberSeq member_seq_XNCoreStatus; + { + TypeIdentifierPair type_ids_XNFWStatus; + ReturnCode_t return_code_XNFWStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNFWStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNFWStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNFWStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNFWStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNFWStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNFWStatus = 0x00000000; + bool common_XNFWStatus_ec {false}; + CommonStructMember common_XNFWStatus {TypeObjectUtils::build_common_struct_member(member_id_XNFWStatus, member_flags_XNFWStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNFWStatus, common_XNFWStatus_ec))}; + if (!common_XNFWStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNFWStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNFWStatus = "XNFWStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNFWStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNFWStatus = TypeObjectUtils::build_complete_member_detail(name_XNFWStatus, member_ann_builtin_XNFWStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNFWStatus = TypeObjectUtils::build_complete_struct_member(common_XNFWStatus, detail_XNFWStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNFWStatus); + } + { + TypeIdentifierPair type_ids_XNTMStatus; + ReturnCode_t return_code_XNTMStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNTMStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNTMStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNTMStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNTMStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNTMStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNTMStatus = 0x00000001; + bool common_XNTMStatus_ec {false}; + CommonStructMember common_XNTMStatus {TypeObjectUtils::build_common_struct_member(member_id_XNTMStatus, member_flags_XNTMStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNTMStatus, common_XNTMStatus_ec))}; + if (!common_XNTMStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNTMStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNTMStatus = "XNTMStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNTMStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNTMStatus = TypeObjectUtils::build_complete_member_detail(name_XNTMStatus, member_ann_builtin_XNTMStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNTMStatus = TypeObjectUtils::build_complete_struct_member(common_XNTMStatus, detail_XNTMStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNTMStatus); + } + { + TypeIdentifierPair type_ids_XNEMStatus; + ReturnCode_t return_code_XNEMStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNEMStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNEMStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNEMStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNEMStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNEMStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNEMStatus = 0x00000002; + bool common_XNEMStatus_ec {false}; + CommonStructMember common_XNEMStatus {TypeObjectUtils::build_common_struct_member(member_id_XNEMStatus, member_flags_XNEMStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNEMStatus, common_XNEMStatus_ec))}; + if (!common_XNEMStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNEMStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNEMStatus = "XNEMStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNEMStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNEMStatus = TypeObjectUtils::build_complete_member_detail(name_XNEMStatus, member_ann_builtin_XNEMStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNEMStatus = TypeObjectUtils::build_complete_struct_member(common_XNEMStatus, detail_XNEMStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNEMStatus); + } + { + TypeIdentifierPair type_ids_XNSDStatus; + ReturnCode_t return_code_XNSDStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNSDStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNSDStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNSDStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSDStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNSDStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNSDStatus = 0x00000003; + bool common_XNSDStatus_ec {false}; + CommonStructMember common_XNSDStatus {TypeObjectUtils::build_common_struct_member(member_id_XNSDStatus, member_flags_XNSDStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNSDStatus, common_XNSDStatus_ec))}; + if (!common_XNSDStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNSDStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNSDStatus = "XNSDStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNSDStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNSDStatus = TypeObjectUtils::build_complete_member_detail(name_XNSDStatus, member_ann_builtin_XNSDStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNSDStatus = TypeObjectUtils::build_complete_struct_member(common_XNSDStatus, detail_XNSDStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNSDStatus); + } + { + TypeIdentifierPair type_ids_XNThMStatus; + ReturnCode_t return_code_XNThMStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThMStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThMStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThMStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThMStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThMStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThMStatus = 0x00000004; + bool common_XNThMStatus_ec {false}; + CommonStructMember common_XNThMStatus {TypeObjectUtils::build_common_struct_member(member_id_XNThMStatus, member_flags_XNThMStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThMStatus, common_XNThMStatus_ec))}; + if (!common_XNThMStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThMStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThMStatus = "XNThMStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNThMStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNThMStatus = TypeObjectUtils::build_complete_member_detail(name_XNThMStatus, member_ann_builtin_XNThMStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNThMStatus = TypeObjectUtils::build_complete_struct_member(common_XNThMStatus, detail_XNThMStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNThMStatus); + } + { + TypeIdentifierPair type_ids_XNMMStatus; + ReturnCode_t return_code_XNMMStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNMMStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNMMStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNMMStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNMMStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNMMStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNMMStatus = 0x00000005; + bool common_XNMMStatus_ec {false}; + CommonStructMember common_XNMMStatus {TypeObjectUtils::build_common_struct_member(member_id_XNMMStatus, member_flags_XNMMStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNMMStatus, common_XNMMStatus_ec))}; + if (!common_XNMMStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNMMStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNMMStatus = "XNMMStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNMMStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNMMStatus = TypeObjectUtils::build_complete_member_detail(name_XNMMStatus, member_ann_builtin_XNMMStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNMMStatus = TypeObjectUtils::build_complete_struct_member(common_XNMMStatus, detail_XNMMStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNMMStatus); + } + { + TypeIdentifierPair type_ids_XNSMStatus; + ReturnCode_t return_code_XNSMStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNSMStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNSMStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNSMStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSMStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNSMStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNSMStatus = 0x00000006; + bool common_XNSMStatus_ec {false}; + CommonStructMember common_XNSMStatus {TypeObjectUtils::build_common_struct_member(member_id_XNSMStatus, member_flags_XNSMStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNSMStatus, common_XNSMStatus_ec))}; + if (!common_XNSMStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNSMStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNSMStatus = "XNSMStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNSMStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNSMStatus = TypeObjectUtils::build_complete_member_detail(name_XNSMStatus, member_ann_builtin_XNSMStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNSMStatus = TypeObjectUtils::build_complete_struct_member(common_XNSMStatus, detail_XNSMStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNSMStatus); + } + { + TypeIdentifierPair type_ids_XNDMStatus; + ReturnCode_t return_code_XNDMStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNDMStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNDMStatus); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNDMStatus) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNDMStatus Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNDMStatus = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNDMStatus = 0x00000007; + bool common_XNDMStatus_ec {false}; + CommonStructMember common_XNDMStatus {TypeObjectUtils::build_common_struct_member(member_id_XNDMStatus, member_flags_XNDMStatus, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNDMStatus, common_XNDMStatus_ec))}; + if (!common_XNDMStatus_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNDMStatus member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNDMStatus = "XNDMStatus"; + eprosima::fastcdr::optional member_ann_builtin_XNDMStatus; + ann_custom_XNCoreStatus.reset(); + CompleteMemberDetail detail_XNDMStatus = TypeObjectUtils::build_complete_member_detail(name_XNDMStatus, member_ann_builtin_XNDMStatus, ann_custom_XNCoreStatus); + CompleteStructMember member_XNDMStatus = TypeObjectUtils::build_complete_struct_member(common_XNDMStatus, detail_XNDMStatus); + TypeObjectUtils::add_complete_struct_member(member_seq_XNCoreStatus, member_XNDMStatus); + } + CompleteStructType struct_type_XNCoreStatus = TypeObjectUtils::build_complete_struct_type(struct_flags_XNCoreStatus, header_XNCoreStatus, member_seq_XNCoreStatus); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_XNCoreStatus, type_name_XNCoreStatus.to_string(), type_ids_XNCoreStatus)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSim::XNSimStatus::XNCoreStatus already registered in TypeObjectRegistry for a different type."); + } + } +} +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_XNEngineStatus_type_identifier( + TypeIdentifierPair& type_ids_XNEngineStatus) +{ + + ReturnCode_t return_code_XNEngineStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNEngineStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "XNSim::XNSimStatus::XNEngineStatus", type_ids_XNEngineStatus); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNEngineStatus) + { + StructTypeFlag struct_flags_XNEngineStatus = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_XNEngineStatus = "XNSim::XNSimStatus::XNEngineStatus"; + eprosima::fastcdr::optional type_ann_builtin_XNEngineStatus; + eprosima::fastcdr::optional ann_custom_XNEngineStatus; + CompleteTypeDetail detail_XNEngineStatus = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_XNEngineStatus, ann_custom_XNEngineStatus, type_name_XNEngineStatus.to_string()); + CompleteStructHeader header_XNEngineStatus; + header_XNEngineStatus = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_XNEngineStatus); + CompleteStructMemberSeq member_seq_XNEngineStatus; + { + TypeIdentifierPair type_ids_XNEngineName; + ReturnCode_t return_code_XNEngineName {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNEngineName = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_XNEngineName); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNEngineName) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_XNEngineName)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_XNEngineName = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNEngineName = 0x00000000; + bool common_XNEngineName_ec {false}; + CommonStructMember common_XNEngineName {TypeObjectUtils::build_common_struct_member(member_id_XNEngineName, member_flags_XNEngineName, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNEngineName, common_XNEngineName_ec))}; + if (!common_XNEngineName_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNEngineName member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNEngineName = "XNEngineName"; + eprosima::fastcdr::optional member_ann_builtin_XNEngineName; + ann_custom_XNEngineStatus.reset(); + CompleteMemberDetail detail_XNEngineName = TypeObjectUtils::build_complete_member_detail(name_XNEngineName, member_ann_builtin_XNEngineName, ann_custom_XNEngineStatus); + CompleteStructMember member_XNEngineName = TypeObjectUtils::build_complete_struct_member(common_XNEngineName, detail_XNEngineName); + TypeObjectUtils::add_complete_struct_member(member_seq_XNEngineStatus, member_XNEngineName); + } + { + TypeIdentifierPair type_ids_XNEngineID; + ReturnCode_t return_code_XNEngineID {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNEngineID = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNEngineID); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNEngineID) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNEngineID Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNEngineID = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNEngineID = 0x00000001; + bool common_XNEngineID_ec {false}; + CommonStructMember common_XNEngineID {TypeObjectUtils::build_common_struct_member(member_id_XNEngineID, member_flags_XNEngineID, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNEngineID, common_XNEngineID_ec))}; + if (!common_XNEngineID_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNEngineID member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNEngineID = "XNEngineID"; + eprosima::fastcdr::optional member_ann_builtin_XNEngineID; + ann_custom_XNEngineStatus.reset(); + CompleteMemberDetail detail_XNEngineID = TypeObjectUtils::build_complete_member_detail(name_XNEngineID, member_ann_builtin_XNEngineID, ann_custom_XNEngineStatus); + CompleteStructMember member_XNEngineID = TypeObjectUtils::build_complete_struct_member(common_XNEngineID, detail_XNEngineID); + TypeObjectUtils::add_complete_struct_member(member_seq_XNEngineStatus, member_XNEngineID); + } + { + TypeIdentifierPair type_ids_XNEngineSt; + ReturnCode_t return_code_XNEngineSt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNEngineSt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNEngineSt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNEngineSt) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNEngineSt Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNEngineSt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNEngineSt = 0x00000002; + bool common_XNEngineSt_ec {false}; + CommonStructMember common_XNEngineSt {TypeObjectUtils::build_common_struct_member(member_id_XNEngineSt, member_flags_XNEngineSt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNEngineSt, common_XNEngineSt_ec))}; + if (!common_XNEngineSt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNEngineSt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNEngineSt = "XNEngineSt"; + eprosima::fastcdr::optional member_ann_builtin_XNEngineSt; + ann_custom_XNEngineStatus.reset(); + CompleteMemberDetail detail_XNEngineSt = TypeObjectUtils::build_complete_member_detail(name_XNEngineSt, member_ann_builtin_XNEngineSt, ann_custom_XNEngineStatus); + CompleteStructMember member_XNEngineSt = TypeObjectUtils::build_complete_struct_member(common_XNEngineSt, detail_XNEngineSt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNEngineStatus, member_XNEngineSt); + } + { + TypeIdentifierPair type_ids_XNEngineAff; + ReturnCode_t return_code_XNEngineAff {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNEngineAff = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNEngineAff); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNEngineAff) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNEngineAff Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNEngineAff = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNEngineAff = 0x00000003; + bool common_XNEngineAff_ec {false}; + CommonStructMember common_XNEngineAff {TypeObjectUtils::build_common_struct_member(member_id_XNEngineAff, member_flags_XNEngineAff, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNEngineAff, common_XNEngineAff_ec))}; + if (!common_XNEngineAff_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNEngineAff member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNEngineAff = "XNEngineAff"; + eprosima::fastcdr::optional member_ann_builtin_XNEngineAff; + ann_custom_XNEngineStatus.reset(); + CompleteMemberDetail detail_XNEngineAff = TypeObjectUtils::build_complete_member_detail(name_XNEngineAff, member_ann_builtin_XNEngineAff, ann_custom_XNEngineStatus); + CompleteStructMember member_XNEngineAff = TypeObjectUtils::build_complete_struct_member(common_XNEngineAff, detail_XNEngineAff); + TypeObjectUtils::add_complete_struct_member(member_seq_XNEngineStatus, member_XNEngineAff); + } + { + TypeIdentifierPair type_ids_XNThCnt; + ReturnCode_t return_code_XNThCnt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThCnt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThCnt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThCnt) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThCnt Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThCnt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThCnt = 0x00000004; + bool common_XNThCnt_ec {false}; + CommonStructMember common_XNThCnt {TypeObjectUtils::build_common_struct_member(member_id_XNThCnt, member_flags_XNThCnt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThCnt, common_XNThCnt_ec))}; + if (!common_XNThCnt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThCnt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThCnt = "XNThCnt"; + eprosima::fastcdr::optional member_ann_builtin_XNThCnt; + ann_custom_XNEngineStatus.reset(); + CompleteMemberDetail detail_XNThCnt = TypeObjectUtils::build_complete_member_detail(name_XNThCnt, member_ann_builtin_XNThCnt, ann_custom_XNEngineStatus); + CompleteStructMember member_XNThCnt = TypeObjectUtils::build_complete_struct_member(common_XNThCnt, detail_XNThCnt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNEngineStatus, member_XNThCnt); + } + { + TypeIdentifierPair type_ids_XNCoreSt; + ReturnCode_t return_code_XNCoreSt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNCoreSt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "XNSim::XNSimStatus::XNCoreStatus", type_ids_XNCoreSt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNCoreSt) + { + XNSim::XNSimStatus::register_XNCoreStatus_type_identifier(type_ids_XNCoreSt); + } + StructMemberFlag member_flags_XNCoreSt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNCoreSt = 0x00000005; + bool common_XNCoreSt_ec {false}; + CommonStructMember common_XNCoreSt {TypeObjectUtils::build_common_struct_member(member_id_XNCoreSt, member_flags_XNCoreSt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNCoreSt, common_XNCoreSt_ec))}; + if (!common_XNCoreSt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNCoreSt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNCoreSt = "XNCoreSt"; + eprosima::fastcdr::optional member_ann_builtin_XNCoreSt; + ann_custom_XNEngineStatus.reset(); + CompleteMemberDetail detail_XNCoreSt = TypeObjectUtils::build_complete_member_detail(name_XNCoreSt, member_ann_builtin_XNCoreSt, ann_custom_XNEngineStatus); + CompleteStructMember member_XNCoreSt = TypeObjectUtils::build_complete_struct_member(common_XNCoreSt, detail_XNCoreSt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNEngineStatus, member_XNCoreSt); + } + CompleteStructType struct_type_XNEngineStatus = TypeObjectUtils::build_complete_struct_type(struct_flags_XNEngineStatus, header_XNEngineStatus, member_seq_XNEngineStatus); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_XNEngineStatus, type_name_XNEngineStatus.to_string(), type_ids_XNEngineStatus)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSim::XNSimStatus::XNEngineStatus already registered in TypeObjectRegistry for a different type."); + } + } +} +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_XNThreadStatus_type_identifier( + TypeIdentifierPair& type_ids_XNThreadStatus) +{ + + ReturnCode_t return_code_XNThreadStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThreadStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "XNSim::XNSimStatus::XNThreadStatus", type_ids_XNThreadStatus); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThreadStatus) + { + StructTypeFlag struct_flags_XNThreadStatus = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_XNThreadStatus = "XNSim::XNSimStatus::XNThreadStatus"; + eprosima::fastcdr::optional type_ann_builtin_XNThreadStatus; + eprosima::fastcdr::optional ann_custom_XNThreadStatus; + CompleteTypeDetail detail_XNThreadStatus = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_XNThreadStatus, ann_custom_XNThreadStatus, type_name_XNThreadStatus.to_string()); + CompleteStructHeader header_XNThreadStatus; + header_XNThreadStatus = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_XNThreadStatus); + CompleteStructMemberSeq member_seq_XNThreadStatus; + { + TypeIdentifierPair type_ids_XNThreadName; + ReturnCode_t return_code_XNThreadName {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThreadName = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_XNThreadName); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThreadName) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_XNThreadName)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_XNThreadName = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThreadName = 0x00000000; + bool common_XNThreadName_ec {false}; + CommonStructMember common_XNThreadName {TypeObjectUtils::build_common_struct_member(member_id_XNThreadName, member_flags_XNThreadName, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThreadName, common_XNThreadName_ec))}; + if (!common_XNThreadName_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThreadName member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThreadName = "XNThreadName"; + eprosima::fastcdr::optional member_ann_builtin_XNThreadName; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThreadName = TypeObjectUtils::build_complete_member_detail(name_XNThreadName, member_ann_builtin_XNThreadName, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThreadName = TypeObjectUtils::build_complete_struct_member(common_XNThreadName, detail_XNThreadName); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThreadName); + } + { + TypeIdentifierPair type_ids_XNThreadID; + ReturnCode_t return_code_XNThreadID {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThreadID = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThreadID); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThreadID) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThreadID Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThreadID = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThreadID = 0x00000001; + bool common_XNThreadID_ec {false}; + CommonStructMember common_XNThreadID {TypeObjectUtils::build_common_struct_member(member_id_XNThreadID, member_flags_XNThreadID, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThreadID, common_XNThreadID_ec))}; + if (!common_XNThreadID_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThreadID member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThreadID = "XNThreadID"; + eprosima::fastcdr::optional member_ann_builtin_XNThreadID; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThreadID = TypeObjectUtils::build_complete_member_detail(name_XNThreadID, member_ann_builtin_XNThreadID, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThreadID = TypeObjectUtils::build_complete_struct_member(common_XNThreadID, detail_XNThreadID); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThreadID); + } + { + TypeIdentifierPair type_ids_XNThreadSt; + ReturnCode_t return_code_XNThreadSt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThreadSt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThreadSt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThreadSt) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThreadSt Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThreadSt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThreadSt = 0x00000002; + bool common_XNThreadSt_ec {false}; + CommonStructMember common_XNThreadSt {TypeObjectUtils::build_common_struct_member(member_id_XNThreadSt, member_flags_XNThreadSt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThreadSt, common_XNThreadSt_ec))}; + if (!common_XNThreadSt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThreadSt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThreadSt = "XNThreadSt"; + eprosima::fastcdr::optional member_ann_builtin_XNThreadSt; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThreadSt = TypeObjectUtils::build_complete_member_detail(name_XNThreadSt, member_ann_builtin_XNThreadSt, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThreadSt = TypeObjectUtils::build_complete_struct_member(common_XNThreadSt, detail_XNThreadSt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThreadSt); + } + { + TypeIdentifierPair type_ids_XNThreadAff; + ReturnCode_t return_code_XNThreadAff {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThreadAff = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThreadAff); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThreadAff) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThreadAff Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThreadAff = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThreadAff = 0x00000003; + bool common_XNThreadAff_ec {false}; + CommonStructMember common_XNThreadAff {TypeObjectUtils::build_common_struct_member(member_id_XNThreadAff, member_flags_XNThreadAff, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThreadAff, common_XNThreadAff_ec))}; + if (!common_XNThreadAff_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThreadAff member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThreadAff = "XNThreadAff"; + eprosima::fastcdr::optional member_ann_builtin_XNThreadAff; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThreadAff = TypeObjectUtils::build_complete_member_detail(name_XNThreadAff, member_ann_builtin_XNThreadAff, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThreadAff = TypeObjectUtils::build_complete_struct_member(common_XNThreadAff, detail_XNThreadAff); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThreadAff); + } + { + TypeIdentifierPair type_ids_XNThreadPro; + ReturnCode_t return_code_XNThreadPro {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThreadPro = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThreadPro); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThreadPro) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThreadPro Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThreadPro = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThreadPro = 0x00000004; + bool common_XNThreadPro_ec {false}; + CommonStructMember common_XNThreadPro {TypeObjectUtils::build_common_struct_member(member_id_XNThreadPro, member_flags_XNThreadPro, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThreadPro, common_XNThreadPro_ec))}; + if (!common_XNThreadPro_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThreadPro member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThreadPro = "XNThreadPro"; + eprosima::fastcdr::optional member_ann_builtin_XNThreadPro; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThreadPro = TypeObjectUtils::build_complete_member_detail(name_XNThreadPro, member_ann_builtin_XNThreadPro, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThreadPro = TypeObjectUtils::build_complete_struct_member(common_XNThreadPro, detail_XNThreadPro); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThreadPro); + } + { + TypeIdentifierPair type_ids_XNThRunCnt; + ReturnCode_t return_code_XNThRunCnt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThRunCnt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_uint64_t", type_ids_XNThRunCnt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThRunCnt) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThRunCnt Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThRunCnt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThRunCnt = 0x00000005; + bool common_XNThRunCnt_ec {false}; + CommonStructMember common_XNThRunCnt {TypeObjectUtils::build_common_struct_member(member_id_XNThRunCnt, member_flags_XNThRunCnt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThRunCnt, common_XNThRunCnt_ec))}; + if (!common_XNThRunCnt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThRunCnt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThRunCnt = "XNThRunCnt"; + eprosima::fastcdr::optional member_ann_builtin_XNThRunCnt; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThRunCnt = TypeObjectUtils::build_complete_member_detail(name_XNThRunCnt, member_ann_builtin_XNThRunCnt, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThRunCnt = TypeObjectUtils::build_complete_struct_member(common_XNThRunCnt, detail_XNThRunCnt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThRunCnt); + } + { + TypeIdentifierPair type_ids_XNThCurFreq; + ReturnCode_t return_code_XNThCurFreq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThCurFreq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_XNThCurFreq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThCurFreq) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThCurFreq Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThCurFreq = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThCurFreq = 0x00000006; + bool common_XNThCurFreq_ec {false}; + CommonStructMember common_XNThCurFreq {TypeObjectUtils::build_common_struct_member(member_id_XNThCurFreq, member_flags_XNThCurFreq, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThCurFreq, common_XNThCurFreq_ec))}; + if (!common_XNThCurFreq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThCurFreq member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThCurFreq = "XNThCurFreq"; + eprosima::fastcdr::optional member_ann_builtin_XNThCurFreq; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThCurFreq = TypeObjectUtils::build_complete_member_detail(name_XNThCurFreq, member_ann_builtin_XNThCurFreq, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThCurFreq = TypeObjectUtils::build_complete_struct_member(common_XNThCurFreq, detail_XNThCurFreq); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThCurFreq); + } + { + TypeIdentifierPair type_ids_XNThSetFreq; + ReturnCode_t return_code_XNThSetFreq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThSetFreq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_XNThSetFreq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThSetFreq) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThSetFreq Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThSetFreq = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThSetFreq = 0x00000007; + bool common_XNThSetFreq_ec {false}; + CommonStructMember common_XNThSetFreq {TypeObjectUtils::build_common_struct_member(member_id_XNThSetFreq, member_flags_XNThSetFreq, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThSetFreq, common_XNThSetFreq_ec))}; + if (!common_XNThSetFreq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThSetFreq member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThSetFreq = "XNThSetFreq"; + eprosima::fastcdr::optional member_ann_builtin_XNThSetFreq; + ann_custom_XNThreadStatus.reset(); + CompleteMemberDetail detail_XNThSetFreq = TypeObjectUtils::build_complete_member_detail(name_XNThSetFreq, member_ann_builtin_XNThSetFreq, ann_custom_XNThreadStatus); + CompleteStructMember member_XNThSetFreq = TypeObjectUtils::build_complete_struct_member(common_XNThSetFreq, detail_XNThSetFreq); + TypeObjectUtils::add_complete_struct_member(member_seq_XNThreadStatus, member_XNThSetFreq); + } + CompleteStructType struct_type_XNThreadStatus = TypeObjectUtils::build_complete_struct_type(struct_flags_XNThreadStatus, header_XNThreadStatus, member_seq_XNThreadStatus); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_XNThreadStatus, type_name_XNThreadStatus.to_string(), type_ids_XNThreadStatus)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSim::XNSimStatus::XNThreadStatus already registered in TypeObjectRegistry for a different type."); + } + } +} +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_XNModelStatus_type_identifier( + TypeIdentifierPair& type_ids_XNModelStatus) +{ + + ReturnCode_t return_code_XNModelStatus {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelStatus = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "XNSim::XNSimStatus::XNModelStatus", type_ids_XNModelStatus); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelStatus) + { + StructTypeFlag struct_flags_XNModelStatus = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_XNModelStatus = "XNSim::XNSimStatus::XNModelStatus"; + eprosima::fastcdr::optional type_ann_builtin_XNModelStatus; + eprosima::fastcdr::optional ann_custom_XNModelStatus; + CompleteTypeDetail detail_XNModelStatus = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_XNModelStatus, ann_custom_XNModelStatus, type_name_XNModelStatus.to_string()); + CompleteStructHeader header_XNModelStatus; + header_XNModelStatus = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_XNModelStatus); + CompleteStructMemberSeq member_seq_XNModelStatus; + { + TypeIdentifierPair type_ids_XNModelName; + ReturnCode_t return_code_XNModelName {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelName = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "anonymous_string_unbounded", type_ids_XNModelName); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelName) + { + { + SBound bound = 0; + StringSTypeDefn string_sdefn = TypeObjectUtils::build_string_s_type_defn(bound); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_s_string_type_identifier(string_sdefn, + "anonymous_string_unbounded", type_ids_XNModelName)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "anonymous_string_unbounded already registered in TypeObjectRegistry for a different type."); + } + } + } + StructMemberFlag member_flags_XNModelName = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelName = 0x00000000; + bool common_XNModelName_ec {false}; + CommonStructMember common_XNModelName {TypeObjectUtils::build_common_struct_member(member_id_XNModelName, member_flags_XNModelName, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelName, common_XNModelName_ec))}; + if (!common_XNModelName_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelName member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelName = "XNModelName"; + eprosima::fastcdr::optional member_ann_builtin_XNModelName; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelName = TypeObjectUtils::build_complete_member_detail(name_XNModelName, member_ann_builtin_XNModelName, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelName = TypeObjectUtils::build_complete_struct_member(common_XNModelName, detail_XNModelName); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelName); + } + { + TypeIdentifierPair type_ids_XNModelID; + ReturnCode_t return_code_XNModelID {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelID = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNModelID); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelID) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNModelID Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNModelID = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelID = 0x00000001; + bool common_XNModelID_ec {false}; + CommonStructMember common_XNModelID {TypeObjectUtils::build_common_struct_member(member_id_XNModelID, member_flags_XNModelID, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelID, common_XNModelID_ec))}; + if (!common_XNModelID_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelID member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelID = "XNModelID"; + eprosima::fastcdr::optional member_ann_builtin_XNModelID; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelID = TypeObjectUtils::build_complete_member_detail(name_XNModelID, member_ann_builtin_XNModelID, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelID = TypeObjectUtils::build_complete_struct_member(common_XNModelID, detail_XNModelID); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelID); + } + { + TypeIdentifierPair type_ids_XNModelSt; + ReturnCode_t return_code_XNModelSt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelSt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNModelSt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelSt) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNModelSt Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNModelSt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelSt = 0x00000002; + bool common_XNModelSt_ec {false}; + CommonStructMember common_XNModelSt {TypeObjectUtils::build_common_struct_member(member_id_XNModelSt, member_flags_XNModelSt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelSt, common_XNModelSt_ec))}; + if (!common_XNModelSt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelSt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelSt = "XNModelSt"; + eprosima::fastcdr::optional member_ann_builtin_XNModelSt; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelSt = TypeObjectUtils::build_complete_member_detail(name_XNModelSt, member_ann_builtin_XNModelSt, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelSt = TypeObjectUtils::build_complete_struct_member(common_XNModelSt, detail_XNModelSt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelSt); + } + { + TypeIdentifierPair type_ids_XNModelThID; + ReturnCode_t return_code_XNModelThID {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelThID = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNModelThID); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelThID) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNModelThID Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNModelThID = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelThID = 0x00000003; + bool common_XNModelThID_ec {false}; + CommonStructMember common_XNModelThID {TypeObjectUtils::build_common_struct_member(member_id_XNModelThID, member_flags_XNModelThID, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelThID, common_XNModelThID_ec))}; + if (!common_XNModelThID_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelThID member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelThID = "XNModelThID"; + eprosima::fastcdr::optional member_ann_builtin_XNModelThID; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelThID = TypeObjectUtils::build_complete_member_detail(name_XNModelThID, member_ann_builtin_XNModelThID, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelThID = TypeObjectUtils::build_complete_struct_member(common_XNModelThID, detail_XNModelThID); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelThID); + } + { + TypeIdentifierPair type_ids_XNModelNode; + ReturnCode_t return_code_XNModelNode {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelNode = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNModelNode); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelNode) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNModelNode Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNModelNode = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelNode = 0x00000004; + bool common_XNModelNode_ec {false}; + CommonStructMember common_XNModelNode {TypeObjectUtils::build_common_struct_member(member_id_XNModelNode, member_flags_XNModelNode, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelNode, common_XNModelNode_ec))}; + if (!common_XNModelNode_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelNode member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelNode = "XNModelNode"; + eprosima::fastcdr::optional member_ann_builtin_XNModelNode; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelNode = TypeObjectUtils::build_complete_member_detail(name_XNModelNode, member_ann_builtin_XNModelNode, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelNode = TypeObjectUtils::build_complete_struct_member(common_XNModelNode, detail_XNModelNode); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelNode); + } + { + TypeIdentifierPair type_ids_XNModelPro; + ReturnCode_t return_code_XNModelPro {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelPro = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNModelPro); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelPro) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNModelPro Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNModelPro = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelPro = 0x00000005; + bool common_XNModelPro_ec {false}; + CommonStructMember common_XNModelPro {TypeObjectUtils::build_common_struct_member(member_id_XNModelPro, member_flags_XNModelPro, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelPro, common_XNModelPro_ec))}; + if (!common_XNModelPro_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelPro member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelPro = "XNModelPro"; + eprosima::fastcdr::optional member_ann_builtin_XNModelPro; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelPro = TypeObjectUtils::build_complete_member_detail(name_XNModelPro, member_ann_builtin_XNModelPro, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelPro = TypeObjectUtils::build_complete_struct_member(common_XNModelPro, detail_XNModelPro); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelPro); + } + { + TypeIdentifierPair type_ids_XNModelRunCnt; + ReturnCode_t return_code_XNModelRunCnt {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNModelRunCnt = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_uint64_t", type_ids_XNModelRunCnt); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNModelRunCnt) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNModelRunCnt Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNModelRunCnt = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNModelRunCnt = 0x00000006; + bool common_XNModelRunCnt_ec {false}; + CommonStructMember common_XNModelRunCnt {TypeObjectUtils::build_common_struct_member(member_id_XNModelRunCnt, member_flags_XNModelRunCnt, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNModelRunCnt, common_XNModelRunCnt_ec))}; + if (!common_XNModelRunCnt_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNModelRunCnt member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNModelRunCnt = "XNModelRunCnt"; + eprosima::fastcdr::optional member_ann_builtin_XNModelRunCnt; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNModelRunCnt = TypeObjectUtils::build_complete_member_detail(name_XNModelRunCnt, member_ann_builtin_XNModelRunCnt, ann_custom_XNModelStatus); + CompleteStructMember member_XNModelRunCnt = TypeObjectUtils::build_complete_struct_member(common_XNModelRunCnt, detail_XNModelRunCnt); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNModelRunCnt); + } + { + TypeIdentifierPair type_ids_XNMdlCurFreq; + ReturnCode_t return_code_XNMdlCurFreq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNMdlCurFreq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_XNMdlCurFreq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNMdlCurFreq) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNMdlCurFreq Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNMdlCurFreq = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNMdlCurFreq = 0x00000007; + bool common_XNMdlCurFreq_ec {false}; + CommonStructMember common_XNMdlCurFreq {TypeObjectUtils::build_common_struct_member(member_id_XNMdlCurFreq, member_flags_XNMdlCurFreq, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNMdlCurFreq, common_XNMdlCurFreq_ec))}; + if (!common_XNMdlCurFreq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNMdlCurFreq member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNMdlCurFreq = "XNMdlCurFreq"; + eprosima::fastcdr::optional member_ann_builtin_XNMdlCurFreq; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNMdlCurFreq = TypeObjectUtils::build_complete_member_detail(name_XNMdlCurFreq, member_ann_builtin_XNMdlCurFreq, ann_custom_XNModelStatus); + CompleteStructMember member_XNMdlCurFreq = TypeObjectUtils::build_complete_struct_member(common_XNMdlCurFreq, detail_XNMdlCurFreq); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNMdlCurFreq); + } + { + TypeIdentifierPair type_ids_XNMdlSetFreq; + ReturnCode_t return_code_XNMdlSetFreq {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNMdlSetFreq = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_double", type_ids_XNMdlSetFreq); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNMdlSetFreq) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNMdlSetFreq Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNMdlSetFreq = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNMdlSetFreq = 0x00000008; + bool common_XNMdlSetFreq_ec {false}; + CommonStructMember common_XNMdlSetFreq {TypeObjectUtils::build_common_struct_member(member_id_XNMdlSetFreq, member_flags_XNMdlSetFreq, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNMdlSetFreq, common_XNMdlSetFreq_ec))}; + if (!common_XNMdlSetFreq_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNMdlSetFreq member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNMdlSetFreq = "XNMdlSetFreq"; + eprosima::fastcdr::optional member_ann_builtin_XNMdlSetFreq; + ann_custom_XNModelStatus.reset(); + CompleteMemberDetail detail_XNMdlSetFreq = TypeObjectUtils::build_complete_member_detail(name_XNMdlSetFreq, member_ann_builtin_XNMdlSetFreq, ann_custom_XNModelStatus); + CompleteStructMember member_XNMdlSetFreq = TypeObjectUtils::build_complete_struct_member(common_XNMdlSetFreq, detail_XNMdlSetFreq); + TypeObjectUtils::add_complete_struct_member(member_seq_XNModelStatus, member_XNMdlSetFreq); + } + CompleteStructType struct_type_XNModelStatus = TypeObjectUtils::build_complete_struct_type(struct_flags_XNModelStatus, header_XNModelStatus, member_seq_XNModelStatus); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_XNModelStatus, type_name_XNModelStatus.to_string(), type_ids_XNModelStatus)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSim::XNSimStatus::XNModelStatus already registered in TypeObjectRegistry for a different type."); + } + } +} + +} // namespace XNSimStatus +namespace XNSimControl { +// TypeIdentifier is returned by reference: dependent structures/unions are registered in this same method +void register_XNRuntimeControl_type_identifier( + TypeIdentifierPair& type_ids_XNRuntimeControl) +{ + + ReturnCode_t return_code_XNRuntimeControl {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNRuntimeControl = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "XNSim::XNSimControl::XNRuntimeControl", type_ids_XNRuntimeControl); + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNRuntimeControl) + { + StructTypeFlag struct_flags_XNRuntimeControl = TypeObjectUtils::build_struct_type_flag(eprosima::fastdds::dds::xtypes::ExtensibilityKind::APPENDABLE, + false, false); + QualifiedTypeName type_name_XNRuntimeControl = "XNSim::XNSimControl::XNRuntimeControl"; + eprosima::fastcdr::optional type_ann_builtin_XNRuntimeControl; + eprosima::fastcdr::optional ann_custom_XNRuntimeControl; + CompleteTypeDetail detail_XNRuntimeControl = TypeObjectUtils::build_complete_type_detail(type_ann_builtin_XNRuntimeControl, ann_custom_XNRuntimeControl, type_name_XNRuntimeControl.to_string()); + CompleteStructHeader header_XNRuntimeControl; + header_XNRuntimeControl = TypeObjectUtils::build_complete_struct_header(TypeIdentifier(), detail_XNRuntimeControl); + CompleteStructMemberSeq member_seq_XNRuntimeControl; + { + TypeIdentifierPair type_ids_XNSimCmd; + ReturnCode_t return_code_XNSimCmd {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNSimCmd = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNSimCmd); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNSimCmd) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSimCmd Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNSimCmd = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNSimCmd = 0x00000000; + bool common_XNSimCmd_ec {false}; + CommonStructMember common_XNSimCmd {TypeObjectUtils::build_common_struct_member(member_id_XNSimCmd, member_flags_XNSimCmd, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNSimCmd, common_XNSimCmd_ec))}; + if (!common_XNSimCmd_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNSimCmd member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNSimCmd = "XNSimCmd"; + eprosima::fastcdr::optional member_ann_builtin_XNSimCmd; + ann_custom_XNRuntimeControl.reset(); + CompleteMemberDetail detail_XNSimCmd = TypeObjectUtils::build_complete_member_detail(name_XNSimCmd, member_ann_builtin_XNSimCmd, ann_custom_XNRuntimeControl); + CompleteStructMember member_XNSimCmd = TypeObjectUtils::build_complete_struct_member(common_XNSimCmd, detail_XNSimCmd); + TypeObjectUtils::add_complete_struct_member(member_seq_XNRuntimeControl, member_XNSimCmd); + } + { + TypeIdentifierPair type_ids_XNThrCmd; + ReturnCode_t return_code_XNThrCmd {eprosima::fastdds::dds::RETCODE_OK}; + return_code_XNThrCmd = + eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->type_object_registry().get_type_identifiers( + "_int32_t", type_ids_XNThrCmd); + + if (eprosima::fastdds::dds::RETCODE_OK != return_code_XNThrCmd) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNThrCmd Structure member TypeIdentifier unknown to TypeObjectRegistry."); + return; + } + StructMemberFlag member_flags_XNThrCmd = TypeObjectUtils::build_struct_member_flag(eprosima::fastdds::dds::xtypes::TryConstructFailAction::DISCARD, + false, false, false, false); + MemberId member_id_XNThrCmd = 0x00000001; + bool common_XNThrCmd_ec {false}; + CommonStructMember common_XNThrCmd {TypeObjectUtils::build_common_struct_member(member_id_XNThrCmd, member_flags_XNThrCmd, TypeObjectUtils::retrieve_complete_type_identifier(type_ids_XNThrCmd, common_XNThrCmd_ec))}; + if (!common_XNThrCmd_ec) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, "Structure XNThrCmd member TypeIdentifier inconsistent."); + return; + } + MemberName name_XNThrCmd = "XNThrCmd"; + eprosima::fastcdr::optional member_ann_builtin_XNThrCmd; + ann_custom_XNRuntimeControl.reset(); + CompleteMemberDetail detail_XNThrCmd = TypeObjectUtils::build_complete_member_detail(name_XNThrCmd, member_ann_builtin_XNThrCmd, ann_custom_XNRuntimeControl); + CompleteStructMember member_XNThrCmd = TypeObjectUtils::build_complete_struct_member(common_XNThrCmd, detail_XNThrCmd); + TypeObjectUtils::add_complete_struct_member(member_seq_XNRuntimeControl, member_XNThrCmd); + } + CompleteStructType struct_type_XNRuntimeControl = TypeObjectUtils::build_complete_struct_type(struct_flags_XNRuntimeControl, header_XNRuntimeControl, member_seq_XNRuntimeControl); + if (eprosima::fastdds::dds::RETCODE_BAD_PARAMETER == + TypeObjectUtils::build_and_register_struct_type_object(struct_type_XNRuntimeControl, type_name_XNRuntimeControl.to_string(), type_ids_XNRuntimeControl)) + { + EPROSIMA_LOG_ERROR(XTYPES_TYPE_REPRESENTATION, + "XNSim::XNSimControl::XNRuntimeControl already registered in TypeObjectRegistry for a different type."); + } + } +} + +} // namespace XNSimControl + +} // namespace XNSim + diff --git a/XNCore_Win/XNIDL/XNSimStatusTypeObjectSupport.hpp b/XNCore_Win/XNIDL/XNSimStatusTypeObjectSupport.hpp new file mode 100644 index 0000000..e80a29a --- /dev/null +++ b/XNCore_Win/XNIDL/XNSimStatusTypeObjectSupport.hpp @@ -0,0 +1,117 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file XNSimStatusTypeObjectSupport.hpp + * Header file containing the API required to register the TypeObject representation of the described types in the IDL file + * + * This file was generated by the tool fastddsgen. + */ + +#ifndef FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_TYPE_OBJECT_SUPPORT_HPP +#define FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_TYPE_OBJECT_SUPPORT_HPP + +#include + + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif // EPROSIMA_USER_DLL_EXPORT +#else +#define eProsima_user_DllExport +#endif // _WIN32 + +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +namespace XNSim { +namespace XNSimStatus { +/** + * @brief Register XNCoreStatus related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_XNCoreStatus_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register XNEngineStatus related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_XNEngineStatus_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register XNThreadStatus related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_XNThreadStatus_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +/** + * @brief Register XNModelStatus related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_XNModelStatus_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +} // namespace XNSimStatus + +namespace XNSimControl { +/** + * @brief Register XNRuntimeControl related TypeIdentifier. + * Fully-descriptive TypeIdentifiers are directly registered. + * Hash TypeIdentifiers require to fill the TypeObject information and hash it, consequently, the TypeObject is + * indirectly registered as well. + * + * @param[out] TypeIdentifier of the registered type. + * The returned TypeIdentifier corresponds to the complete TypeIdentifier in case of hashed TypeIdentifiers. + * Invalid TypeIdentifier is returned in case of error. + */ +eProsima_user_DllExport void register_XNRuntimeControl_type_identifier( + eprosima::fastdds::dds::xtypes::TypeIdentifierPair& type_ids); + +} // namespace XNSimControl + +} // namespace XNSim + + +#endif // DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#endif // FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUS_TYPE_OBJECT_SUPPORT_HPP diff --git a/XNCore_Win/XNLogger/CMakeLists.txt b/XNCore_Win/XNLogger/CMakeLists.txt new file mode 100644 index 0000000..4d11e5d --- /dev/null +++ b/XNCore_Win/XNLogger/CMakeLists.txt @@ -0,0 +1,6 @@ +set(XNLOGGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNLogger.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNLogger.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNLOGGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNLogger/XNLogger.cpp b/XNCore_Win/XNLogger/XNLogger.cpp new file mode 100644 index 0000000..c3f0126 --- /dev/null +++ b/XNCore_Win/XNLogger/XNLogger.cpp @@ -0,0 +1,116 @@ +#include "XNLogger.h" + +namespace XNSim { + +XNLogger::XNLogger() + : consoleOutputEnabled{true, true, true, true}, + fileOutputEnabled{true, true, true, true} { + // 获取当前工作目录 + XN_PATH currentDir = getCurrentPath(); + XN_PATH logDirPath = currentDir / "log"; + + // 创建 log 文件夹 + if (!std::filesystem::exists(logDirPath)) { + std::filesystem::create_directories(logDirPath); + } + + // 创建以当前日期和时间命名的日志文件 + 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"; + + logFilePath = (logDirPath / logFileName).string(); + logFile.open(logFilePath, std::ios::app); +} + +XNLogger::~XNLogger() { + if (logFile.is_open()) { + logFile.close(); + } +} + +std::string XNLogger::getCurrentTimeString() const { + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + auto ms = std::chrono::duration_cast( + now.time_since_epoch()) % + 1000; + + std::stringstream ss; + ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S"); + ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); + return ss.str(); +} + +void XNLogger::log(LogLevel level, const std::string &message) { + std::lock_guard locker(mutex); + std::string logMessage = "[" + getCurrentTimeString() + "] [" + + logLevelToString(level) + "] " + message; + + std::string coloredMessage; + + // 根据日志等级设置颜色 + switch (level) { + case Debug: + coloredMessage = COLOR_DEBUG + logMessage + COLOR_RESET; + break; + case Info: + coloredMessage = COLOR_INFO + logMessage + COLOR_RESET; + break; + case Warning: + coloredMessage = COLOR_WARNING + logMessage + COLOR_RESET; + break; + case Error: + coloredMessage = COLOR_ERROR + logMessage + COLOR_RESET; + break; + default: + coloredMessage = logMessage; // 默认无颜色 + break; + } + + // 控制台输出 + if (consoleOutputEnabled[level]) { + if (level == Time) { + // 如果是时间日志,则不换行,回退到该行开始 + std::cout << coloredMessage << "\r" << std::flush; + } else { + std::cout << coloredMessage << std::endl; + } + } + + // 文件输出 + if (fileOutputEnabled[level] && logFile.is_open()) { + if (level == Time) { + logFile << logMessage << "\r" << std::flush; + } else { + logFile << logMessage << std::endl; + } + } +} + +void XNLogger::enableConsoleOutput(LogLevel level, bool enable) { + consoleOutputEnabled[level] = enable; +} + +void XNLogger::enableFileOutput(LogLevel level, bool enable) { + fileOutputEnabled[level] = enable; +} + +std::string XNLogger::logLevelToString(LogLevel level) const { + switch (level) { + case Debug: + return "DEBUG"; + case Info: + return "INFO"; + case Warning: + return "WARNING"; + case Error: + return "ERROR"; + case Time: + return "TIME"; + default: + return "UNKNOWN"; + } +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNLogger/XNLogger.h b/XNCore_Win/XNLogger/XNLogger.h new file mode 100644 index 0000000..0cdd18c --- /dev/null +++ b/XNCore_Win/XNLogger/XNLogger.h @@ -0,0 +1,247 @@ +/** + * @file XNLogger.h + * @author jinchao + * @brief 日志类 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ +#pragma once +#include + +namespace XNSim { +/** + * @brief 日志类 + */ +class XNLogger { +public: + /** + * @brief 日志等级 + */ + enum LogLevel { Debug, Info, Warning, Error, Time }; + + /** + * @brief 获取日志类实例 + * @return 日志类实例 + */ + static XNLogger &instance() { + static XNLogger instance; + return instance; + } + + /** + * @brief 日志输出 + * @param level 日志等级 + * @param message 日志消息 + */ + void log(LogLevel level, const XN_STRING &message); + + /** + * @brief 启用控制台输出 + * @param level 日志等级 + * @param enable 是否启用 + */ + void enableConsoleOutput(LogLevel level, XN_BOOL enable); + + /** + * @brief 启用文件输出 + * @param level 日志等级 + * @param enable 是否启用 + */ + void enableFileOutput(LogLevel level, XN_BOOL enable); + +private: + /** + * @brief 构造函数 + */ + XNLogger(); + + /** + * @brief 析构函数 + */ + ~XNLogger(); + + /** + * @brief 禁止拷贝构造 + */ + XNLogger(const XNLogger &) = delete; + + /** + * @brief 禁止赋值 + */ + XNLogger &operator=(const XNLogger &) = delete; + + /** + * @brief 日志文件路径 + */ + XN_STRING logFilePath; + + /** + * @brief 控制台输出控制 + */ + XN_BOOL consoleOutputEnabled[5]; + + /** + * @brief 文件输出控制 + */ + XN_BOOL fileOutputEnabled[5]; + + /** + * @brief 日志文件 + */ + XN_OFSTREAM logFile; + + /** + * @brief 互斥锁 + */ + XN_MUTEX mutex; + + /** + * @brief 日志等级转换为字符串 + * @param level 日志等级 + * @return 日志等级字符串 + */ + XN_STRING logLevelToString(LogLevel level) const; + + /** + * @brief 获取当前时间字符串 + * @return 格式化的时间字符串 + */ + XN_STRING getCurrentTimeString() const; + + /** + * @brief 控制台输出字体恢复颜色常量 + */ + const XN_STRING COLOR_RESET = "\033[0m"; + + /** + * @brief 调试颜色常量 + */ + const XN_STRING COLOR_DEBUG = "\033[34m"; // 蓝色 + + /** + * @brief 信息颜色常量 + */ + const XN_STRING COLOR_INFO = "\033[32m"; // 绿色 + + /** + * @brief 警告颜色常量 + */ + const XN_STRING COLOR_WARNING = "\033[33m"; // 黄色 + + /** + * @brief 错误颜色常量 + */ + const XN_STRING COLOR_ERROR = "\033[31m"; // 红色 +}; + +/** + * @brief 日志辅助类 + */ +class XNLoggerHelper { +public: + /** + * @brief 带参数的日志输出 + * @tparam Args 参数类型 + * @param level 日志等级 + * @param message 日志消息 + * @param args 参数 + */ + template + inline static typename std::enable_if<(sizeof...(Args) > 0), void>::type + log(XNLogger::LogLevel level, const XN_STRING &message, Args... args) { + XN_STRING formattedMessage = formatMessage(message, args...); + XNLogger::instance().log(level, formattedMessage); + } + + /** + * @brief 不带参数的日志输出 + * @param level 日志等级 + * @param message 日志消息 + */ + inline static void log(XNLogger::LogLevel level, const XN_STRING &message) { + XNLogger::instance().log(level, message); + } + +private: + /** + * @brief 将参数转换为字符串 + * @tparam T 参数类型 + * @param arg 要转换的参数 + * @return 转换后的字符串 + */ + template static XN_STRING convertToString(const T &arg) { + if constexpr (XNSim::is_arithmetic_v) { + return std::to_string(arg); // 处理数值类型 + } else if constexpr (XNSim::is_same_v) { + return arg; + } else if constexpr (XNSim::is_convertible_v) { + return XN_STRING(arg); + } else if constexpr (XNSim::is_same_v || + XNSim::is_same_v) { + return XN_STRING(arg); + } else { + static_assert(XNSim::is_arithmetic_v || + XNSim::is_same_v || + XNSim::is_convertible_v || + XNSim::is_same_v || + XNSim::is_same_v, + "A01021001: 不支持的类型转换,详见XNLogger.cpp:line 199"); + } + } + + /** + * @brief 格式化日志消息,顺序替换%1、%2、%3…… + * @tparam Args 参数类型 + * @param message 日志消息 + * @param args 参数包 + * @return 格式化后的消息 + */ + template + static XN_STRING formatMessage(const XN_STRING &message, Args &&...args) { + static_assert( + sizeof...(Args) <= 9, + "A01021002: 单条日志参数数量超过限制,详见XNLogger.cpp:line 216"); + + XN_STRING result = message; + // 使用初始化列表展开参数包 + int index = 1; + // 使用lambda和std::initializer_list展开参数包 + (void)std::initializer_list{( + [&result, &index](const auto &value) { + XN_STRING placeholder = "%" + ToXNString(index++); + size_t pos = result.find(placeholder); + if (pos != XN_STRING::npos) { + result.replace(pos, placeholder.length(), convertToString(value)); + } + }(args), + 0)...}; + return result; + } +}; +} // namespace XNSim +/** + * @brief 宏定义,用于输出调试日志 + */ +#define LOG_DEBUG(message, ...) \ + XNLoggerHelper::log(XNLogger::Debug, message, ##__VA_ARGS__) + +/** + * @brief 宏定义,用于输出信息日志 + */ +#define LOG_INFO(message, ...) \ + XNLoggerHelper::log(XNLogger::Info, message, ##__VA_ARGS__) + +/** + * @brief 宏定义,用于输出警告日志 + */ +#define LOG_WARNING(message, ...) \ + XNLoggerHelper::log(XNLogger::Warning, message, ##__VA_ARGS__) + +/** + * @brief 宏定义,用于输出错误日志 + */ +#define LOG_ERROR(message, ...) \ + XNLoggerHelper::log(XNLogger::Error, message, ##__VA_ARGS__) diff --git a/XNCore_Win/XNModelManager/CMakeLists.txt b/XNCore_Win/XNModelManager/CMakeLists.txt new file mode 100644 index 0000000..29723ed --- /dev/null +++ b/XNCore_Win/XNModelManager/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNMODELMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNModelManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNModelManager_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNModelManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNMODELMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNModelManager/XNModelManager.cpp b/XNCore_Win/XNModelManager/XNModelManager.cpp new file mode 100644 index 0000000..1516178 --- /dev/null +++ b/XNCore_Win/XNModelManager/XNModelManager.cpp @@ -0,0 +1,174 @@ +/** + * @file XNModelManager.cpp + * @author jinchao + * @brief 模型管理器类源文件 + * @version 1.0 + * @date 2024-11-06 + * + * @copyright Copyright (c) 2024 XN + * + */ +#include "XNModelManager.h" +#include "XNFramework/XNFramework.h" +#include "XNModelManager_p.h" +#include "XNModelObject/XNModelObject.h" +#include "XNThreadManager/XNThreadManager.h" + + +namespace XNSim { +// 构造函数 +XNModelManager::XNModelManager() + : XNBaseFrameObject(new XNModelManagerPrivate()) { + SetUniqueId(enumValue(XNCoreObjectID::ModelManager)); + SetObjectName("XNModelManager"); + T_D(); + d->ModelIDAssigned.resize(XN_MODEL_ID_SIZE, false); +} + +// 析构函数 +XNModelManager::~XNModelManager() {} + +XNModelManager::XNModelManager(PrivateType *p) : XNBaseFrameObject(p) {} + +// 运行前最后准备 +XN_BOOL XNModelManager::PrepareForExecute() { + T_D(); + for (auto &model : d->ModelMap) { + model.second->PrepareForExecute(); + } + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("XNModelManager is prepared!"); + return true; +} + +XN_BOOL XNModelManager::Initialize() { + T_D(); + LOG_INFO("XNModelManager Initialize Success!"); + d->_status = XNFrameObjectStatus::Initialized; + return true; +} + +void XNModelManager::LoadModel(const XN_STRING &modelPath, + const XN_STRING &className, + const XN_STRING &modelVersion, + const XN_STRING &planeName, + XN_UINT32 initialType, XN_UINT32 threadID) { + T_D(); + XN_HANDLE handle = loadLibrary(modelPath); + if (handle) { + typedef XNModelObjectPtr (*InitialModelFunc)(); + XN_STRING initialModelName = "Initial" + className; + InitialModelFunc initialModel = + (InitialModelFunc)getSymbol(handle, initialModelName.c_str()); + if (initialModel) { + XNModelObjectPtr model = initialModel(); + if (model) { + XN_UINT32 modelID = RegisterModel(); + if (modelID == 0) { + LOG_WARNING("0x2174 Assign Model ID Failed, Model ID is used up!"); + closeLibrary(handle); + return; + } + model->SetUniqueId(modelID); + model->SetObjectName(className); + model->SetFramework(GetFramework()); + model->SetInitializeType(initialType); + model->SetThreadID(threadID); + XN_STRING workPath = GetFramework()->GetWorkPath() + "/Packages/"; + model->SetLibPath(workPath); + if (initialType == 0) { + // 使用std::filesystem处理路径 + XN_PATH configPath = XN_PATH(modelPath).parent_path() / + (className + "_V" + modelVersion + ".mcfg"); + model->SetXmlPath(configPath.string()); + } else if (initialType == 1) { + model->SetXmlPath(planeName + "," + className + "," + modelVersion); + } + + // 注册模型到管理器 + d->ModelMap[modelID] = model; + + // 初始化模型 + model->Initialize(); + + // 注册到线程管理器 + if (threadID != 0) { + auto framework = GetFramework(); + if (framework) { + // 注册到线程管理器 (重复注册了,暂删除) + // framework->GetThreadManager()->RegisterFunction( + // modelID, std::bind(&XNModelObject::StepUpdate, model.get()), + // threadID, model->GetRunFreq(), model->GetRunNode(), + // model->GetRunPriority()); 设置模型设置频率 + XN_DOUBLE threadFreq = + framework->GetThreadManager()->GetThreadFreqByID(threadID); + XN_DOUBLE modelSetFreq = + threadFreq / (double)(1 << model->GetRunFreq()); + model->SetSetFreq(modelSetFreq); + } + } + } else { + LOG_WARNING("0x2173 Model %s Not found in dynamic link library %s!", + className.c_str(), modelPath.c_str()); + closeLibrary(handle); + return; + } + } else { + LOG_WARNING( + "0x2177 InitialModel function not found in dynamic link library %s!", + modelPath); + closeLibrary(handle); + return; + } + } else { + LOG_WARNING( + "0x2172 Model %s Dynamic link library loading failed! Error: %s", + className, LoadError()); + } +} + +// 模型注册 +XN_UINT32 XNModelManager::RegisterModel() { + T_D(); + // 从10000~19999的编号中分配ID + for (XN_UINT32 i = 0; i < XN_MODEL_ID_SIZE; i++) { + if (d->ModelIDAssigned[i]) + continue; + else { + d->ModelIDAssigned[i] = true; + return i + XN_MODEL_ID_START; + } + } + return 0; +} + +// 获取模型指针 +XNModelObjectPtr XNModelManager::GetModel(XN_UINT32 modelID) { + T_D(); + if (d->ModelIDAssigned[modelID - XN_MODEL_ID_START]) { + auto model = d->ModelMap.find(modelID); + if (model != d->ModelMap.end()) { + return model->second; + } + return nullptr; + } else + return nullptr; +} + +void XNModelManager::RegisterFunction(XN_UINT32 id, XNCallBack fun, + XN_UINT32 threadID, XN_UINT32 freqGroup, + XN_UINT32 RunPos, XN_UINT32 RunPriorty) { + T_D(); + if (d->ModelIDAssigned[id - 10000]) { + auto framework = GetFramework(); + if (framework) { + framework->GetThreadManager()->RegisterFunction( + id, fun, threadID, freqGroup, RunPos, RunPriorty); + } + } else { + LOG_WARNING("0x2177 Submission of periodic function was rejected, model ID " + "%1 is not registered!", + id); + } +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNModelManager/XNModelManager.h b/XNCore_Win/XNModelManager/XNModelManager.h new file mode 100644 index 0000000..d4397f4 --- /dev/null +++ b/XNCore_Win/XNModelManager/XNModelManager.h @@ -0,0 +1,99 @@ +/** + * @file XNModelManager.h + * @author jinchao + * @brief 模型管理器类头文件 + * @version 1.0 + * @date 2024-11-06 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject.h" + +namespace XNSim { +struct XNModelManagerPrivate; + +/** + * @brief 模型管理器类 + * @details + * 用于管理仿真系统中所有加载的模型,为模型分配唯一ID。其它组件或模型可以通过该唯一ID访问或控制该模型。 + */ +class XNModelManager : public XNBaseFrameObject { + XN_METATYPE(XNModelManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNModelManager) + +public: + /** + * @brief 模型管理器类默认构造函数 + */ + XNModelManager(); + + /** + * @brief 模型管理器类默认析构函数 + */ + virtual ~XNModelManager(); + +protected: + /** + * @brief 模型管理器带参构造函数 + * @param p:私有结构体指针 + * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 + */ + XNModelManager(PrivateType *p); + +public: + /** + * @brief 系统开始运行前的最后准备工作 + * @details 系统运行前模型管理器做最后处理的接口 + */ + virtual XN_BOOL PrepareForExecute() override; + + /** + * @brief 初始化模型管理器 + * @details 模型管理器的初始化接口 + */ + virtual XN_BOOL Initialize() override; + + /** + * @brief 加载模型 + * @param modelPath: QString类型,模型动态链接库路径 + * @param className: QString类型,模型类名 + * @param modelVersion: QString类型,模型版本号 + * @param initialType: UINT32类型,初始化类型 + * @param threadID: UINT32类型,线程ID + * @details 加载模型 + */ + void LoadModel(const XN_STRING &modelPath, const XN_STRING &className, + const XN_STRING &modelVersion, const XN_STRING &planeName, + XN_UINT32 initialType, XN_UINT32 threadID); + + /** + * @brief 注册模型信息 + * @return UINT32: 模型的全局唯一ID + * @details 模型通过此接口注册自身,并获取自身全局唯一ID + */ + uint32_t RegisterModel(); + + /** + * @brief 获取模型指针 + * @param modelID: UINT32类型,模型全局唯一ID + * @return XNModelObjectPtr: 模型基类指针 + */ + XNModelObjectPtr GetModel(XN_UINT32 modelID); + + /** + * @brief 注册模型函数 + * @param ModelID: UINT32类型,模型全局唯一ID + * @param fun: 函数指针 + * @param freqGroup: + * UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 + * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) + * @param RunPriorty: + * UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 + */ + void RegisterFunction(XN_UINT32 id, XNCallBack fun, XN_UINT32 threadID, + XN_UINT32 freqGroup, XN_UINT32 RunPos, + XN_UINT32 RunPriorty); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNModelManager/XNModelManager_p.h b/XNCore_Win/XNModelManager/XNModelManager_p.h new file mode 100644 index 0000000..8e2fa6c --- /dev/null +++ b/XNCore_Win/XNModelManager/XNModelManager_p.h @@ -0,0 +1,19 @@ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject_p.h" + +namespace XNSim { +using XNModelMap = std::map; + +struct XNModelManagerPrivate : public XNBaseFrameObjectPrivate { + /** + * @brief 模型ID库 + * @details 所有模型已用ID的存储库 + */ + XNAsignedIDFlag ModelIDAssigned; + /** + * @brief 模型ID与模型指针的映射表 + * @details 所有模型ID与模型指针的映射表 + */ + XNModelMap ModelMap; +}; +} // namespace XNSim diff --git a/XNCore_Win/XNModelObject/CMakeLists.txt b/XNCore_Win/XNModelObject/CMakeLists.txt new file mode 100644 index 0000000..c3e25ba --- /dev/null +++ b/XNCore_Win/XNModelObject/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNMODELOBJECT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNModelObject.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNModelObject_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNModelObject.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNMODELOBJECT_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNModelObject/XNModelObject.cpp b/XNCore_Win/XNModelObject/XNModelObject.cpp new file mode 100644 index 0000000..ee9efa9 --- /dev/null +++ b/XNCore_Win/XNModelObject/XNModelObject.cpp @@ -0,0 +1,478 @@ +/** + * @file XNModelObject.cpp + * @author jinchao + * @brief 模型基类源文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#include "XNModelObject.h" +#include "XNDDSManager/XNDDSManager.h" +#include "XNFramework/XNFramework.h" +#include "XNIDL/XNSimStatusPubSubTypes.hpp" +#include "XNModelManager/XNModelManager.h" +#include "XNModelObject_p.h" +#include "XNThreadManager/XNThreadManager.h" + +namespace XNSim { +// 默认构造函数 +XNModelObject::XNModelObject() : XNObject(new XNModelObjectPrivate()) {} + +// 默认析构函数 +XNModelObject::~XNModelObject() {} + +XNModelObject::XNModelObject(PrivateType *p) : XNObject(p) {} + +void XNModelObject::SetFramework(XNFrameworkPtr framework) { + T_D(); + d->_framework = framework; +} + +XNFrameworkPtr XNModelObject::GetFramework() const { + T_D(); + return d->_framework; +} + +// 获取模型描述 +const XN_STRING &XNModelObject::GetDescription() { + T_D(); + return d->_sDescription; +} + +// 设置模型描述 +void XNModelObject::SetDescription(const XN_STRING &sDescription) { + T_D(); + d->_sDescription = sDescription; +} + +// 获取作者 +const XN_STRING &XNModelObject::GetAuthor() { + T_D(); + return d->_sAuthor; +} + +// 设置作者 +void XNModelObject::SetAuthor(const XN_STRING &sAuthor) { + T_D(); + d->_sAuthor = sAuthor; +} + +// 获取模型配置文件路径 +const XN_STRING &XNModelObject::GetXmlPath() { + T_D(); + return d->_sXmlPath; +} + +// 设置模型配置文件路径 +void XNModelObject::SetXmlPath(const XN_STRING &sXmlPath) { + T_D(); + d->_sXmlPath = sXmlPath; +} + +// 获取模型创建时间 +const XNTimePoint &XNModelObject::GetCreateTime() { + T_D(); + return d->_cCreatTime; +} + +// 设置模型创建时间 +void XNModelObject::SetCreateTime(const XNTimePoint &cTime) { + T_D(); + d->_cCreatTime = cTime; +} + +// 获取模型修改时间 +const XNTimePoint &XNModelObject::GetChangeTime() { + T_D(); + return d->_cChangeTime; +} + +// 设置模型修改时间 +void XNModelObject::SetChangeTime(const XNTimePoint &cTime) { + T_D(); + d->_cChangeTime = cTime; +} + +// 获取模型版本号 +const XN_STRING &XNModelObject::GetVersion() { + T_D(); + return d->_sVersion; +} + +// 设置模型版本号 +void XNModelObject::SetVersion(const XN_STRING &sVersion) { + T_D(); + d->_sVersion = sVersion; +} + +void XNModelObject::SetInitializeType(XN_UINT32 initialType) { + T_D(); + d->_initialType = initialType; +} + +void XNModelObject::SetThreadID(XN_UINT32 threadID) { + T_D(); + d->_threadID = threadID; +} + +XN_UINT32 XNModelObject::GetThreadID() const { + T_D(); + return d->_threadID; +} + +XN_UINT32 XNModelObject::GetRunFreq() const { + T_D(); + return d->_runFreq; +} + +void XNModelObject::SetRunFreq(XN_UINT32 runFreq) { + T_D(); + d->_runFreq = runFreq; +} + +XN_UINT32 XNModelObject::GetRunNode() const { + T_D(); + return d->_runNode; +} + +void XNModelObject::SetRunNode(XN_UINT32 runNode) { + T_D(); + d->_runNode = runNode; +} + +XN_UINT32 XNModelObject::GetRunPriority() const { + T_D(); + return d->_runPriority; +} + +void XNModelObject::SetRunPriority(XN_UINT32 runPriority) { + T_D(); + d->_runPriority = runPriority; +} + +XN_DOUBLE XNModelObject::GetSetFreq() const { + T_D(); + return d->_setFreq; +} + +void XNModelObject::SetSetFreq(XN_DOUBLE setFreq) { + T_D(); + d->_setFreq = setFreq; +} + +const XN_STRING &XNModelObject::GetLibPath() { + T_D(); + return d->_sLibPath; +} + +void XNModelObject::SetLibPath(const XN_STRING &sLibPath) { + T_D(); + d->_sLibPath = sLibPath; +} + +// 初始化函数 +void XNModelObject::Initialize() { + T_D(); + if (d->_initialType == 0) { + ParseXml(); + } else { + ParseConfig(); + } +} + +void XNModelObject::ParseXml() { + T_D(); + // 读取配置文件,设置循环执行函数 + XN_XMLDocument doc; + if (LoadXmlFile(GetXmlPath(), doc) != 0) { + LOG_WARNING("0x2161 Failed to parse model configuration file: %1!", + GetXmlPath()); + return; + } + + XN_XMLElement *rootNode = GetRootElement(doc); + if (!rootNode) { + LOG_WARNING("0x2161 Failed to parse model configuration file: %1!", + GetXmlPath()); + return; + } + // 读取配置文件的模型参数 + XN_STRING modelName = GetFirstChildElementText(rootNode, "Name"); + if (modelName.empty() || 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.empty() ? "null" : modelName); + return; + } + d->_sDescription = GetFirstChildElementText(rootNode, "Description"); + d->_sAuthor = GetFirstChildElementText(rootNode, "Author"); + d->_sVersion = GetFirstChildElementText(rootNode, "Version"); + + // 使用标准C++时间处理 + XN_STRING createTimeStr = GetFirstChildElementText(rootNode, "CreateTime"); + XN_STRING changeTimeStr = GetFirstChildElementText(rootNode, "ChangeTime"); + d->_cCreatTime = parseISOTime(createTimeStr); + d->_cChangeTime = parseISOTime(changeTimeStr); + + XN_STRING funcNode = GetFirstChildElementText(rootNode, "Node"); + d->_runPriority = XNSafe_stoi(GetFirstChildElementText(rootNode, "Priority")); + + // 检查运行节点是否是 "x-x" 形式 + XN_SIZE 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 = XNSafe_stoi(funcNode.substr(0, tmp)); + d->_runNode = XNSafe_stoi(funcNode.substr(tmp + 1)); + + // 注册周期性函数 + auto framework = GetFramework(); + if (framework) { + auto threadManager = framework->GetThreadManager(); + if (threadManager) { + threadManager->RegisterFunction( + GetUniqueId(), std::bind(&XNModelObject::StepUpdate, this), + d->_threadID, d->_runFreq, d->_runNode, d->_runPriority); + } + } + + // 加载动态库 + XN_STRING mathlib = GetFirstChildElementText(rootNode, "MathLib"); + if (!mathlib.empty()) { + // 使用标准C++文件路径处理 + XN_PATH xmlPath(GetXmlPath()); + d->_sLibPath = xmlPath.parent_path().string() + "/" + mathlib; + + // 使用标准C++动态库加载 + d->_dynamicLib = loadLibrary(d->_sLibPath); + if (d->_dynamicLib) { // 动态库加载成功 + LOG_INFO( + "0x2163 Model %1 loaded algorithm dynamic library %2 successfully!", + GetObjectName(), d->_sLibPath); + } else { + LOG_WARNING("0x2160 Model %1 failed to find algorithm dynamic library " + "%2, will not call " + "algorithm!", + GetObjectName(), d->_sLibPath); + d->_dynamicLib = nullptr; + } + } + + // 处理指令列表 + XN_XMLElement *nodeCmds = GetFirstChildElement(rootNode, "CommandList"); + if (nodeCmds) { + for (XN_XMLElement *nodeCmd = GetFirstChildElement(nodeCmds, "Command"); + nodeCmd != nullptr; + nodeCmd = GetNextSiblingElement(nodeCmd, "Command")) { + XN_STRING cmdName = GetAttribute(nodeCmd, "Name"); + XN_STRING cmdDescription = GetAttribute(nodeCmd, "Description"); + XN_STRING cmdCall = GetAttribute(nodeCmd, "Call"); + // TODO: 处理命令列表 + } + } +} + +void XNModelObject::ParseConfig() { + T_D(); + XN_STRINGLIST nameAndVersion = XNSplit(GetXmlPath(), ","); + XN_STRING planeName = nameAndVersion[0]; + XN_STRING modelName = nameAndVersion[1]; + XN_STRING modelVersion = nameAndVersion[2]; + // 获取数据库路径 + XN_STRING dbPath = getEnv("XNCore"); + if (dbPath.empty()) { + LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!"); + return; + } + dbPath += "/database/XNSim.db"; + + // 打开数据库 + XN_DB_PTR db = openDatabase(dbPath); + if (db == nullptr) { + LOG_ERROR("0x1016 打开数据库失败: %1", sqlite3_errmsg(db)); + return; + } + + // 准备SQL语句 + XN_STRING sql = "SELECT * FROM XNModelsVersion WHERE PlaneName = ? AND " + "ClassName = ? AND Version = ?"; + XN_DB_STMT_PTR stmt = prepareSql(db, sql); + if (stmt == nullptr) { + LOG_ERROR("0x1017 准备SQL语句失败: %1", sqlite3_errmsg(db)); + closeDatabase(db); + return; + } + + // 绑定参数 + if (!bindText(stmt, 1, planeName) || !bindText(stmt, 2, modelName) || + !bindText(stmt, 3, modelVersion)) { + LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db)); + finalizeSql(stmt); + closeDatabase(db); + return; + } + + // 执行查询 + if (!stepSql(stmt)) { + LOG_ERROR("0x1019 未找到机型为%1,模型名称为%2,版本号%3的记录", + planeName.c_str(), modelName.c_str(), modelVersion.c_str()); + finalizeSql(stmt); + closeDatabase(db); + return; + } + + d->_sDescription = getStringFromSqlite3(stmt, 7); + d->_sAuthor = getStringFromSqlite3(stmt, 6); + d->_sVersion = getStringFromSqlite3(stmt, 2); + + // 解析时间 + XN_STRING createTimeStr = getStringFromSqlite3(stmt, 8); + XN_STRING changeTimeStr = getStringFromSqlite3(stmt, 9); + d->_cCreatTime = parseISOTime(createTimeStr); + d->_cChangeTime = parseISOTime(changeTimeStr); + d->_runFreq = XNSafe_stoi(getStringFromSqlite3(stmt, 10)); + d->_runNode = XNSafe_stoi(getStringFromSqlite3(stmt, 11)); + d->_runPriority = XNSafe_stoi(getStringFromSqlite3(stmt, 12)); + + // 注册周期性函数 + auto framework = GetFramework(); + if (framework) { + auto threadManager = framework->GetThreadManager(); + if (threadManager) { + threadManager->RegisterFunction( + GetUniqueId(), std::bind(&XNModelObject::StepUpdate, this), + d->_threadID, d->_runFreq, d->_runNode, d->_runPriority); + } + } + + // 加载动态库 + XN_STRING mathlib = getStringFromSqlite3(stmt, 13); + if (mathlib.length() > 0) { + // 使用标准C++文件路径处理 + // std::filesystem::path xmlPath(GetXmlPath()); + // d->_sLibPath = xmlPath.parent_path().string() + "/" + mathlib; + XN_STRING libPath = d->_sLibPath + "/" + mathlib; + // 使用标准C++动态库加载 + d->_dynamicLib = loadLibrary(libPath); + if (d->_dynamicLib) { // 动态库加载成功 + LOG_INFO("0x2163 模型 %1 加载数据包模型动态库 %2 成功!", GetObjectName(), + libPath); + } else { + LOG_WARNING( + "0x2160 模型 %1 未找到数据包模型动态库 %2, 将不调用数据包模型!", + GetObjectName(), libPath); + d->_dynamicLib = nullptr; + } + } + + // TODO: 读取模型命令列表 + // 清理资源 + finalizeSql(stmt); + closeDatabase(db); +} + +// 单步执行函数 +void XNModelObject::StepUpdate() { + T_D(); + XN_UINT32 setFreq = d->_setFreq < 1.0 ? 1 : (XN_UINT32)d->_setFreq; + if (d->_dataWriter != nullptr && d->_runCnt > 0 && + d->_runCnt % setFreq == 0) { + XNSim::XNSimStatus::XNModelStatus modelStatus; + modelStatus.XNModelName(GetObjectName()); + modelStatus.XNModelID(GetUniqueId()); + modelStatus.XNModelSt(1); + modelStatus.XNModelThID(d->_threadID); + modelStatus.XNModelNode(d->_runNode); + modelStatus.XNModelPro(d->_runPriority); + modelStatus.XNModelRunCnt(d->_runCnt); + XN_TIMESPEC now; + getCurrentRTTime(&now); + double time_diff = calculateRTTime(&now, &d->_lastRunTime); + modelStatus.XNMdlCurFreq(d->_setFreq / time_diff); + modelStatus.XNMdlSetFreq(d->_setFreq); + d->_dataWriter->write(&modelStatus); + d->_lastRunTime = now; + LOG_DEBUG("Model: %1 Write DDS!", GetObjectName()); + } + d->_runCnt++; +} + +// 运行前最后准备函数 +void XNModelObject::PrepareForExecute() { + T_D(); + d->_runCnt = 0; + // 注册DDS + RegisterDDSParticipant(); + getCurrentRTTime(&d->_lastRunTime); +} + +void XNModelObject::RegisterDDSParticipant() { + T_D(); + auto framework = GetFramework(); + if (framework == nullptr) { + LOG_WARNING("Failed to get Framework!"); + return; + } + auto ddsManager = framework->GetDDSManager(); + if (ddsManager == nullptr) { + LOG_WARNING("Failed to get DDSManager!"); + return; + } + XN_UINT32 MyID = GetUniqueId(); + d->_dataWriter = + ddsManager + ->RegisterPublisher( + "XNSim::XNSimStatus::XNModelStatus", MyID); +} + +XN_INT32 XNModelObject::RegisterEventHandler(const XN_STRING &eventName, + XNEventCallback callback, + bool async, + XNEvent::Priority priority) { + // 获取事件管理器 + auto framework = GetFramework(); + if (framework == nullptr) { + LOG_WARNING("Failed to get Framework!"); + return -1; + } + + XNEventManagerPtr eventManager = framework->GetEventManager(); + if (eventManager == nullptr) { + LOG_WARNING("Failed to get EventManager!"); + return -1; + } + + // 注册事件处理器 + return eventManager->RegisterEventHandler(eventName, callback, GetUniqueId(), + async, priority); +} + +void XNModelObject::TriggerEvent(const XN_STRING &eventName, + const XN_ANY &eventData, XN_BOOL forceAsync, + XNEvent::Priority priority) { + // 获取事件管理器 + auto framework = GetFramework(); + if (framework == nullptr) { + LOG_WARNING("Failed to get Framework!"); + return; + } + + XNEventManagerPtr eventManager = framework->GetEventManager(); + if (eventManager == nullptr) { + LOG_WARNING("Failed to get EventManager!"); + return; + } + + // 触发事件 + eventManager->TriggerEvent(eventName, eventData, forceAsync, priority); +} +} // namespace XNSim diff --git a/XNCore_Win/XNModelObject/XNModelObject.h b/XNCore_Win/XNModelObject/XNModelObject.h new file mode 100644 index 0000000..5366ba6 --- /dev/null +++ b/XNCore_Win/XNModelObject/XNModelObject.h @@ -0,0 +1,267 @@ +/** + * @file XNModelObject.h + * @author jinchao + * @brief 模型基类头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNEventManager/XNEventManager.h" +#include "XNObject/XNObject.h" + +namespace XNSim { +struct XNModelObjectPrivate; + +/** + * @brief 模型基类 + * @details 所有模型系统中模型的基类,预先实现了部分模型共有的功能。 + */ +class XNModelObject : public XNObject { + XN_METATYPE(XNModelObject, XNObject) + XN_DECLARE_PRIVATE(XNModelObject) + +public: + /** + * @brief 模型基类默认构造函数 + */ + XNModelObject(); + + /** + * @brief 模型基类默认析构函数 + */ + virtual ~XNModelObject(); + +protected: + /** + * @brief 模型基类带参构造函数 + * @param p:XNModelObjectPrivate类型,私有结构体指针 + * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 + */ + XNModelObject(PrivateType *p); + +public: + void SetFramework(XNFrameworkPtr framework); + +protected: + XNFrameworkPtr GetFramework() const; + +public: + /** + * @brief 获取模型描述 + * @return const QString&:模型描述 + */ + const XN_STRING &GetDescription(); + + /** + * @brief 设置模型描述 + * @param sDescription:QString类型,模型描述 + */ + void SetDescription(const XN_STRING &sDescription); + + /** + * @brief 获取作者 + * @return const QString&: 作者 + */ + const XN_STRING &GetAuthor(); + + /** + * @brief 设置作者 + * @param sAuthor: QString类型,作者 + */ + void SetAuthor(const XN_STRING &sAuthor); + + /** + * @brief 获取模型配置文件路径 + * @return const QString&: 模型配置文件路径 + */ + const XN_STRING &GetXmlPath(); + + /** + * @brief 设置模型配置文件路径 + * @param sXmlPath:QString类型,模型配置文件路径 + */ + void SetXmlPath(const XN_STRING &sXmlPath); + + /** + * @brief 获取模型创建时间 + * @return const XNTimePoint&:模型创建时间 + */ + const XNTimePoint &GetCreateTime(); + + /** + * @brief 设置模型创建时间 + * @param cTime: XNTimePoint类型,模型创建时间 + */ + void SetCreateTime(const XNTimePoint &cTime); + + /** + * @brief 获取模型修改时间 + * @return const XNTimePoint&:模型修改时间 + */ + const XNTimePoint &GetChangeTime(); + + /** + * @brief 设置模型修改时间 + * @param cTime: XNTimePoint类型,模型修改时间 + */ + void SetChangeTime(const XNTimePoint &cTime); + + /** + * @brief 获取模型版本号 + * @return const XNString&: 模型版本号 + */ + const XN_STRING &GetVersion(); + + /** + * @brief 设置模型版本号 + * @param sVersion: std::string类型,模型版本号 + */ + void SetVersion(const XN_STRING &sVersion); + + /** + * @brief 获取模型运行频率组 + * @return uint32_t: 模型运行频率组 + */ + XN_UINT32 GetRunFreq() const; + + /** + * @brief 设置模型运行频率组 + * @param runFreq: uint32_t类型,模型运行频率组 + */ + void SetRunFreq(XN_UINT32 runFreq); + + /** + * @brief 获取模型运行节点 + * @return uint32_t: 模型运行节点 + */ + XN_UINT32 GetRunNode() const; + + /** + * @brief 设置模型运行节点 + * @param runNode: uint32_t类型,模型运行节点 + */ + void SetRunNode(XN_UINT32 runNode); + + /** + * @brief 获取模型运行优先级 + * @return uint32_t: 模型运行优先级 + */ + XN_UINT32 GetRunPriority() const; + + /** + * @brief 设置模型运行优先级 + * @param runPriority: uint32_t类型,模型运行优先级 + */ + void SetRunPriority(XN_UINT32 runPriority); + + /** + * @brief 获取模型设置频率 + * @return double: 模型设置频率 + */ + XN_DOUBLE GetSetFreq() const; + + /** + * @brief 设置模型设置频率 + * @param setFreq: double类型,模型设置频率 + */ + void SetSetFreq(XN_DOUBLE setFreq); + + /** + * @brief 获取模型动态库路径 + * @return const std::string&: 模型动态库路径 + */ + const XN_STRING &GetLibPath(); + + /** + * @brief 设置模型动态库路径 + * @param sLibPath: std::string类型,模型动态库路径 + */ + void SetLibPath(const XN_STRING &sLibPath); + + /** + * @brief 单步执行函数 + * @details 模型默认的周期性执行函数 + */ + virtual void StepUpdate(); + + /** + * @brief 注册事件处理器 + * @param eventName: 事件名称 + * @param callback: 事件处理回调函数 + * @param async: 是否异步处理 + * @return: 返回处理器ID,失败返回-1 + */ + int RegisterEventHandler( + const XN_STRING &eventName, XNEventCallback callback, + XN_BOOL async = false, + XNEvent::Priority priority = XNEvent::Priority::Normal); + + /** + * @brief 触发事件 + * @param eventName: 要触发的事件名称 + * @param eventData: 事件携带的数据 + * @param forceAsync: 强制异步处理 + */ + void TriggerEvent(const XN_STRING &eventName, + const XN_ANY &eventData = XN_ANY(), + XN_BOOL forceAsync = false, + XNEvent::Priority priority = XNEvent::Priority::Normal); + + /** + * @brief 注册实时事件处理器 + * @param eventName: 事件名称 + * @param callback: 事件处理回调函数 + * @return: 返回处理器ID,失败返回-1 + */ + int RegisterRTEventHandler(const XN_STRING &eventName, + XNEventCallback callback) { + return RegisterEventHandler(eventName, callback, true, + XNEvent::Priority::RealTime); + } + + /** + * @brief 触发实时事件 + * @param eventName: 要触发的事件名称 + * @param eventData: 事件携带的数据 + */ + void TriggerRTEvent(const XN_STRING &eventName, + const XN_ANY &eventData = XN_ANY()) { + TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); + } + + void SetInitializeType(XN_UINT32 initialType); + + void SetThreadID(XN_UINT32 threadID); + + XN_UINT32 GetThreadID() const; + + /** + * @brief 初始化函数 + * @details + * 模型的初始化函数接口,子类继承时要调用父类初始化接口,或在此函数中使用AddMyFunction方法注册需要被线程调用的函数 + */ + virtual void Initialize(); + + /** + * @brief 仿真系统运行前做最后处理 + * @details 系统运行前模型做最后处理的接口 + */ + virtual void PrepareForExecute(); + +public: + virtual void RegisterDDSParticipant(); + +private: + void ParseXml(); + void ParseConfig(); +}; +} // namespace XNSim + +#define XN_MODEL_INITIALIZE(ClassName) \ + extern "C" XNSim::XNModelObjectPtr Initial##ClassName() { \ + XNSim::ClassName##Ptr obj = std::make_shared(); \ + return obj; \ + } diff --git a/XNCore_Win/XNModelObject/XNModelObject_p.h b/XNCore_Win/XNModelObject/XNModelObject_p.h new file mode 100644 index 0000000..6e2bedd --- /dev/null +++ b/XNCore_Win/XNModelObject/XNModelObject_p.h @@ -0,0 +1,98 @@ +/** + * @file XNModelObject_p.h + * @author jinchao + * @brief 模型基类私有头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNObject/XNObject_p.h" + +namespace XNSim { +/** + * @brief 模型基类私有结构体 + */ +struct XNModelObjectPrivate : public XNObjectPrivate { + XNFrameworkPtr _framework; + /** + * @brief 模型描述 + */ + XN_STRING _sDescription; + /** + * @brief 模型作者 + */ + XN_STRING _sAuthor; + /** + * @brief 模型配置文件路径 + */ + XN_STRING _sXmlPath; + /** + * @brief 数据包模型动态库路径 + */ + XN_STRING _sLibPath; + /** + * @brief 模型创建时间 + */ + XNTimePoint _cCreatTime; + /** + * @brief 模型修改时间 + */ + XNTimePoint _cChangeTime; + /** + * @brief 模型版本号 + */ + XN_STRING _sVersion; + /** + * @brief 数据包模型动态库句柄 + */ + XN_HANDLE _dynamicLib = nullptr; + + /** + * @brief 发布者信息 + */ + XNDDSDataWriterPtr _dataWriter; + + /** + * @brief 模型运行时间 + */ + XN_TIMESPEC _lastRunTime; + + /** + * @brief 模型运行次数 + */ + XN_UINT64 _runCnt; + + /** + * @brief 模型运行频率 + */ + XN_UINT32 _runFreq; + + /** + * @brief 模型运行节点 + */ + XN_UINT32 _runNode; + + /** + * @brief 模型运行优先级 + */ + XN_UINT32 _runPriority; + + /** + * @brief 模型设置频率 + */ + XN_DOUBLE _setFreq; + + /** + * @brief 模型初始化类型 + */ + XN_UINT32 _initialType; + + /** + * @brief 模型线程ID + */ + XN_UINT32 _threadID; +}; +} // namespace XNSim diff --git a/XNCore_Win/XNObject/CMakeLists.txt b/XNCore_Win/XNObject/CMakeLists.txt new file mode 100644 index 0000000..9c9eb1c --- /dev/null +++ b/XNCore_Win/XNObject/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNOBJECT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNObject.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNObject_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNObject.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNOBJECT_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNObject/XNObject.cpp b/XNCore_Win/XNObject/XNObject.cpp new file mode 100644 index 0000000..c4bf623 --- /dev/null +++ b/XNCore_Win/XNObject/XNObject.cpp @@ -0,0 +1,33 @@ +#include "XNObject.h" +#include "XNObject_p.h" + +namespace XNSim { +XNObject::XNObject() : _Private_Ptr(new XNObjectPrivate()) { + _Private_Ptr->_Public_Ptr = this; +} + +XNObject::XNObject(PrivateType *p) : _Private_Ptr(p) { + _Private_Ptr->_Public_Ptr = this; +} + +XNObject::~XNObject() { + if (_Private_Ptr) { + delete _Private_Ptr; + } + _Private_Ptr = nullptr; +} + +XNObjectPrivate::~XNObjectPrivate() { _Public_Ptr = nullptr; } + +XN_UINT32 XNObject::GetUniqueId() { return _Private_Ptr->uUniqueID; } + +void XNObject::SetUniqueId(const XN_UINT32 &uniqueId) { + _Private_Ptr->uUniqueID = uniqueId; +} + +const XN_STRING &XNObject::GetObjectName() { return _Private_Ptr->sObjectName; } + +void XNObject::SetObjectName(const XN_STRING &name) { + _Private_Ptr->sObjectName = name; +} +} // namespace XNSim diff --git a/XNCore_Win/XNObject/XNObject.h b/XNCore_Win/XNObject/XNObject.h new file mode 100644 index 0000000..587b360 --- /dev/null +++ b/XNCore_Win/XNObject/XNObject.h @@ -0,0 +1,99 @@ +/** + * @file XNObject.h + * @author jinchao + * @brief 基础对象类 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ +#pragma once + +#include "XNGlobalDefine/XNDefine.h" +#include "XNLogger/XNLogger.h" + +namespace XNSim { +struct XNObjectPrivate; + +/** + * @brief 基础对象类 + */ +class XNCORE_EXPORT XNObject : public std::enable_shared_from_this { + XN_METATYPE_P(XNObject) + XN_NOCOPYABLE(XNObject) +protected: + using PrivateType = XNObjectPrivate; + /** + * @brief 私有数据成员 + */ + PrivateType *_Private_Ptr; + +public: + /** + * @brief 构造函数 + */ + XNObject(); + + /** + * @brief 析构函数 + */ + virtual ~XNObject(); + +protected: + /** + * @brief 构造函数 + * @param p 私有数据成员 + */ + XNObject(PrivateType *p); + +public: + /** + * @brief 获取唯一ID + * @return 唯一ID + */ + XN_UINT32 GetUniqueId(); + + /** + * @brief 设置唯一ID + * @param uniqueId 唯一ID + */ + void SetUniqueId(const XN_UINT32 &uniqueId); + + /** + * @brief 获取对象名称 + * @return 对象名称 + */ + const XN_STRING &GetObjectName(); + + /** + * @brief 设置对象名称 + * @param name 对象名称 + */ + void SetObjectName(const XN_STRING &name); +}; + +class XNFramework; +class XNDDSManager; +class XNEventManager; +class XNModelManager; +class XNServiceManager; +class XNThreadManager; +class XNTimeManager; +class XNConfigManager; +class XNThreadObject; +class XNModelObject; +class XNServiceObject; + +XNCLASS_PTR_DECLARE(XNFramework) +XNCLASS_PTR_DECLARE(XNDDSManager) +XNCLASS_PTR_DECLARE(XNEventManager) +XNCLASS_PTR_DECLARE(XNModelManager) +XNCLASS_PTR_DECLARE(XNServiceManager) +XNCLASS_PTR_DECLARE(XNThreadManager) +XNCLASS_PTR_DECLARE(XNTimeManager) +XNCLASS_PTR_DECLARE(XNConfigManager) +XNCLASS_PTR_DECLARE(XNThreadObject) +XNCLASS_PTR_DECLARE(XNModelObject) +XNCLASS_PTR_DECLARE(XNServiceObject) +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNObject/XNObject_p.h b/XNCore_Win/XNObject/XNObject_p.h new file mode 100644 index 0000000..0c9257f --- /dev/null +++ b/XNCore_Win/XNObject/XNObject_p.h @@ -0,0 +1,36 @@ +/** + * @file XNObject_p.h + * @author jinchao + * @brief 基础对象类的私有数据成员 + * @version 1.0 + * @date 2025-01-08 + * + * @copyright Copyright (c) 2025 COMAC + * + */ +#pragma once + +#include "XNObject.h" + +namespace XNSim { +/** + * @brief 基础对象类的私有数据成员 + */ +struct XNObjectPrivate { + virtual ~XNObjectPrivate(); + /** + * @brief 基础对象类指针 + */ + XNObject *_Public_Ptr; + + /** + * @brief 唯一ID + */ + XN_UINT32 uUniqueID; + + /** + * @brief 对象名称 + */ + XN_STRING sObjectName; +}; +} // namespace XNSim diff --git a/XNCore_Win/XNServiceManager/CMakeLists.txt b/XNCore_Win/XNServiceManager/CMakeLists.txt new file mode 100644 index 0000000..0cc1a54 --- /dev/null +++ b/XNCore_Win/XNServiceManager/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNSERVICEMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNServiceManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNServiceManager_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNServiceManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNSERVICEMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNServiceManager/XNServiceManager.cpp b/XNCore_Win/XNServiceManager/XNServiceManager.cpp new file mode 100644 index 0000000..8c0e6fe --- /dev/null +++ b/XNCore_Win/XNServiceManager/XNServiceManager.cpp @@ -0,0 +1,122 @@ +#include "XNServiceManager.h" +#include "XNServiceManager_p.h" +#include "XNServiceObject/XNServiceObject.h" + +namespace XNSim { +XNServiceManager::XNServiceManager() + : XNBaseFrameObject(new XNServiceManagerPrivate()) { + SetUniqueId(enumValue(XNCoreObjectID::ServiceManager)); + SetObjectName("XNServiceManager"); + T_D(); + d->ServiceIDAssigned.resize(XN_SERVICE_ID_SIZE, false); +} + +XNServiceManager::~XNServiceManager() {} + +XNServiceManager::XNServiceManager(PrivateType *p) : XNBaseFrameObject(p) {} + +bool XNServiceManager::Initialize() { + T_D(); + LOG_INFO("XNServiceManager Initialize Success!"); + d->_status = XNFrameObjectStatus::Initialized; + return true; +} + +XN_BOOL XNServiceManager::PrepareForExecute() { + T_D(); + for (auto &service : d->ServiceList) { + service.second->PrepareForExecute(); + } + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("XNServiceManager is prepared!"); + return true; +} + +void XNServiceManager::LoadService(const XN_STRING &servicePath, + const XN_STRING &serviceName, + const XN_STRING &serviceVersion, + XN_UINT32 initialType) { + T_D(); + XN_HANDLE handle = loadLibrary(servicePath); + if (handle) { + typedef XNServiceObjectPtr (*InitialServiceFunc)(); + XN_STRING initialServiceName = "Initial" + serviceName; + InitialServiceFunc initialService = + (InitialServiceFunc)getSymbol(handle, initialServiceName); + if (initialService) { + XNServiceObjectPtr service = initialService(); + if (service) { + XN_UINT32 serviceID = RegisterService(); + if (serviceID == 0) { + LOG_WARNING( + "0x2174 Assign Service ID Failed, Service ID is used up!"); + closeLibrary(handle); + return; + } + service->SetUniqueId(serviceID); + service->SetObjectName(serviceName); + service->SetFramework(GetFramework()); + if (initialType == 0) { + // 使用std::filesystem处理路径 + XN_PATH configPath = XN_PATH(servicePath).parent_path() / + (serviceName + "_V" + serviceVersion + ".scfg"); + service->SetXmlPath(configPath.string()); + } else if (initialType == 1) { + LOG_INFO("0x2176 加载服务: %1", serviceName + "," + serviceVersion); + service->SetXmlPath(serviceName + "," + serviceVersion); + } else { + LOG_WARNING("0x2175 InitialType Error, InitialType: %d", initialType); + closeLibrary(handle); + return; + } + + // 注册服务到管理器 + d->ServiceList[serviceID] = service; + service->SetInitializeType(initialType); + // 初始化服务 + LOG_INFO("0x2176 初始化服务: %1", serviceName); + service->Initialize(); + } else { + LOG_WARNING("0x2173 Service %s Not found in dynamic link library %s!", + serviceName, servicePath); + closeLibrary(handle); + return; + } + } else { + LOG_WARNING("0x2177 Service %s Initialization Failed, Function " + "InitialService Not Found!", + serviceName); + closeLibrary(handle); + return; + } + } else { + LOG_WARNING( + "0x2172 Service %s Dynamic link library loading failed! Error: %s", + serviceName, LoadError()); + } +} + +XNServiceObjectPtr XNServiceManager::GetService(XN_UINT32 serviceID) { + T_D(); + if (d->ServiceIDAssigned[serviceID - XN_SERVICE_ID_START] && + d->ServiceList.find(serviceID) != d->ServiceList.end()) { + return d->ServiceList[serviceID]; + } else { + return nullptr; + } +} + +XN_UINT32 XNServiceManager::RegisterService() { + T_D(); + // 从20000~29999的编号中分配ID + for (XN_UINT32 i = 0; i < XN_SERVICE_ID_SIZE; i++) { + if (d->ServiceIDAssigned[i]) + continue; + else { + d->ServiceIDAssigned[i] = true; + return i + XN_SERVICE_ID_START; + } + } + return 0; +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNServiceManager/XNServiceManager.h b/XNCore_Win/XNServiceManager/XNServiceManager.h new file mode 100644 index 0000000..de14ba1 --- /dev/null +++ b/XNCore_Win/XNServiceManager/XNServiceManager.h @@ -0,0 +1,34 @@ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject.h" + +namespace XNSim { +struct XNServiceManagerPrivate; + +class XNServiceManager : public XNBaseFrameObject { + XN_METATYPE(XNServiceManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNServiceManager) +public: + /** + * @brief 服务管理器类默认构造函数 + */ + XNServiceManager(); + + /** + * @brief 服务管理器类析构函数 + */ + virtual ~XNServiceManager(); + +protected: + XNServiceManager(PrivateType *p); + +public: + virtual XN_BOOL Initialize() override; + virtual XN_BOOL PrepareForExecute() override; + void LoadService(const XN_STRING &servicePath, const XN_STRING &serviceName, + const XN_STRING &serviceVersion, XN_UINT32 initialType); + +public: + XNServiceObjectPtr GetService(XN_UINT32 serviceID); + XN_UINT32 RegisterService(); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNServiceManager/XNServiceManager_p.h b/XNCore_Win/XNServiceManager/XNServiceManager_p.h new file mode 100644 index 0000000..45d6e5b --- /dev/null +++ b/XNCore_Win/XNServiceManager/XNServiceManager_p.h @@ -0,0 +1,20 @@ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject_p.h" + +namespace XNSim { +using XNServiceMap = std::map; + +struct XNServiceManagerPrivate : public XNBaseFrameObjectPrivate { + /** + * @brief 服务ID库 + * @details 所有服务已用ID的存储库 + */ + XNAsignedIDFlag ServiceIDAssigned; + + /** + * @brief 服务列表 + * @details 所有服务的存储库 + */ + XNServiceMap ServiceList; +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNServiceObject/CMakeLists.txt b/XNCore_Win/XNServiceObject/CMakeLists.txt new file mode 100644 index 0000000..6f97910 --- /dev/null +++ b/XNCore_Win/XNServiceObject/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNSERVICEOBJECT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNServiceObject.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNServiceObject_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNServiceObject.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNSERVICEOBJECT_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNServiceObject/XNServiceObject.cpp b/XNCore_Win/XNServiceObject/XNServiceObject.cpp new file mode 100644 index 0000000..8695ac9 --- /dev/null +++ b/XNCore_Win/XNServiceObject/XNServiceObject.cpp @@ -0,0 +1,294 @@ +#include "XNServiceObject.h" +#include "XNEventManager/XNEventManager.h" +#include "XNFramework/XNFramework.h" +#include "XNServiceObject_p.h" + +namespace XNSim { +XNServiceObject::XNServiceObject() : XNObject(new XNServiceObjectPrivate()) { + T_D(); + d->_initialType = 0; +} + +XNServiceObject::~XNServiceObject() {} + +XNServiceObject::XNServiceObject(PrivateType *p) : XNObject(p) {} + +const XN_STRING &XNServiceObject::GetVersion() { + T_D(); + return d->_sVersion; +} + +const XN_STRING &XNServiceObject::GetDescription() { + T_D(); + return d->_sDescription; +} + +const XN_STRING &XNServiceObject::GetAuthor() { + T_D(); + return d->_sAuthor; +} + +const XN_STRING &XNServiceObject::GetXmlPath() { + T_D(); + return d->_sXmlPath; +} + +const XNTimePoint &XNServiceObject::GetCreateTime() { + T_D(); + return d->_cCreateTime; +} + +const XNTimePoint &XNServiceObject::GetChangeTime() { + T_D(); + return d->_cChangeTime; +} + +void XNServiceObject::SetVersion(const XN_STRING &version) { + T_D(); + d->_sVersion = version; +} + +void XNServiceObject::SetDescription(const XN_STRING &sDescription) { + T_D(); + d->_sDescription = sDescription; +} + +void XNServiceObject::SetAuthor(const XN_STRING &sAuthor) { + T_D(); + d->_sAuthor = sAuthor; +} + +void XNServiceObject::SetXmlPath(const XN_STRING &sXmlPath) { + T_D(); + d->_sXmlPath = sXmlPath; +} + +void XNServiceObject::SetCreateTime(const XNTimePoint &cTime) { + T_D(); + d->_cCreateTime = cTime; +} + +void XNServiceObject::SetChangeTime(const XNTimePoint &cTime) { + T_D(); + d->_cChangeTime = cTime; +} + +XN_INT32 XNServiceObject::RegisterEventHandler(const XN_STRING &eventName, + XNEventCallback callback, + bool async, + XNEvent::Priority priority) { + // 注册事件处理器 + 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 XN_STRING &eventName, + const XN_ANY &eventData, bool forceAsync, + XNEvent::Priority priority) { + // 触发事件 + T_D(); + auto framework = GetFramework(); + if (framework) { + auto eventManager = framework->GetEventManager(); + if (eventManager) { + eventManager->TriggerEvent(eventName, eventData, forceAsync, priority); + } + } +} + +XN_INT32 XNServiceObject::RegisterRTEventHandler(const XN_STRING &eventName, + XNEventCallback callback) { + return RegisterEventHandler(eventName, callback, true, + XNEvent::Priority::RealTime); +} + +void XNServiceObject::TriggerRTEvent(const XN_STRING &eventName, + const XN_ANY &eventData) { + TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); +} + +void XNServiceObject::SetInitializeType(XN_UINT32 initialType) { + T_D(); + d->_initialType = initialType; +} + +void XNServiceObject::Initialize() { + T_D(); + if (d->_initialType == 0) { + ParseXml(); + } else { + ParseConfig(); + } +} + +void XNServiceObject::ParseXml() { + T_D(); + XN_XMLDocument doc; + if (LoadXmlFile(GetXmlPath(), doc) != 0) { + LOG_WARNING("Failed to open the service configuration file: %1!", + GetXmlPath()); + return; + } + + XN_XMLElement *rootNode = GetRootElement(doc); + if (!rootNode) { + LOG_WARNING("Invalid XML file format: %1!", GetXmlPath()); + return; + } + + XN_STRING serviceName = GetFirstChildElementText(rootNode, "Name"); + 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 = GetFirstChildElementText(rootNode, "Description"); + d->_sAuthor = GetFirstChildElementText(rootNode, "Author"); + d->_sVersion = GetFirstChildElementText(rootNode, "Version"); + + // 解析时间 + XN_STRING createTimeStr = GetFirstChildElementText(rootNode, "CreateTime"); + XN_STRING changeTimeStr = GetFirstChildElementText(rootNode, "ChangeTime"); + d->_cCreateTime = parseISOTime(createTimeStr); + d->_cChangeTime = parseISOTime(changeTimeStr); + + XN_XMLElement *nodeCmds = GetFirstChildElement(rootNode, "CommandList"); + if (nodeCmds) { + for (XN_XMLElement *nodeCmd = GetFirstChildElement(nodeCmds, "Command"); + nodeCmd != nullptr; + nodeCmd = GetNextSiblingElement(nodeCmd, "Command")) { + XN_STRING cmdName = GetAttribute(nodeCmd, "Name"); + XN_STRING cmdDescription = GetAttribute(nodeCmd, "Description"); + XN_STRING cmdCall = GetAttribute(nodeCmd, "Call"); + // TODO: 处理命令信息 + } + } +} + +void XNServiceObject::ParseConfig() { + T_D(); + XN_STRINGLIST nameAndVersion = XNSplit(GetXmlPath(), ","); + XN_STRING serviceName = nameAndVersion[0]; + XN_STRING serviceVersion = nameAndVersion[1]; + // 获取数据库路径 + XN_STRING dbPath = getEnv("XNCore"); + if (dbPath.empty()) { + LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!"); + return; + } + dbPath += "/database/XNSim.db"; + + // 打开数据库 + XN_DB_PTR db = openDatabase(dbPath); + if (db == nullptr) { + LOG_ERROR("0x1016 打开数据库失败: %1", dbPath); + return; + } + + // 准备SQL语句 + XN_STRING sql = + "SELECT * FROM XNServiceVersion WHERE ClassName = ? AND Version = ?"; + XN_DB_STMT_PTR stmt = prepareSql(db, sql); + if (stmt == nullptr) { + LOG_ERROR("0x1017 准备SQL语句失败: %1", sql); + closeDatabase(db); + return; + } + + // 绑定参数 + if (!bindText(stmt, 1, serviceName) || !bindText(stmt, 2, serviceVersion)) { + LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db)); + finalizeSql(stmt); + closeDatabase(db); + return; + } + + // 执行查询 + if (!stepSql(stmt)) { + LOG_ERROR("0x1019 未找到服务名称为%1,版本号%2的记录", serviceName.c_str(), + serviceVersion.c_str()); + finalizeSql(stmt); + closeDatabase(db); + return; + } + d->_sDescription = getStringFromSqlite3(stmt, 5); + d->_sAuthor = getStringFromSqlite3(stmt, 4); + d->_sVersion = getStringFromSqlite3(stmt, 2); + + // 解析时间 + XN_STRING createTimeStr = getStringFromSqlite3(stmt, 6); + XN_STRING changeTimeStr = getStringFromSqlite3(stmt, 7); + d->_cCreateTime = parseISOTime(createTimeStr); + d->_cChangeTime = parseISOTime(changeTimeStr); + + // 读取服务命令列表 + XN_STRING commandListStr = getStringFromSqlite3(stmt, 8); + if (!commandListStr.empty()) { + try { + XN_JSON commandList = parseJson(commandListStr); + if (commandList.is_array()) { + for (const auto &cmd : commandList) { + if (cmd.contains("Name") && cmd.contains("Description") && + cmd.contains("Call")) { + LOG_INFO("0x1021 服务命令: %1", cmd["Name"].get()); + // TODO: 处理服务命令信息 + // d->_commandList.emplace_back( + // cmd["Name"].get(), + // cmd["Description"].get(), + // cmd["Call"].get() + // ); + } + } + } + } catch (const std::exception &e) { + LOG_WARNING("0x1020 解析服务命令列表失败: %1", e.what()); + } + } + + // 读取其他参数 + XN_STRING otherParamsStr = getStringFromSqlite3(stmt, 9); + if (!otherParamsStr.empty()) { + try { + d->_otherParams = parseJson(otherParamsStr); + } catch (const std::exception &e) { + LOG_WARNING("0x1020 解析其他参数失败: %1", e.what()); + } + } + + // 清理资源 + finalizeSql(stmt); + closeDatabase(db); +} + +void XNServiceObject::PrepareForExecute() { + T_D(); + RegisterDDSParticipant(); +} + +void XNServiceObject::RegisterDDSParticipant() { + T_D(); + // TODO 注册服务状态主题参与者 +} + +XNFrameworkPtr XNServiceObject::GetFramework() const { + T_D(); + return d->pFramework; +} + +void XNServiceObject::SetFramework(XNFrameworkPtr framework) { + T_D(); + d->pFramework = framework; +} +} // namespace XNSim diff --git a/XNCore_Win/XNServiceObject/XNServiceObject.h b/XNCore_Win/XNServiceObject/XNServiceObject.h new file mode 100644 index 0000000..7b0cd3c --- /dev/null +++ b/XNCore_Win/XNServiceObject/XNServiceObject.h @@ -0,0 +1,74 @@ +#pragma once + +#include "XNEventManager/XNEventManager.h" +#include "XNObject/XNObject.h" +#include "XNServiceManager/XNServiceManager.h" + +namespace XNSim { +struct XNServiceObjectPrivate; + +class XNServiceObject : public XNObject { + XN_METATYPE(XNServiceObject, XNObject) + XN_DECLARE_PRIVATE(XNServiceObject) +public: + XNServiceObject(); + virtual ~XNServiceObject(); + +protected: + XNServiceObject(PrivateType *p); + +public: + const XN_STRING &GetVersion(); + const XN_STRING &GetDescription(); + const XN_STRING &GetAuthor(); + const XN_STRING &GetXmlPath(); + const XNTimePoint &GetCreateTime(); + const XNTimePoint &GetChangeTime(); + + void SetVersion(const XN_STRING &version); + void SetDescription(const XN_STRING &description); + void SetAuthor(const XN_STRING &author); + void SetXmlPath(const XN_STRING &xmlPath); + void SetCreateTime(const XNTimePoint &createTime); + void SetChangeTime(const XNTimePoint &changeTime); + + XN_INT32 + RegisterEventHandler(const XN_STRING &eventName, XNEventCallback callback, + bool async = false, + XNEvent::Priority priority = XNEvent::Priority::Normal); + + void TriggerEvent(const XN_STRING &eventName, + const XN_ANY &eventData = XN_ANY(), bool forceAsync = false, + XNEvent::Priority priority = XNEvent::Priority::Normal); + + XN_INT32 RegisterRTEventHandler(const XN_STRING &eventName, + XNEventCallback callback); + + void TriggerRTEvent(const XN_STRING &eventName, + const XN_ANY &eventData = XN_ANY()); + + void SetInitializeType(XN_UINT32 initialType); + + virtual void Initialize(); + virtual void PrepareForExecute(); + + virtual void RegisterDDSParticipant(); + + void SetFramework(XNFrameworkPtr framework); + +protected: + XNFrameworkPtr GetFramework() const; + +private: + void ParseXml(); + void ParseConfig(); +}; + +XNCLASS_PTR_DECLARE(XNServiceObject) +} // namespace XNSim + +#define XN_SERVICE_INITIALIZE(ClassName) \ + extern "C" XNSim::XNServiceObjectPtr Initial##ClassName() { \ + XNSim::ClassName##Ptr obj = std::make_shared(); \ + return obj; \ + } diff --git a/XNCore_Win/XNServiceObject/XNServiceObject_p.h b/XNCore_Win/XNServiceObject/XNServiceObject_p.h new file mode 100644 index 0000000..ae4ec07 --- /dev/null +++ b/XNCore_Win/XNServiceObject/XNServiceObject_p.h @@ -0,0 +1,18 @@ +#pragma once +#include "XNObject/XNObject_p.h" + +namespace XNSim { +struct XNServiceObjectPrivate : public XNObjectPrivate { + XN_STRING _sDescription; + XN_STRING _sAuthor; + XN_STRING _sXmlPath; + XNTimePoint _cCreateTime; + XNTimePoint _cChangeTime; + XN_STRING _sVersion; + XNDDSDataWriterMap _dataWriters; + XNFrameworkPtr pFramework; + uint32_t _initialType; + XN_JSON _otherParams; +}; + +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNThreadManager/CMakeLists.txt b/XNCore_Win/XNThreadManager/CMakeLists.txt new file mode 100644 index 0000000..53ade6a --- /dev/null +++ b/XNCore_Win/XNThreadManager/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNTHREADMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNThreadManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNThreadManager_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNThreadManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNTHREADMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNThreadManager/XNThreadManager.cpp b/XNCore_Win/XNThreadManager/XNThreadManager.cpp new file mode 100644 index 0000000..24db043 --- /dev/null +++ b/XNCore_Win/XNThreadManager/XNThreadManager.cpp @@ -0,0 +1,236 @@ +/** + * @file XNThreadManager.cpp + * @author jinchao + * @brief 线程管理器类源文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#include "XNThreadManager.h" +#include "XNFramework/XNFramework.h" +#include "XNModelManager/XNModelManager.h" +#include "XNThreadManager_p.h" +#include "XNThreadObject/XNThreadObject.h" +#include "XNTimeManager/XNTimeManager.h" + + +namespace XNSim { + +// 默认构造函数 +XNThreadManager::XNThreadManager() + : XNBaseFrameObject(new XNThreadManagerPrivate()) { + SetUniqueId(enumValue(XNCoreObjectID::ThreadManager)); + SetObjectName("XNThreadManager"); +} + +XNThreadManager::~XNThreadManager() {} + +XNThreadManager::XNThreadManager(PrivateType *p) : XNBaseFrameObject(p) {} + +// 初始化函数 +bool XNThreadManager::Initialize() { + T_D(); + d->_eRunStatus = RunStatus::NotStart; + d->_threadList.clear(); + d->_funList.clear(); + LOG_INFO("XNThreadManager Initialize Success!"); + d->_status = XNFrameObjectStatus::Initialized; + return true; +} + +// 开始控制 +void XNThreadManager::Start() { + T_D(); + // 如果当前状态是未开始状态 + if (d->_eRunStatus == RunStatus::NotStart) { + // 状态切换为正在运行 + d->_eRunStatus = RunStatus::Runing; + } +} + +// 停止控制 +void XNThreadManager::Abort() { + T_D(); + // 如果当前状态不是停止状态 + if (d->_eRunStatus != RunStatus::Aborted) { + // 状态切换为停止 + d->_eRunStatus = RunStatus::Aborted; + } +} + +// 暂停控制 +void XNThreadManager::Pause() { + T_D(); + // 如果当前是正在运行状态 + if (d->_eRunStatus == RunStatus::Runing) { + // 状态切换为暂停 + d->_eRunStatus = RunStatus::Suspend; + } +} + +// 继续控制 +void XNThreadManager::Continue() { + T_D(); + // 如果当前是暂停状态 + if (d->_eRunStatus == RunStatus::Suspend) { + // TODO 这里需要重新设置一下时间信息,不然启动后会加速运行至设定的时间 + // 状态切换为正在运行 + d->_eRunStatus = RunStatus::Runing; + } +} + +// 获取当前运行状态 +RunStatus XNThreadManager::GetStatus() { + T_D(); + return d->_eRunStatus; +} + +// 添加周期性函数 +void XNThreadManager::RegisterFunction(XN_UINT32 id, XNCallBack fun, + XN_UINT32 threadID, XN_UINT32 freqGroup, + XN_UINT32 RunPos, XN_UINT32 RunPriorty) { + T_D(); + // 如果周期性函数校验通过 + if (IsFunParamRight(id, freqGroup, RunPos)) { + // 存储提交的函数 + XNFunInfoPtr sFunInfo = std::make_shared(); + sFunInfo->fun = fun; + sFunInfo->threadID = threadID; + sFunInfo->freqGroup = freqGroup; + sFunInfo->RunPos = RunPos; + sFunInfo->RunPriority = RunPriorty; + d->_funList[id].push_back(sFunInfo); + 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); + } + } +} + +// 注册函数校验 +XN_BOOL XNThreadManager::IsFunParamRight(XN_UINT32 id, XN_UINT32 freqGroup, + XN_UINT32 RunPos) { + // 检查提交的函数是否符合规定 + if (freqGroup < 0 || freqGroup > 5) { + // 如果频率分组不是0~5 + LOG_WARNING("0x2170 The submitted function's run frequency group of Model " + "[ %1 ] is not " + "between 0 and 5, registration failed!", + id); + return false; + } else if (RunPos > (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!", + id); + return false; + } + return true; +} + +// 仿真运行前做最后处理 +XN_BOOL XNThreadManager::PrepareForExecute() { + T_D(); + PERIOD_INFO pinfo; + getCurrentRTTime(&(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..."); + for (auto &thread : d->_threadList) { + XN_BOOL bRet = thread.second->Initialize(); + if (!bRet) { + LOG_ERROR("Thread [ %1 ] PrepareForExecute Failed!", thread.first); + continue; + } + } + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("XNThreadManager is prepared!"); + return true; +} + +// 添加线程 +XN_UINT32 XNThreadManager::AddThreadPool(XN_STRING name, XN_DOUBLE freq, + XN_UINT32 priority, XN_UINT32 CPUAff) { + T_D(); + // 创建线程对象 + XNThreadObjectPtr thread = + std::make_shared(name, freq, priority, CPUAff); + thread->SetThreadID(AllocateThreadID()); + thread->SetFramework(GetFramework()); + 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::SimControl(XN_UINT32 objectId, SimControlCmd cmd) { + T_D(); + if (objectId == 0) { + switch (cmd) { + case SimControlCmd::Start: + Start(); + break; + case SimControlCmd::Abort: + Abort(); + break; + case SimControlCmd::Continue: + Continue(); + break; + case SimControlCmd::Suspend: + Pause(); + break; + } + } + for (auto &thread : d->_threadList) { + thread.second->SimControl(objectId, cmd); + } +} + +// 获取线程数量 +XN_UINT32 XNThreadManager::GetThreadCount() { + T_D(); + return d->_threadList.size(); +} + +// 分配线程ID +XN_UINT32 XNThreadManager::AllocateThreadID() { + T_D(); + // 从5000到9999分配线程ID + static XN_UINT32 threadID = 5000; + while (d->_threadList.find(threadID) != d->_threadList.end()) { + threadID++; + } + d->_threadList[threadID] = nullptr; + return threadID; +} + +void XNThreadManager::SetThreadFreqByID(XN_UINT32 threadID, XN_DOUBLE freq) { + T_D(); + d->_threadList[threadID]->SetRunFrequecy(freq); +} + +XN_DOUBLE XNThreadManager::GetThreadFreqByID(XN_UINT32 threadID) { + T_D(); + return d->_threadList[threadID]->GetRunFrequecy(); +} +} // namespace XNSim diff --git a/XNCore_Win/XNThreadManager/XNThreadManager.h b/XNCore_Win/XNThreadManager/XNThreadManager.h new file mode 100644 index 0000000..a656cff --- /dev/null +++ b/XNCore_Win/XNThreadManager/XNThreadManager.h @@ -0,0 +1,167 @@ +/** + * @file XNThreadManager.h + * @author jinchao + * @brief 线程管理器类头文件 + * @version 1.0 + * @date 2024-11-06 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject.h" + +namespace XNSim { +struct XNThreadManagerPrivate; + +/** + * @brief 线程管理器类 + * @details + * 主要负责创建、管理与控制模型调度线程,并向调度线程中添加需要调度执行的模型周期性函数 + */ +class XNThreadManager : public XNBaseFrameObject { + XN_METATYPE(XNThreadManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNThreadManager) + +public: + /** + * @brief 线程管理器类默认构造函数 + */ + XNThreadManager(); + + /** + * @brief 线程管理器类析构函数 + */ + virtual ~XNThreadManager(); + +protected: + /** + * @brief 线程管理器类带参构造函数 + * @param dd:XNThreadManagerPrivate类型,私有结构体指针 + * @param parent:QObject类型,父对象指针 + * @details 子类构造时调用此构造函数,传入子类的私有结构体指针 + */ + XNThreadManager(PrivateType *p); + +public: + /** + * @brief 开始控制 + * @details 控制线程管理器开始运行接口 + */ + void Start(); + + /** + * @brief 停止控制 + * @details 控制线程管理器停止运行接口 + */ + void Abort(); + + /** + * @brief 暂停控制 + * @details 控制线程管理器暂停运行接口 + */ + void Pause(); + + /** + * @brief 继续控制 + * @details 控制线程管理器继续运行接口 + */ + void Continue(); + + /** + * @brief 初始化线程管理器 + * @return true: 初始化成功 + * @return false: 初始化失败 + * @details 线程管理器的初始化接口函数 + */ + virtual XN_BOOL Initialize() override; + + /** + * @brief 仿真运行前最后处理 + * @note 线程管理器在所有线程开始执行前的准备工作 + */ + virtual XN_BOOL PrepareForExecute() override; + + /** + * @brief 设置线程频率 + * @param threadID: UINT32类型,线程ID + * @param freq: double类型,线程频率 + * @details 设置线程频率接口 + */ + void SetThreadFreqByID(XN_UINT32 threadID, XN_DOUBLE freq); + + /** + * @brief 获取线程频率 + * @param threadID: UINT32类型,线程ID + * @return double: 线程频率 + * @details 获取线程频率接口 + */ + XN_DOUBLE GetThreadFreqByID(XN_UINT32 threadID); + + /** + * @brief 仿真控制 + * @param objectId: 对象ID + * @param cmd: 仿真控制命令 + */ + void SimControl(XN_UINT32 objectId, SimControlCmd cmd); + + /** + * @brief 获取运行状态 + * @return RunStatus: 枚举类,线程运行状态 + * @details 获取线程管理器运行状态接口 + */ + RunStatus GetStatus(); + + /** + * @brief 获取线程数量 + * @return quint32: 线程数量 + */ + XN_UINT32 GetThreadCount(); + + /** + * @brief 添加一个线程 + * @param name: XNString类型,线程名称 + * @param freq: double类型,线程运行频率,单位Hz + * @param priority: + * UINT32类型,线程运行优先级,99~0,优先级数值越大,优先级越高 + * @param CPUAff: + * UINT32类型,线程的CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + * @details 按照设置的参数创建线程 + */ + virtual XN_UINT32 AddThreadPool(XN_STRING name, XN_DOUBLE freq, + XN_UINT32 priority, XN_UINT32 CPUAff); + + /** + * @brief 向线程中添加周期性函数 + * @param id: UINT32类型,模型全局唯一ID + * @param fun: XNCallBack函数包装器类型,需要提交的函数的包装 + * @param threadID: UINT32类型,线程ID + * @param freqGroup: + * UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 + * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) + * @param RunPriorty: + * UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 + * @return true: 添加成功 + * @return false: 添加失败 + * @details 根据运行频率组和节点号向对应的线程中添加周期性函数 + */ + void RegisterFunction(XN_UINT32 id, XNCallBack fun, XN_UINT32 threadID, + XN_UINT32 freqGroup, XN_UINT32 RunPos, + XN_UINT32 RunPriorty); + +private: + /** + * @brief 注册函数校验 + * @param freqGroup: + * UINT32类型,提交的函数运行频率组,0为基频,1为半频,2为1/4频,3为1/8频,4为1/16频,5为1/32频 + * @param RunPos: UINT32类型,提交的函数运行节点号,<2^(freqGroup) + * @return true:提交的函数频率与节点号符合规则 + * @return false:提交的函数频率与节点号不符合规则 + */ + bool IsFunParamRight(XN_UINT32 ModelID, XN_UINT32 freqGroup, + XN_UINT32 RunPos); + + XN_UINT32 AllocateThreadID(); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNThreadManager/XNThreadManager_p.h b/XNCore_Win/XNThreadManager/XNThreadManager_p.h new file mode 100644 index 0000000..6d14c1a --- /dev/null +++ b/XNCore_Win/XNThreadManager/XNThreadManager_p.h @@ -0,0 +1,72 @@ +/** + * @file XNThreadManager_p.h + * @author jinchao + * @brief 线程管理器类私有头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject_p.h" + +namespace XNSim { +/** + * @brief 周期性函数存储结构体 + */ +struct XNFunInfo { + /** + * @brief 周期性函数包装器 + */ + XNCallBack fun; + /** + * @brief 线程ID + */ + XN_UINT32 threadID; + /** + * @brief 运行频率组 + */ + XN_UINT32 freqGroup; + /** + * @brief 运行节点 + */ + XN_UINT32 RunPos; + /** + * @brief 运行优先级 + */ + XN_UINT32 RunPriority; +}; +/** + * @brief 声明周期性函数存储结构体的智能指针 + */ +using XNFunInfoPtr = std::shared_ptr; + +using XNFunInfoMap = std::map>; + +using XNThreadMap = std::map; + +using XNThreadIDSet = std::set; + +/** + * @brief 线程管理器类私有结构体 + */ +struct XNThreadManagerPrivate : public XNBaseFrameObjectPrivate { + /** + * @brief 所有线程运行状态 + */ + RunStatus _eRunStatus; + /** + * @brief 线程列表 + */ + XNThreadMap _threadList; + /** + * @brief 周期性函数存储列表 + */ + XNFunInfoMap _funList; + /** + * @brief 线程ID + */ + XNThreadIDSet _threadIDMap; +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNThreadObject/CMakeLists.txt b/XNCore_Win/XNThreadObject/CMakeLists.txt new file mode 100644 index 0000000..a8df486 --- /dev/null +++ b/XNCore_Win/XNThreadObject/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNTHREADOBJECT_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNThreadObject.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNThreadObject_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNThreadObject.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNTHREADOBJECT_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNThreadObject/XNThreadObject.cpp b/XNCore_Win/XNThreadObject/XNThreadObject.cpp new file mode 100644 index 0000000..6bf968e --- /dev/null +++ b/XNCore_Win/XNThreadObject/XNThreadObject.cpp @@ -0,0 +1,438 @@ +/** + * @file XNThreadObject.cpp + * @author jinchao + * @brief 线程类源文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#include "XNThreadObject.h" +#include "XNDDSManager/XNDDSManager.h" +#include "XNFramework/XNFramework.h" +#include "XNIDL/XNSimStatusPubSubTypes.hpp" +#include "XNLogger/XNLogger.h" +#include "XNThreadManager/XNThreadManager.h" +#include "XNThreadObject_p.h" + + +namespace XNSim { +XNThreadObject::XNThreadObject(XN_STRING name, XN_DOUBLE freq, + XN_UINT32 priority, XN_UINT32 CPUAff) + : XNObject(new XNThreadObjectPrivate()) { + SetObjectName(name); + T_D(); + d->_uPriority = priority; + d->_uAffinity = CPUAff; + d->_pinfo.period_ns = 1.0E9 / freq; + d->_setFreq = freq; + d->_funVec.resize(32); + // InitialFunPool(); +} + +// 默认析构函数 +XNThreadObject::~XNThreadObject(void) {} + +XNFrameworkPtr XNThreadObject::GetFramework() { + T_D(); + return d->_framework; +} + +void XNThreadObject::SetFramework(XNFrameworkPtr framework) { + T_D(); + d->_framework = framework; +} + +// 初始化函数 +XN_BOOL XNThreadObject::Initialize() { + T_D(); + XN_INT32 ret; +#ifdef XN_WINDOWS + d->_thread = std::thread(&XNThreadObject::ThreadFunction, this); + HANDLE h_thread = d->_thread.native_handle(); + if (h_thread != nullptr) { + bool bRet = SetThreadPriority(h_thread, THREAD_PRIORITY_TIME_CRITICAL); + if (!bRet) { + LOG_ERROR("0x2210 Thread: %1 Set Thread Priority Failed!", + GetObjectName()); + return false; + } + } +#endif + +#ifdef XN_LINUX + // 初始化线程参数 + ret = pthread_attr_init(&(d->_attr)); + if (ret) { + LOG_ERROR("0x2210 Thread: %1 Initialize Attribute Failed!", + GetObjectName()); + return false; + } + + // 设置线程栈空间大小 + ret = pthread_attr_setstacksize(&(d->_attr), PTHREAD_STACK_MIN * 20); + if (ret) { + 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!", + GetObjectName()); + return false; + } + + // 设置线程优先级 + d->_param.sched_priority = d->_uPriority; + ret = pthread_attr_setschedparam(&(d->_attr), &d->_param); + if (ret) { + 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!", + GetObjectName()); + return false; + } + + // 线程创建 + ret = pthread_create(&d->_thread, &d->_attr, ThreadFunction, this); + if (ret) { + LOG_ERROR("0x2215 Thread: %1 Create Failed!", GetObjectName()); + return false; + } + + // 设置亲和性 + if (!OnSetCPUAffinity()) { + return false; + } +#endif + + XNFrameworkPtr framework = GetFramework(); + if (!framework) { + LOG_WARNING("0x2216 Thread: %1 get Framework Failed!", GetObjectName()); + return true; + } + + XNDDSManagerPtr ddsManager = framework->GetDDSManager(); + if (!ddsManager) { + LOG_WARNING("0x2216 Thread: %1 get DDSManager Failed!", GetObjectName()); + return true; + } + + d->_writer = + ddsManager + ->RegisterPublisher( + "XNSim::XNSimStatus::XNThreadStatus", d->_threadID); + if (d->_writer == nullptr) { + LOG_WARNING("0x2217 Thread: %1 get DDS Writer Failed!", GetObjectName()); + return true; + } + LOG_INFO("Thread: %1 is prepared!", GetObjectName()); + return true; +} + +// 仿真控制 +void XNThreadObject::SimControl(XN_UINT32 objectId, SimControlCmd cmd) { + T_D(); + if (objectId == 0) { + switch (cmd) { + case SimControlCmd::Start: + Start(); + break; + case SimControlCmd::Suspend: + Pause(); + break; + case SimControlCmd::Continue: + Continue(); + break; + case SimControlCmd::Abort: + Stop(true); + break; + } + } +} + +// 开始执行 +void XNThreadObject::Start() { + T_D(); + XNThreadMutexLock(&d->_mtx); + // 设置运行状态 + if (d->_eRunStatus == RunStatus::NotStart || + d->_eRunStatus == RunStatus::Suspend) { + d->_eRunStatus = RunStatus::Runing; + } + XNThreadCVNotifyOne(&d->_cond); + XNThreadMutexUnlock(&d->_mtx); + LOG_INFO("Thread: %1 Start!", GetObjectName()); +} + +// 暂停执行 +void XNThreadObject::Pause() { + T_D(); + XNThreadMutexLock(&d->_mtx); + // 设置运行状态 + if (d->_eRunStatus == RunStatus::Runing) { + d->_eRunStatus = RunStatus::Suspend; + } + XNThreadMutexUnlock(&d->_mtx); + LOG_INFO("Thread: %1 Pause!", GetObjectName()); +} + +// 继续执行 +void XNThreadObject::Continue() { + T_D(); + XNThreadMutexLock(&d->_mtx); + // 设置运行状态 + if (d->_eRunStatus == RunStatus::Suspend) { + d->_eRunStatus = RunStatus::Runing; + } + XNThreadCVNotifyOne(&d->_cond); + XNThreadMutexUnlock(&d->_mtx); +} + +// 停止执行 +void XNThreadObject::Stop(bool force) { + T_D(); + if (force) { + XNThreadMutexLock(&d->_mtx); + // 设置运行状态 + d->_eRunStatus = RunStatus::Aborted; + XNThreadCVNotifyOne(&d->_cond); + XNThreadMutexUnlock(&d->_mtx); + Join(); + } else { + XNThreadMutexLock(&d->_mtx); + // 设置运行状态 + d->_eRunStatus = RunStatus::Finished; + XNThreadCVNotifyOne(&d->_cond); + XNThreadMutexUnlock(&d->_mtx); + Join(); + } + LOG_INFO("Thread: %1 Stop!", GetObjectName()); +} + +// 加入线程 +void XNThreadObject::Join() { + T_D(); + XNThreadJoin(d->_thread); +} + +// 分离线程 +void XNThreadObject::Detach() { + T_D(); + XNThreadDetach(d->_thread); +} + +// 获取线程运行状态 +RunStatus XNThreadObject::GetRunStatus() { + T_D(); + return d->_eRunStatus; +} + +// 向线程添加周期性函数 +void XNThreadObject::AddFunction(XNCallBack fun, FreqLevel freq, XN_UINT32 pos, + XN_UINT32 priorty) { + T_D(); + for (XN_INT32 i = 0; i < d->_funVec.size();) { + if (i + pos >= d->_funVec.size()) + break; + d->_funVec[i + pos][priorty].push_back(fun); + switch (freq) { + case FreqLevel::BaseFreq: + i++; + break; + case FreqLevel::HalfFreq: + i += 2; + break; + case FreqLevel::QuarterFreq: + i += 4; + break; + case FreqLevel::EighthFreq: + i += 8; + break; + case FreqLevel::SixteenthFreq: + i += 16; + break; + case FreqLevel::ThirtyTwothFreq: + i += 32; + break; + default: + i += 32; + break; + } + } +} + +// 获取线程运行频率 +const XN_DOUBLE &XNThreadObject::GetRunFrequecy() { + T_D(); + return d->_setFreq; +} + +// 设置线程运行频率 +void XNThreadObject::SetRunFrequecy(const XN_DOUBLE &dRunFrequecy) { + T_D(); + d->_setFreq = dRunFrequecy; + d->_pinfo.period_ns = 1.0E9 / dRunFrequecy; +} + +// 获取线程运行优先级 +const XN_UINT32 &XNThreadObject::GetRunPriority() { + T_D(); + return d->_uPriority; +} + +// 设置线程运行优先级 +void XNThreadObject::SetRunPriority(const XN_UINT32 &uRunPriority) { + T_D(); + d->_uPriority = uRunPriority; +} + +// 获取线程CPU亲和性掩码 +const XN_UINT32 &XNThreadObject::GetCPUAffinity() { + T_D(); + return d->_uAffinity; +} + +// 设置线程CPU亲和性掩码 +void XNThreadObject::SetCPUAffinity(const XN_UINT32 &uCPUAffinity) { + T_D(); + d->_uAffinity = uCPUAffinity; +} + +// 设置线程运行间隔 +void XNThreadObject::SetStartTime(const XN_TIMESPEC &startTime) { + T_D(); +#ifdef XN_WINDOWS + d->_lastRunTime = startTime; +#endif +#ifdef XN_LINUX + d->_pinfo.next_period = startTime; + d->_lastRunTime = startTime; +#endif +} + +// 执行线程CPU亲和性设置 +bool XNThreadObject::OnSetCPUAffinity() { + T_D(); +#ifdef XN_LINUX + cpu_set_t mask; + CPU_ZERO(&mask); + XN_INT32 cpuNum = sysconf(_SC_NPROCESSORS_CONF); + for (XN_INT32 i = 0; i < cpuNum; i++) { + if (((d->_uAffinity >> i) & 1) == 1) + CPU_SET(i, &mask); + } + if (pthread_setaffinity_np(d->_thread, sizeof(mask), &mask) == -1) { + LOG_WARNING("0x2216 线程: %1 设置CPU亲和性失败!", GetObjectName()); + return false; + } +#endif + return true; +} + +// 线程主执行函数 +#ifdef XN_WINDOWS +void XNThreadObject::ThreadFunction() { + T_D(); + XN_STRING name = GetObjectName(); +#endif +#ifdef XN_LINUX + void *XNThreadObject::ThreadFunction(void *args) { + // 获取创建线程类的私有变量结构体指针 + ThisType *thisPtr = (ThisType *)args; + auto d = thisPtr->GetPP(); + XN_STRING name = thisPtr->GetObjectName(); +#endif + while (1) { + // 加锁保护线程状态 + XNThreadMutexLock(&d->_mtx); + // 当处于notstart或suspend时准备挂起 + while (d->_eRunStatus == RunStatus::NotStart || + d->_eRunStatus == RunStatus::Suspend) { + // 如果挂起时切换为终止,则直接跳出 + if (d->_eRunStatus == RunStatus::Aborted || + d->_eRunStatus == RunStatus::Finished) { + XNThreadMutexUnlock(&d->_mtx); + break; + } + // 挂起线程 + XNThreadCVWait(&d->_cond, &d->_mtx); + } + // 如果为finished直接结束线程 + if (d->_eRunStatus == RunStatus::Finished) { + XNThreadMutexUnlock(&d->_mtx); + break; + } + // 解锁 + XNThreadMutexUnlock(&d->_mtx); + + // 任务执行 + auto &funMap = d->_funVec[d->_RunPosition++]; + for (auto &funv : funMap) { + for (auto &fun : funv.second) { + fun(); + } + } + d->_RunPosition %= d->_funVec.size(); + + // 如果为abort等待任务执行完成再结束 + XNThreadMutexLock(&d->_mtx); + if (d->_eRunStatus == RunStatus::Aborted) { + XNThreadMutexUnlock(&d->_mtx); + break; + } + XNThreadMutexUnlock(&d->_mtx); + + // 填写DDS主题数据 + XN_UINT32 setFreq = + (1.0E9 / d->_pinfo.period_ns) < 1.0 ? 1 : (XN_UINT32)d->_setFreq; + if (d->_writer != nullptr && d->_count > 0 && d->_count % setFreq == 0) { + XN_TIMESPEC now; + getCurrentRTTime(&now); + double seconds = calculateRTTime(&now, &d->_lastRunTime); + XNSim::XNSimStatus::XNThreadStatus threadStatus; + threadStatus.XNThreadName(name); + threadStatus.XNThreadID(XNThreadGetID()); + threadStatus.XNThreadSt((uint32_t)d->_eRunStatus); + threadStatus.XNThreadAff(d->_uAffinity); + threadStatus.XNThreadPro(d->_uPriority); + threadStatus.XNThRunCnt(d->_count); + threadStatus.XNThSetFreq(d->_setFreq); + threadStatus.XNThCurFreq(d->_setFreq / seconds); + d->_writer->write(&threadStatus); + d->_lastRunTime = now; + LOG_DEBUG("Thread: %1 Write DDS! SetFreq: %2 Hz, CurFreq: %3 Hz", name, + d->_setFreq, d->_setFreq / seconds); + } + d->_count++; + + sleepToNextRTTime(&d->_pinfo); + } +#ifdef XN_WINDOWS + } +#endif +#ifdef XN_LINUX + return nullptr; +} +#endif + +// 获取线程ID +const XN_UINT32 &XNThreadObject::GetThreadID() { + T_D(); + return d->_threadID; +} + +// 设置线程ID +void XNThreadObject::SetThreadID(const XN_UINT32 &threadID) { + T_D(); + d->_threadID = threadID; +} +} // namespace XNSim diff --git a/XNCore_Win/XNThreadObject/XNThreadObject.h b/XNCore_Win/XNThreadObject/XNThreadObject.h new file mode 100644 index 0000000..5048ab0 --- /dev/null +++ b/XNCore_Win/XNThreadObject/XNThreadObject.h @@ -0,0 +1,207 @@ +/** + * @file XNThreadObject.h + * @author jinchao + * @brief 调度线程类头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNObject/XNObject.h" + +namespace XNSim { +struct XNThreadObjectPrivate; + +/** + * @brief 调度线程类 + * @details 调度所有模型提交的周期性执行函数 + */ +class XNCORE_EXPORT XNThreadObject : public XNObject { + XN_METATYPE(XNThreadObject, XNObject) + XN_DECLARE_PRIVATE(XNThreadObject) + +public: + XNThreadObject() = delete; + + /** + * @brief 默认析构函数 + */ + virtual ~XNThreadObject(); + + explicit XNThreadObject(XN_STRING name = "", XN_DOUBLE freq = BASE_RUN_FREQ, + XN_UINT32 priority = 99, XN_UINT32 CPUAff = 0); + +public: + /** + * @brief 获取框架对象 + * @return 框架对象 + */ + XNFrameworkPtr GetFramework(); + + /** + * @brief 设置框架对象 + * @param framework 框架对象 + */ + void SetFramework(XNFrameworkPtr framework); + + /** + * @brief 线程初始化 + * @return true: 初始化成功 + * @return false: 初始化失败 + */ + XN_BOOL Initialize(); + + /** + * @brief 仿真控制 + * @param objectId: 对象ID + * @param cmd: 仿真控制命令 + */ + void SimControl(XN_UINT32 objectId, SimControlCmd cmd); + + /** + * @brief 设置线程运行的开始时间 + * @param simTime: timespec结构体类型,用于线程纳秒睡眠计算的开始时间 + * @details 通过设置统一的开始时间,使个线程能同步执行 + */ + void SetStartTime(const XN_TIMESPEC &simTime); + + /** + * @brief 加入线程 + * @details 等待线程结束 + */ + void Join(); + + /** + * @brief 线程脱离 + */ + void Detach(); + + /** + * @brief 获取线程ID + * @return const quint32&: 线程ID + */ + const XN_UINT32 &GetThreadID(); + + /** + * @brief 设置线程ID + * @param threadID: 线程ID + */ + void SetThreadID(const XN_UINT32 &threadID); + + /** + * @brief 获取运行状态 + * @return RunStatus: 运行状态枚举 + */ + RunStatus GetRunStatus(); + + /** + * @brief 获取线程运行频率 + * @return const double&:线程运行频率 + */ + const XN_DOUBLE &GetRunFrequecy(); + + /** + * @brief 设置线程运行频率 + * @param eRunFrequecy: double类型,线程运行频率 + */ + void SetRunFrequecy(const XN_DOUBLE &dRunFrequecy); + + /** + * @brief 获取线程运行优先级 + * @return const UINT32&:运行优先级,0~99,99最高 + */ + const XN_UINT32 &GetRunPriority(); + + /** + * @brief 设置线程运行优先级 + * @param uRunPriority: UINT32类型,运行优先级,0~99,99最高 + */ + void SetRunPriority(const XN_UINT32 &uRunPriority); + + /** + * @brief 设置线程CPU亲和性掩码 + * @return const UINT32&: + * CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + */ + const XN_UINT32 &GetCPUAffinity(); + + /** + * @brief 获取线程CPU亲和性掩码 + * @param uCPUAffinity: + * UINT32类型,CPU亲和性掩码,按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。 + * 例如:0x00000003表示使用0,1号CPU + */ + void SetCPUAffinity(const XN_UINT32 &uCPUAffinity); + + /** + * @brief 向线程添加周期性函数 + * @param fun:XNCallBack函数包装器类型,需要提交的函数的包装 + * @param freq:FreqLevel类型,提交的函数运行频率组 + * @param pos:UINT32类型,提交的函数运行节点号 + * @param + * priorty:UINT32类型,提交的函数运行优先级,99~0,优先级数值越大,优先级越高 + * @details 根据运行频率组和节点号向调度线程任务表中添加周期性函数 + */ + void AddFunction(XNCallBack fun, FreqLevel freq, XN_UINT32 pos, + XN_UINT32 priorty); + +private: + /** + * @brief 控制线程开始 + * @return true: 线程启动成功 + * @return false: 线程启动失败 + */ + void Start(); + + /** + * @brief 控制线程暂停 + * @return true: 线程暂停成功 + * @return false: 线程暂停失败 + */ + void Pause(); + + /** + * @brief 控制线程继续 + * @return true: 线程继续成功 + * @return false: 线程继续失败 + */ + void Continue(); + + /** + * @brief 控制线程停止 + * @param force:bool类型,true = 强制停止,flase = 等待当前认为结束后停止 + * @return true: 线程停止成功 + * @return false: 线程停止失败 + */ + void Stop(XN_BOOL force = false); + + /** + * @brief 执行线程CPU亲和性设置 + * @return true: 设置线程CPU亲和性成功 + * @return false: 设置线程CPU亲和性失败 + */ + XN_BOOL OnSetCPUAffinity(); + +#ifdef XN_WINDOWS + /** + * @brief 线程主执行函数 + * @param args: 线程执行函数输入参数指针 + * @return void*: 线程执行函数返回值指针 + */ + void ThreadFunction(); +#endif +#ifdef XN_LINUX + /** + * @brief 线程主执行函数 + * @param args: 线程执行函数输入参数指针 + * @return void*: 线程执行函数返回值指针 + */ + static void *ThreadFunction(void *args); +#endif +}; + +XNCLASS_PTR_DECLARE(XNThreadObject) +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNThreadObject/XNThreadObject_p.h b/XNCore_Win/XNThreadObject/XNThreadObject_p.h new file mode 100644 index 0000000..4ba8def --- /dev/null +++ b/XNCore_Win/XNThreadObject/XNThreadObject_p.h @@ -0,0 +1,102 @@ +#pragma once +#include "XNObject/XNObject_p.h" + +namespace XNSim { +/** + * @brief 线程类私有结构体 + */ +struct XNThreadObjectPrivate : public XNObjectPrivate { + /** + * @brief 框架对象 + */ + XNFrameworkPtr _framework; + /** + * @brief 线程运行优先级 + */ + XN_UINT32 _uPriority = 0; + /** + * @brief 线程CPU亲和性掩码 + * @details + * 按位表示某CPU核是否使用,从低到高,0表示不使用,1表示使用。例如:0x00000003表示使用0,1号CPU + */ + XN_UINT32 _uAffinity = 0; + /** + * @brief 线程运行频率 + */ + XN_DOUBLE _setFreq = BASE_RUN_FREQ; + /** + * @brief 线程调度任务表 + */ + std::vector>> _funVec; + +#ifdef XN_WINDOWS + /** + * @brief 线程 + */ + XN_THREAD _thread; + /** + * @brief 线程控制锁 + */ + XN_MUTEX _mutex; + /** + * @brief 线程控制锁 + */ + XN_THREAD_MUTEX _mtx = std::unique_lock(_mutex); + /** + * @brief 线程控制条件变量 + */ + XN_THREAD_CV _cond; +#endif + +#ifdef XN_LINUX + /** + * @brief pthread线程调度参数 + */ + XN_THREAD_SCHED_PARAM _param; + /** + * @brief pthread线程属性 + */ + XN_THREAD_ATTR _attr; + /** + * @brief pthread线程 + */ + XN_THREAD _thread; + /** + * @brief 线程控制锁 + */ + XN_THREAD_MUTEX _mtx = PTHREAD_MUTEX_INITIALIZER; + /** + * @brief 线程控制条件变量 + */ + XN_THREAD_CV _cond = PTHREAD_COND_INITIALIZER; +#endif + /** + * @brief 线程睡眠时间控制 + */ + PERIOD_INFO _pinfo; + /** + * @brief 线程运行状态 + */ + RunStatus _eRunStatus = RunStatus::NotStart; + /** + * @brief 线程执行进度 + */ + XN_UINT32 _RunPosition = 0; + /** + * @brief 线程执行计数 + */ + XN_INT32 _count = 0; + /** + * @brief 线程执行时间统计 + */ + XN_TIMESPEC _lastRunTime; + /** + * @brief 线程运行状态主题写入器 + */ + XN_DDS::DataWriter *_writer; + /** + * @brief 线程ID + */ + XN_UINT32 _threadID = 0; +}; +} // namespace XNSim diff --git a/XNCore_Win/XNTimeManager/CMakeLists.txt b/XNCore_Win/XNTimeManager/CMakeLists.txt new file mode 100644 index 0000000..431ed17 --- /dev/null +++ b/XNCore_Win/XNTimeManager/CMakeLists.txt @@ -0,0 +1,7 @@ +set(XNTIMEMANAGER_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/XNTimeManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNTimeManager_p.h + ${CMAKE_CURRENT_SOURCE_DIR}/XNTimeManager.cpp +) + +set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNTIMEMANAGER_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/XNCore_Win/XNTimeManager/XNTimeManager.cpp b/XNCore_Win/XNTimeManager/XNTimeManager.cpp new file mode 100644 index 0000000..386ab3f --- /dev/null +++ b/XNCore_Win/XNTimeManager/XNTimeManager.cpp @@ -0,0 +1,162 @@ +/** + * @file XNTimeManager.cpp + * @author jinchao + * @brief 时间管理器类源文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#include "XNTimeManager.h" +#include "XNDDSManager/XNDDSManager.h" +#include "XNFramework/XNFramework.h" +#include "XNIDL/XNSimStatusPubSubTypes.hpp" +#include "XNThreadManager/XNThreadManager.h" +#include "XNTimeManager_p.h" + + +namespace XNSim { +XNTimeManager::XNTimeManager() : XNBaseFrameObject(new XNTimeManagerPrivate()) { + SetUniqueId(enumValue(XNCoreObjectID::TimeManager)); + SetObjectName("XNTimeManager"); +} + +XNTimeManager::~XNTimeManager() {} + +XNTimeManager::XNTimeManager(PrivateType *p) : XNBaseFrameObject(p) {} + +std::chrono::system_clock::time_point XNTimeManager::GetSimTime() { + T_D(); + XNThreadMutexLock(&(d->_mtx)); + auto simTime = d->_SimTime; + XNThreadMutexUnlock(&(d->_mtx)); + return simTime; +} + +void XNTimeManager::SetStartTime(const XN_TIMESPEC &simTime) { + T_D(); +// 将timespec转换为chrono::system_clock::time_point +#ifdef XN_WINDOWS + auto duration = + std::chrono::duration_cast( + std::chrono::seconds(simTime.QuadPart) + + std::chrono::nanoseconds(simTime.QuadPart % 1000000000)); + d->_SimStartTime = std::chrono::system_clock::time_point(duration); +#endif +#ifdef XN_LINUX + auto duration = std::chrono::seconds(simTime.tv_sec) + + std::chrono::nanoseconds(simTime.tv_nsec); + d->_SimStartTime = std::chrono::system_clock::time_point(duration); +#endif +} + +void XNTimeManager::Start() { + T_D(); + if (d->_eRunStatus == RunStatus::NotStart) { + LOG_INFO("XNSim Start!"); + d->_eRunStatus = RunStatus::Runing; + } else { + LOG_WARNING("XNSim Already Start!"); + } +} + +void XNTimeManager::Abort() { + T_D(); + if (d->_eRunStatus != RunStatus::Aborted) { + LOG_INFO("XNSim Abort!"); + d->_eRunStatus = RunStatus::Aborted; + } else { + LOG_WARNING("XNSim Already Abort!"); + } +} + +void XNTimeManager::Pause() { + T_D(); + if (d->_eRunStatus == RunStatus::Runing) { + LOG_INFO("XNSim Pause!"); + d->_eRunStatus = RunStatus::Suspend; + } else { + LOG_WARNING("XNSim is not in Runing status!"); + } +} + +void XNTimeManager::Continue() { + T_D(); + if (d->_eRunStatus == RunStatus::Suspend) { + LOG_INFO("XNSim Continue!"); + d->_eRunStatus = RunStatus::Runing; + } else { + LOG_WARNING("XNSim is not in Pause status!"); + } +} + +RunStatus XNTimeManager::GetStatus() { + T_D(); + return d->_eRunStatus; +} + +void XNTimeManager::SimControl(XN_UINT32 objectId, SimControlCmd cmd) { + if (objectId == 0) { + switch (cmd) { + case SimControlCmd::Start: + Start(); + break; + case SimControlCmd::Abort: + Abort(); + break; + case SimControlCmd::Continue: + Continue(); + break; + case SimControlCmd::Suspend: + Pause(); + break; + } + } +} + +bool XNTimeManager::Initialize() { + T_D(); + // 时间管理器线程初始化 + // XNThreadManager *threadManager = parent()->findChild("XNThreadManager"); if (threadManager) { double dRunInter = + // threadManager->GetBaseInter() * 32; d->_TimeManagerThread = + // new XNThread(this, "TimeManagerThread", FreqLevel::ThirtyTwothFreq, 10, 0, + // dRunInter); } else { d->_status = XNFrameObjectStatus::Unknown; + // LOG_ERROR("XNTimeManager Initialize Failed!"); + // return; + // } + + // d->_TimeManagerThread->AddFunction(std::bind(&XNTimeManager::StepExecute, + // this), + // FreqLevel::ThirtyTwothFreq, 0, 90); + + // connect(this, &XNTimeManager::SimControl, d->_TimeManagerThread, + // &XNThread::OnSimControl); 运行状态初始化 + d->_eRunStatus = + RunStatus::NotStart; // d->_TimeManagerThread->GetRunStatus(); + // 仿真时间初始化 + d->_SimTime = d->_SimStartTime; + + LOG_INFO("XNTimeManager Initialize Success!"); + d->_status = XNFrameObjectStatus::Initialized; + return true; +} + +bool XNTimeManager::PrepareForExecute() { + T_D(); + d->_status = XNFrameObjectStatus::Ready; + LOG_INFO("XNTimeManager is prepared!"); + return true; +} + +void XNTimeManager::StepExecute() { + T_D(); + // TODO 提交事件 + // 时间推进 + XNThreadMutexLock(&(d->_mtx)); + d->_SimTime += + std::chrono::microseconds(static_cast(BASE_RUN_INTER * 1.0E6)); + XNThreadMutexUnlock(&(d->_mtx)); +} +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNTimeManager/XNTimeManager.h b/XNCore_Win/XNTimeManager/XNTimeManager.h new file mode 100644 index 0000000..ef4c153 --- /dev/null +++ b/XNCore_Win/XNTimeManager/XNTimeManager.h @@ -0,0 +1,115 @@ +/** + * @file XNTimeManager.h + * @author jinchao + * @brief 时间管理器类头文件 + * @version 1.0 + * @date 2024-11-10 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject.h" + +namespace XNSim { +struct XNTimeManagerPrivate; + +/** + * @brief 时间管理器类 + * @details + * 管理仿真系统运行时的时间,在仿真系统运行时同步步进时间信息,并产生系统运行事件 + */ +class XNCORE_EXPORT XNTimeManager : public XNBaseFrameObject { + XN_METATYPE(XNTimeManager, XNBaseFrameObject) + XN_DECLARE_PRIVATE(XNTimeManager) + +public: + /** + * @brief 构造函数 + */ + XNTimeManager(); + + /** + * @brief 析构函数 + */ + virtual ~XNTimeManager(); + +protected: + /** + * @brief 构造函数 + * @param p: 私有数据成员 + */ + XNTimeManager(PrivateType *p); + +public: + /** + * @brief 获取当前仿真时间 + * @return XNTimePoint: 当前仿真时间 + */ + XNTimePoint GetSimTime(); + + /** + * @brief 设置仿真开始时间 + * @param simTime: XN_TIMESPEC类型,仿真开始时间 + */ + void SetStartTime(const XN_TIMESPEC &simTime); + + /** + * @brief 开始控制 + * @details 控制时间管理器线程开始运行接口 + */ + void Start(); + + /** + * @brief 停止控制 + * @details 控制时间管理器线程停止运行接口 + */ + void Abort(); + + /** + * @brief 暂停控制 + * @details 控制时间管理器线程暂停运行接口 + */ + void Pause(); + + /** + * @brief 继续控制 + * @details 控制时间管理器线程继续运行接口 + */ + void Continue(); + + /** + * @brief 初始化时间管理器 + * @return true: 初始化成功 + * @return false: 初始化失败 + * @details 时间管理器的初始化接口函数 + */ + virtual XN_BOOL Initialize() override; + + /** + * @brief 仿真运行前最后处理 + * @note 时间管理器在开始执行前的准备工作 + */ + virtual XN_BOOL PrepareForExecute() override; + + /** + * @brief 仿真控制 + * @param objectId: 对象ID + * @param cmd: 仿真控制命令 + */ + void SimControl(XN_UINT32 objectId, SimControlCmd cmd); + + /** + * @brief 获取运行状态 + * @return RunStatus: 枚举类,时间管理器线程运行状态 + * @details 获取时间管理器线程运行状态接口 + */ + RunStatus GetStatus(); + +private: + /** + * @brief 时间管理器线程单步执行函数 + */ + void StepExecute(); +}; +} // namespace XNSim \ No newline at end of file diff --git a/XNCore_Win/XNTimeManager/XNTimeManager_p.h b/XNCore_Win/XNTimeManager/XNTimeManager_p.h new file mode 100644 index 0000000..7b709b7 --- /dev/null +++ b/XNCore_Win/XNTimeManager/XNTimeManager_p.h @@ -0,0 +1,41 @@ +/** + * @file XNTimeManager_p.h + * @author jinchao + * @brief 时间管理器类私有头文件 + * @version 1.0 + * @date 2024-11-07 + * + * @copyright Copyright (c) 2024 XN + * + */ +#pragma once +#include "XNBaseFrameObject/XNBaseFrameObject_p.h" +#include "XNThreadObject/XNThreadObject.h" + +namespace XNSim { +/** + * @brief 时间管理器类私有结构体 + */ +struct XNTimeManagerPrivate : public XNBaseFrameObjectPrivate { + /* + * @brief 仿真运行状态 + */ + RunStatus _eRunStatus; + /** + * @brief 仿真开始时间 + */ + XNTimePoint _SimStartTime; + /** + * @brief 当前仿真时间 + */ + XNTimePoint _SimTime; + /** + * @brief 时间管理器线程智能指针 + */ + XNThreadObjectPtr _TimeManagerThread; + /** + * @brief 时间管理器线程控制锁 + */ + XN_THREAD_MUTEX _mtx; +}; +} // namespace XNSim \ No newline at end of file