先上传一下抽象层代码

This commit is contained in:
zd383321154 2025-07-19 12:44:06 +08:00
parent 66b91c7aba
commit 033951ef60
85 changed files with 12962 additions and 0 deletions

149
XNCore_Win/CMakeLists.txt Normal file
View File

@ -0,0 +1,149 @@
cmake_minimum_required(VERSION 3.16)
project(XNCore LANGUAGES CXX)
#
set(THIRD_PARTY_DIR "I:/MyPrj/XNSim/ThirdPart")
# Windows32
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)

View File

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

View File

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

View File

@ -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 <XNObject/XNObject.h>
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

View File

@ -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 <XNObject/XNObject_p.h>
namespace XNSim {
/**
* @brief
*/
struct XNBaseFrameObjectPrivate : public XNObjectPrivate {
/**
* @brief
*/
XNFrameObjectStatus _status = XNFrameObjectStatus::NotReady;
/**
* @brief
*/
XNFrameworkPtr _framework;
};
} // namespace XNSim

View File

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

View File

@ -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 <fstream>
#include <streambuf>
#include <cerrno>
#include <tinyxml2.h>
// 默认构造函数
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<std::string> 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<std::string> 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<std::string> 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<std::string> 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;
}

View File

@ -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 <XNBaseFrameObject/XNBaseFrameObject.h>
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

View File

@ -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 <XNBaseFrameObject/XNBaseFrameObject_p.h>
namespace XNSim {
/**
* @brief
*/
struct XNScenarioManagerPrivate : public XNBaseFrameObjectPrivate {
/**
* @brief
*/
XN_STRING _ConfigName;
};
} // namespace XNSim

View File

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

View File

@ -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<std::mutex> 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<uint8_t>((currentPos >> 8) & 0xFF);
result[7] = static_cast<uint8_t>(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<std::mutex> lock(outDataMutex);
clearOutData();
for (auto &func : setByteArrayFunction) {
func(package, currentPos);
}
}
sendOutData();
}
std::unordered_map<std::string, std::string>
XNDDSInterface::getStringData(const std::vector<std::string> &varNames) {
std::unordered_map<std::string, std::string> result;
{
std::lock_guard<std::mutex> 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<std::string, std::string> &data) {
std::lock_guard<std::mutex> 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

View File

@ -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<XN_STRING, XN_STRING>;
using XNInterfaceList = std::vector<XN_STRING>;
using XNGetDataFunction = std::function<XN_STRING()>;
using XNSetDataFunction = std::function<void(XN_STRING)>;
using XNGetByteArrayFunction = std::function<XNByteArray(void)>;
using XNSetByteArrayFunction = std::function<void(XNByteArray, XN_UINT32 &)>;
using XNGetDataFunctionMap = std::unordered_map<XN_STRING, XNGetDataFunction>;
using XNSetDataFunctionMap = std::unordered_map<XN_STRING, XNSetDataFunction>;
using XNGetByteArrayFunctionMap = std::vector<XNGetByteArrayFunction>;
using XNSetByteArrayFunctionMap = std::vector<XNSetByteArrayFunction>;
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 <typename T> XNByteArray getByteArray(const XNDDSOptional<T> &data) {
XNByteArray result(getTypeSize<T>());
if constexpr (std::is_arithmetic_v<T>) {
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<T>) {
if (data) {
return getByteArrayFromStdArray(data.value());
} else {
T zero = {};
return getByteArrayFromStdArray(zero);
}
} else {
static_assert(
std::is_arithmetic_v<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见XNDDSInterface.cppline 78");
}
return result;
}
/**
* @brief
* @param data:
* @param byteArray:
*/
template <typename T>
void setByteArray(XNDDSOptional<T> &data, const XNByteArray &byteArray,
XN_UINT32 &pos) {
XN_UINT32 thisSize = getTypeSize<T>();
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>) {
T temp;
std::memcpy(&temp, thisArray.data(), sizeof(T));
data = temp;
} else if constexpr (is_array_v<T>) {
if (!data) {
data = T{};
}
setByteArrayFromStdArray(data.value(), thisArray);
} else {
static_assert(std::is_arithmetic_v<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
/**
* @brief
* @param data:
* @return
*/
template <typename T, XN_SIZE N>
XNByteArray getByteArrayFromStdArray(const std::array<T, N> &data) {
XNByteArray result(getTypeSize<T>() * N);
for (XN_SIZE i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
std::memcpy(result.data() + i * getTypeSize<T>(), &data[i],
getTypeSize<T>());
} else if constexpr (is_array_v<T>) {
XNByteArray subArray = getByteArrayFromStdArray(data[i]);
std::memcpy(result.data() + i * getTypeSize<T>(), subArray.data(),
getTypeSize<T>());
} else {
static_assert(std::is_arithmetic_v<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
return result;
}
/**
* @brief
* @param data:
* @param byteArray:
*/
template <typename T, XN_SIZE N>
void setByteArrayFromStdArray(std::array<T, N> &data,
const XNByteArray &byteArray) {
if (byteArray.size() < getTypeSize<T>() * N)
return;
for (XN_SIZE i = 0; i < N; ++i) {
if constexpr (std::is_arithmetic_v<T>) {
std::memcpy(&data[i], byteArray.data() + i * getTypeSize<T>(),
getTypeSize<T>());
} else if constexpr (is_array_v<T>) {
XNByteArray subArray(byteArray.data() + i * getTypeSize<T>(),
getTypeSize<T>());
setByteArrayFromStdArray(data[i], subArray);
} else {
static_assert(std::is_arithmetic_v<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
}
/**
* @brief JSON前端
* @param data:
* @return:
*/
template <typename T> std::string getString(const XNDDSOptional<T> &data) {
if constexpr (std::is_arithmetic_v<T>) {
if (data) {
return std::to_string(data.value());
} else {
return "Unknown";
}
} else if constexpr (is_array_v<T>) {
if (data) {
return getStringFromStdArray(data.value());
} else {
T zero = {};
return getStringFromStdArray(zero);
}
} else {
static_assert(std::is_arithmetic_v<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
return std::string();
}
/**
* @brief JSON前端
* @param data:
* @param value:
*/
template <typename T>
void setDataFromString(XNDDSOptional<T> &data, const std::string &value) {
if constexpr (std::is_arithmetic_v<T>) {
if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>) {
data = std::stod(value);
} else {
data = std::stoll(value);
}
} else if constexpr (is_array_v<T>) {
// 解析输入字符串
std::stringstream ss(value);
std::string item;
std::vector<std::string> 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<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
/**
* @brief JSON前端
* @param data:
* @return:
*/
template <typename T, XN_SIZE N>
std::string getStringFromStdArray(const std::array<T, N> &data) {
std::stringstream ss;
for (XN_SIZE i = 0; i < N; ++i) {
if (i > 0)
ss << ",";
if constexpr (std::is_arithmetic_v<T>) {
ss << data[i];
} else if constexpr (is_array_v<T>) {
ss << getStringFromStdArray(data[i]);
} else {
static_assert(std::is_arithmetic_v<T> || is_array_v<T>,
"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 <typename T, XN_SIZE N>
size_t setStdArrayFromString(std::array<T, N> &data,
const std::vector<std::string> &value,
size_t start_pos = 0) {
// 递归处理每个元素
for (XN_SIZE i = 0; i < N; ++i) {
try {
if constexpr (std::is_arithmetic_v<T>) {
// 对于基本类型,直接转换
if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double>) {
data[i] = static_cast<T>(std::stod(value[start_pos + i]));
} else {
data[i] = static_cast<T>(std::stoll(value[start_pos + i]));
}
} else if constexpr (is_array_v<T>) {
// 对于嵌套数组,递归处理
start_pos = setStdArrayFromString(data[i], value, start_pos);
} else {
static_assert(
std::is_arithmetic_v<T> || is_array_v<T>,
"T 必须是算术类型或std::array类型详见XNDDSInterface.cppline "
"275");
}
} catch (const std::exception &e) {
throw std::runtime_error("无法解析第 " + std::to_string(i) +
" 个元素: " + e.what());
}
}
return start_pos + N;
}
template <typename T1, typename T2>
void assign_value_get(const XNDDSOptional<T1> &data, T2 &model_data) {
if (data) {
auto temp = data.value();
if constexpr (std::is_arithmetic_v<T1>) {
static_assert(std::is_arithmetic_v<T2>,
"模板参数T2必须是算术类型详见" + XN_STRING(__FILE__) +
":" + XN_STRING(__LINE__));
static_assert(std::is_convertible_v<T1, T2>,
"模板参数T1必须可以转换为T2类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
model_data = temp;
} else if constexpr (is_array_v<T1>) {
XN_SIZE arraySize = array_size_v<T1>;
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<array_type>) {
model_data[i] = temp2;
} else if constexpr (is_array_v<array_type>) {
XN_SIZE arraySize2 = array_size_v<array_type>;
using sub_array_type = typename array_type::value_type;
if constexpr (std::is_arithmetic_v<sub_array_type>) {
for (XN_SIZE j = 0; j < arraySize2; ++j) {
model_data[i][j] = temp2[j];
}
} else {
static_assert(std::is_arithmetic_v<sub_array_type>,
"模板参数T1是std::"
"array类型时它的数组嵌套不能超过两层详见" +
XN_STRING(__FILE__) + ":" +
XN_STRING(__LINE__));
}
} else {
static_assert(std::is_arithmetic_v<array_type> ||
is_array_v<array_type>,
"模板参数T1是std::array类型时它的value_"
"type必须是算术类型或std::"
"array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
} else {
static_assert(std::is_arithmetic_v<T1> || is_array_v<T1>,
"模板参数T1必须是算术类型或std::"
"array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
}
template <typename T1, typename T2>
void assign_value_set(XNDDSOptional<T1> &data, const T2 &model_data) {
if constexpr (std::is_arithmetic_v<T1>) {
static_assert(std::is_arithmetic_v<T2>, "模板参数T2必须是算术类型详见" +
XN_STRING(__FILE__) + ":" +
XN_STRING(__LINE__));
static_assert(std::is_convertible_v<T2, T1>,
"模板参数T2必须可以转换为T1类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
data = model_data;
} else if constexpr (is_array_v<T1>) {
T1 temp;
XN_SIZE arraySize = array_size_v<T1>;
using array_type = typename T1::value_type;
for (XN_SIZE i = 0; i < arraySize; ++i) {
if constexpr (std::is_arithmetic_v<array_type>) {
temp[i] = model_data[i];
} else if constexpr (is_array_v<array_type>) {
XN_SIZE arraySize2 = array_size_v<array_type>;
using sub_array_type = typename array_type::value_type;
if constexpr (std::is_arithmetic_v<sub_array_type>) {
for (XN_SIZE j = 0; j < arraySize2; ++j) {
temp[i][j] = model_data[i][j];
}
} else {
static_assert(std::is_arithmetic_v<sub_array_type>,
"模板参数T1是std::"
"array类型时它的数组嵌套不能超过两层详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
} else {
static_assert(std::is_arithmetic_v<array_type> ||
is_array_v<array_type>,
"模板参数T1是std::array类型时它的value_"
"type必须是算术类型或std::"
"array类型详见" +
XN_STRING(__FILE__) + ":" + XN_STRING(__LINE__));
}
}
data = temp;
} else {
static_assert(std::is_arithmetic_v<T1> || is_array_v<T1>,
"模板参数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); \
});

View File

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

View File

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

View File

@ -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 <typename T>
XNDDSDataWriterPtr RegisterPublisher(const XN_STRING &topicName,
XN_UINT32 publisherID) {
T_D();
std::lock_guard<std::mutex> lock(d->mutex_);
if (d->topics_.find(topicName) == d->topics_.end()) {
d->topics_[topicName] = TopicInfo();
TopicInfo &tmp = d->topics_[topicName];
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 <typename T>
void RegisterSubscriber(const XN_STRING &topicName, XN_UINT32 subscriberID,
XNDDSCallBack<typename T::type> fun) {
T_D();
std::lock_guard<std::mutex> lock(d->mutex_);
if (d->topics_.find(topicName) == d->topics_.end()) {
d->topics_[topicName] = TopicInfo();
TopicInfo &tmp = d->topics_[topicName];
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<typename T::type>(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

View File

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

View File

@ -0,0 +1,296 @@
#include "XNEventManager.h"
#include "XNEventManager_p.h"
#include "XNFramework.h"
#include <algorithm>
#include <thread>
// 构造函数
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<std::mutex> 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<std::mutex> 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<EventHandlerInfo> handlers;
{
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> lock(d->taskMutex);
// 停止现有线程
d->running = false;
d->taskCond.notify_all();
for (auto &thread : d->workerThreads) {
if (thread.joinable()) {
thread.join();
}
}
d->workerThreads.clear();
// 创建新线程
d->running = true;
for (int i = 0; i < count; ++i) {
d->workerThreads.emplace_back([this, d]() {
while (d->running) {
BaseEventTask *task = nullptr;
{
std::unique_lock<std::mutex> lock(d->taskMutex);
d->taskCond.wait(
lock, [this, d] { return !d->taskQueue.empty() || !d->running; });
if (!d->running) {
break;
}
task = d->taskQueue.front();
d->taskQueue.pop();
}
if (task) {
task->execute();
delete task;
}
}
});
}
LOG_INFO("Set thread pool max thread count to " + std::to_string(count));
}
int XNEventManager::GetMaxThreadCount() const {
T_D();
std::lock_guard<std::mutex> lock(d->taskMutex);
return d->workerThreads.size();
}
void XNEventManager::WaitForAsyncEvents() {
T_D();
std::unique_lock<std::mutex> lock(d->taskMutex);
d->taskCond.wait(lock, [this, d] { return d->taskQueue.empty(); });
LOG_INFO("All async events have been processed");
}
// 初始化事件管理器
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"));
}

View File

@ -0,0 +1,80 @@
#pragma once
#include <XNBaseFrameObject/XNBaseFrameObject.h>
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

View File

@ -0,0 +1,242 @@
#pragma once
#include "XNBaseFrameObject_p.h"
#include "XNEventManager.h"
#include <functional>
#include <sys/types.h>
#include <bits/pthreadtypes.h>
#include <bits/sched.h>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <string>
#include <any>
#include <map>
#include <list>
// 事件处理器信息结构
struct EventHandlerInfo {
std::function<void(const std::any &)> 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<void(const std::any &)> 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<void(const std::any &)> 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<void(const std::any &)> 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<void(const std::any &)> 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, &param);
// 设置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<std::mutex> lock(taskMutex);
taskQueue.push(task);
taskCond.notify_one();
}
private:
static void *threadFunction(void *arg)
{
auto manager = static_cast<RTThreadManager *>(arg);
manager->processTask();
return nullptr;
}
void processTask()
{
while (running) {
RTEventTask *task = nullptr;
{
std::unique_lock<std::mutex> 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<pthread_t> threads;
std::queue<RTEventTask *> taskQueue;
std::mutex taskMutex;
std::condition_variable taskCond;
};
// 事件管理器的私有实现类
struct XNEventManagerPrivate : public XNBaseFrameObjectPrivate {
// 存储事件及其对应的处理器信息列表
// key: 事件名称
// value: 该事件对应的所有处理器信息列表
std::map<std::string, std::list<EventHandlerInfo>> eventHandlers;
// 处理器ID到事件名称的反向映射用于快速查找
std::map<int, std::string> handlerToEvent;
// 本地ID计数器
int localIdCounter = 0;
// 互斥锁,用于保护事件处理器表的线程安全访问
std::mutex eventMutex;
// 线程池相关
std::vector<std::thread> workerThreads;
std::queue<BaseEventTask *> taskQueue;
std::mutex taskMutex;
std::condition_variable taskCond;
bool running = true;
RTThreadManager rtManager;
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,100 @@
#pragma once
#include "XNCore_global.h"
#include "XNType.h"
#include <vector>
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<XN_UINT8> data_;
};
} // namespace XNSim

View File

@ -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 <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(__linux__)
#define XN_LINUX
#include <dlfcn.h>
#include <errno.h>
#include <limits.h>
#include <pthread.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <unistd.h>
#endif

View File

@ -0,0 +1,76 @@
#pragma once
// FastDDS头文件
#include <fastcdr/xcdr/optional.hpp>
#include <fastdds/dds/domain/DomainParticipant.hpp>
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/publisher/DataWriter.hpp>
#include <fastdds/dds/publisher/Publisher.hpp>
#include <fastdds/dds/subscriber/DataReader.hpp>
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
#include <fastdds/dds/subscriber/Subscriber.hpp>
#include <fastdds/dds/topic/TypeSupport.hpp>
#include <functional>
// FastDDS宏定义
#define XN_DDS eprosima::fastdds::dds
namespace XNSim {
template <typename T> using XNDDSOptional = eprosima::fastcdr::optional<T>;
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<XN_STRING, XNDDSPublisherPtr>;
using XNDDSSubscriberMap = std::unordered_map<XN_STRING, XNDDSSubscriberPtr>;
using XNDDSDataWriterMap = std::unordered_map<XN_STRING, XNDDSDataWriterPtr>;
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<XN_STRING, TopicInfo>;
template <typename T> using XNDDSCallBack = std::function<void(const T &)>;
template <typename T>
class DataReaderListenerImpl : public XN_DDS::DataReaderListener {
public:
DataReaderListenerImpl(XNDDSCallBack<T> 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<T> callback_;
};
} // namespace XNSim

View File

@ -0,0 +1,60 @@
#pragma once
// sqlite3头文件
#include "XNCore_global.h"
#include "XNString.h"
#include "XNType.h"
#include <sqlite3.h>
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<const char *>(sqlite3_column_text(stmt, column));
if (text == nullptr) {
return "";
}
return XN_STRING(text);
}
} // namespace XNSim

View File

@ -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 <cstddef>
#include <cstring>
#include <initializer_list>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
/**
* @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

View File

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

View File

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

View File

@ -0,0 +1,41 @@
#pragma once
#include "XNCore_global.h"
#include "XNString.h"
#include "XNType.h"
#include <filesystem>
#include <fstream>
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

View File

@ -0,0 +1,17 @@
#pragma once
// json头文件
#include "XNCore_global.h"
#include "XNString.h"
#include <nlohmann/json.hpp>
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

View File

@ -0,0 +1,42 @@
#pragma once
#include "XNCore_global.h"
#include <memory>
namespace XNSim {
template <typename T>
using XN_ENABLE_SHARED_FROM_THIS = std::enable_shared_from_this<T>;
// 静态指针类型转换辅助函数
template <class ToType, class FromType>
FORCEINLINE ToType XNStaticCastHelper(const FromType &from) {
return std::static_pointer_cast<typename ToType::element_type>(from);
}
// 动态指针类型转换辅助函数
template <class ToType, class FromType>
FORCEINLINE ToType XNCastHelper(const FromType &from) {
return std::dynamic_pointer_cast<typename ToType::element_type>(from);
}
} // namespace XNSim
// 静态类型转换宏
#define XN_CAST(from, to) XNStaticCastHelper<to>(from)
// 获取当前对象的智能指针
#define XN_THISPTR std::static_pointer_cast<ThisType>(shared_from_this())
// 类智能指针声明宏
#define XNCLASS_PTR_DECLARE(a) \
using a##Ptr = std::shared_ptr<class a>; \
using a##WPtr = std::weak_ptr<class a>; \
using a##UPtr = std::unique_ptr<class a>; \
using a##ConsPtr = std::shared_ptr<const class a>;
// 结构体智能指针声明宏
#define XNSTRUCT_PTR_DECLARE(a) \
using a##Ptr = std::shared_ptr<struct a>; \
using a##WPtr = std::weak_ptr<struct a>; \
using a##UPtr = std::unique_ptr<struct a>; \
using a##ConsPtr = std::shared_ptr<const struct a>;

View File

@ -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<Class##Private *>(_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

View File

@ -0,0 +1,73 @@
#pragma once
#include "XNCore_global.h"
#include "XNType.h"
#include <string>
#include <vector>
namespace XNSim {
// 字符串类型抽象
using XN_STRING = std::string;
using XN_WSTRING = std::wstring;
using XN_STRINGLIST = std::vector<XN_STRING>;
using XN_WSTRINGLIST = std::vector<XN_WSTRING>;
// 字符串转换辅助函数
template <typename T> FORCEINLINE XN_STRING To_XNString(const T &value) {
return std::to_string(value);
}
template <typename T> 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

View File

@ -0,0 +1,108 @@
#pragma once
#include <XNGlobalDefine/XNCore_global.h>
#include <any>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
#ifdef XN_LINUX
#include <pthread.h>
#endif
namespace XNSim {
// 线程相关抽象
using XN_MUTEX = std::mutex;
#ifdef XN_WINDOWS
using XN_THREAD = std::thread;
using XN_THREAD_MUTEX = std::unique_lock<std::mutex>;
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<void()>;
// 事件回调函数类型别名
using XNEventCallback = std::function<void(const std::any &)>;
} // namespace XNSim

View File

@ -0,0 +1,99 @@
#pragma once
#include "XNCore_global.h"
#include "XNString.h"
#include "XNType.h"
#include <chrono>
#include <iomanip>
#include <sstream>
#include <time.h>
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

View File

@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
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<bool>;
using XN_ANY = std::any;
} // namespace XNSim

View File

@ -0,0 +1,71 @@
#pragma once
#include <array>
#include <stdexcept>
#include <type_traits>
namespace XNSim {
// 类型检查
template <typename T, typename U>
inline constexpr bool is_same_v = std::is_same_v<T, U>;
// 算术类型检查
template <typename T>
inline constexpr bool is_arithmetic_v = std::is_arithmetic_v<T>;
// 可转换类型检查
template <typename T, typename U>
inline constexpr bool is_convertible_v = std::is_convertible_v<T, U>;
// 数组类型检查
namespace TypeTraits {
template <typename T> struct is_std_array : std::false_type {};
template <typename T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};
} // namespace TypeTraits
// 数组类型检查简化使用
template <typename T>
inline constexpr bool is_array_v = TypeTraits::is_std_array<T>::value;
// 获取数组大小
namespace TypeTraits {
template <typename T>
struct array_size : std::integral_constant<std::size_t, 1> {};
template <typename T, std::size_t N>
struct array_size<std::array<T, N>> : std::integral_constant<std::size_t, N> {};
} // namespace TypeTraits
// 获取数组大小简化使用
template <typename T>
inline constexpr std::size_t array_size_v = TypeTraits::array_size<T>::value;
// 获取类型大小
template <typename T> constexpr size_t getTypeSize() {
if constexpr (is_array_v<T>) {
// 对于std::array计算所有元素的总大小
return getTypeSize<typename T::value_type>() * array_size_v<T>;
} else {
return sizeof(T);
}
}
// 获取数组总大小
template <typename T> constexpr std::size_t arrayTotalSize(const T &arr) {
if constexpr (is_array_v<T>) {
// 对于std::array计算所有元素的总大小
return getTypeSize<typename T::value_type>() * array_size_v<T>;
} else {
return 1;
}
}
// 枚举值获取函数
template <typename T>
constexpr typename std::underlying_type<T>::type enumValue(T e) {
return static_cast<typename std::underlying_type<T>::type>(e);
}
} // namespace XNSim

View File

@ -0,0 +1,43 @@
#pragma once
// tinyxml2头文件
#include "XNCore_global.h"
#include "XNString.h"
#include <tinyxml2.h>
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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -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 <fastcdr/Cdr.h>
#include <fastcdr/CdrSizeCalculator.hpp>
#include <fastcdr/exceptions/BadParamException.h>
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<void>(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<void>(scdr);
static_cast<void>(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<void>(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<void>(scdr);
static_cast<void>(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<void>(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<void>(scdr);
static_cast<void>(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<void>(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<void>(scdr);
static_cast<void>(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<void>(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<void>(scdr);
static_cast<void>(data);
scdr << data.XNSimCmd();
scdr << data.XNThrCmd();
}
} // namespace fastcdr
} // namespace eprosima
#endif // FAST_DDS_GENERATED__XNSIM_XNSIMCONTROL_XNSIMSTATUSCDRAUX_IPP

View File

@ -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 <fastdds/dds/log/Log.hpp>
#include <fastdds/rtps/common/CdrSerialization.hpp>
#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<uint32_t>(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<unsigned char*>(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<const XNCoreStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(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<XNCoreStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const XNCoreStatus*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* XNCoreStatusPubSubType::create_data()
{
return reinterpret_cast<void*>(new XNCoreStatus());
}
void XNCoreStatusPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<XNCoreStatus*>(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<void*>(&data)))
{
return compute_key(static_cast<void*>(&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<const XNCoreStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<unsigned int>(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<uint32_t>(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<unsigned char*>(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<const XNEngineStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(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<XNEngineStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const XNEngineStatus*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* XNEngineStatusPubSubType::create_data()
{
return reinterpret_cast<void*>(new XNEngineStatus());
}
void XNEngineStatusPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<XNEngineStatus*>(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<void*>(&data)))
{
return compute_key(static_cast<void*>(&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<const XNEngineStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<unsigned int>(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<uint32_t>(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<unsigned char*>(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<const XNThreadStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(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<XNThreadStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const XNThreadStatus*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* XNThreadStatusPubSubType::create_data()
{
return reinterpret_cast<void*>(new XNThreadStatus());
}
void XNThreadStatusPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<XNThreadStatus*>(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<void*>(&data)))
{
return compute_key(static_cast<void*>(&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<const XNThreadStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<unsigned int>(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<uint32_t>(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<unsigned char*>(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<const XNModelStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(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<XNModelStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const XNModelStatus*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* XNModelStatusPubSubType::create_data()
{
return reinterpret_cast<void*>(new XNModelStatus());
}
void XNModelStatusPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<XNModelStatus*>(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<void*>(&data)))
{
return compute_key(static_cast<void*>(&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<const XNModelStatus*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<unsigned int>(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<uint32_t>(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<unsigned char*>(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<const XNRuntimeControl*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(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<XNRuntimeControl*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<uint32_t>(calculator.calculate_serialized_size(
*static_cast<const XNRuntimeControl*>(data), current_alignment)) +
4u /*encapsulation*/;
}
catch (eprosima::fastcdr::exception::Exception& /*exception*/)
{
return 0;
}
}
void* XNRuntimeControlPubSubType::create_data()
{
return reinterpret_cast<void*>(new XNRuntimeControl());
}
void XNRuntimeControlPubSubType::delete_data(
void* data)
{
delete(reinterpret_cast<XNRuntimeControl*>(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<void*>(&data)))
{
return compute_key(static_cast<void*>(&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<const XNRuntimeControl*>(data);
// Object that manages the raw buffer.
eprosima::fastcdr::FastBuffer fastbuffer(reinterpret_cast<char*>(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<unsigned int>(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"

View File

@ -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 <fastdds/dds/core/policy/QosPolicies.hpp>
#include <fastdds/dds/topic/TopicDataType.hpp>
#include <fastdds/rtps/common/InstanceHandle.hpp>
#include <fastdds/rtps/common/SerializedPayload.hpp>
#include <fastdds/utils/md5.hpp>
#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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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<void>(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

File diff suppressed because it is too large Load Diff

View File

@ -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 <fastdds/dds/xtypes/type_representation/TypeObject.hpp>
#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

View File

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

View File

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

View File

@ -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 <XNGlobalDefine/XNDefine.h>
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 <typename... Args>
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 <typename T> static XN_STRING convertToString(const T &arg) {
if constexpr (XNSim::is_arithmetic_v<T>) {
return std::to_string(arg); // 处理数值类型
} else if constexpr (XNSim::is_same_v<T, XN_STRING>) {
return arg;
} else if constexpr (XNSim::is_convertible_v<T, XN_STRING>) {
return XN_STRING(arg);
} else if constexpr (XNSim::is_same_v<T, char *> ||
XNSim::is_same_v<T, const char *>) {
return XN_STRING(arg);
} else {
static_assert(XNSim::is_arithmetic_v<T> ||
XNSim::is_same_v<T, XN_STRING> ||
XNSim::is_convertible_v<T, XN_STRING> ||
XNSim::is_same_v<T, XN_CHAR *> ||
XNSim::is_same_v<T, const XN_CHAR *>,
"A01021001: 不支持的类型转换详见XNLogger.cppline 199");
}
}
/**
* @brief %1%2%3
* @tparam Args
* @param message
* @param args
* @return
*/
template <typename... Args>
static XN_STRING formatMessage(const XN_STRING &message, Args &&...args) {
static_assert(
sizeof...(Args) <= 9,
"A01021002: 单条日志参数数量超过限制详见XNLogger.cppline 216");
XN_STRING result = message;
// 使用初始化列表展开参数包
int index = 1;
// 使用lambda和std::initializer_list展开参数包
(void)std::initializer_list<int>{(
[&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__)

View File

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

View File

@ -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();
// 从1000019999的编号中分配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

View File

@ -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
* 仿IDID访问或控制该模型
*/
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类型0121/431/841/1651/32
* @param RunPos: UINT32类型<2^(freqGroup)
* @param RunPriorty:
* UINT32类型990
*/
void RegisterFunction(XN_UINT32 id, XNCallBack fun, XN_UINT32 threadID,
XN_UINT32 freqGroup, XN_UINT32 RunPos,
XN_UINT32 RunPriorty);
};
} // namespace XNSim

View File

@ -0,0 +1,19 @@
#pragma once
#include "XNBaseFrameObject/XNBaseFrameObject_p.h"
namespace XNSim {
using XNModelMap = std::map<XN_UINT32, XNModelObjectPtr>;
struct XNModelManagerPrivate : public XNBaseFrameObjectPrivate {
/**
* @brief ID库
* @details ID的存储库
*/
XNAsignedIDFlag ModelIDAssigned;
/**
* @brief ID与模型指针的映射表
* @details ID与模型指针的映射表
*/
XNModelMap ModelMap;
};
} // namespace XNSim

View File

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

View File

@ -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::XNModelStatusPubSubType>(
"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

View File

@ -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<XNSim::ClassName>(); \
return obj; \
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
// 从2000029999的编号中分配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

View File

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

View File

@ -0,0 +1,20 @@
#pragma once
#include "XNBaseFrameObject/XNBaseFrameObject_p.h"
namespace XNSim {
using XNServiceMap = std::map<XN_UINT32, XNServiceObjectPtr>;
struct XNServiceManagerPrivate : public XNBaseFrameObjectPrivate {
/**
* @brief ID库
* @details ID的存储库
*/
XNAsignedIDFlag ServiceIDAssigned;
/**
* @brief
* @details
*/
XNServiceMap ServiceList;
};
} // namespace XNSim

View File

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

View File

@ -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<std::string>());
// TODO: 处理服务命令信息
// d->_commandList.emplace_back(
// cmd["Name"].get<std::string>(),
// cmd["Description"].get<std::string>(),
// cmd["Call"].get<std::string>()
// );
}
}
}
} 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

View File

@ -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<XNSim::ClassName>(); \
return obj; \
}

View File

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

View File

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

View File

@ -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<XNFunInfo>();
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) {
// 如果频率分组不是05
LOG_WARNING("0x2170 The submitted function's run frequency group of Model "
"[ %1 ] is not "
"between 0 and 5, registration failed!",
id);
return false;
} else if (RunPos > (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<XNThreadObject>(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

View File

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

View File

@ -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<XNFunInfo>;
using XNFunInfoMap = std::map<XN_UINT32, std::vector<XNFunInfoPtr>>;
using XNThreadMap = std::map<XN_UINT32, XNThreadObjectPtr>;
using XNThreadIDSet = std::set<XN_UINT32>;
/**
* @brief 线
*/
struct XNThreadManagerPrivate : public XNBaseFrameObjectPrivate {
/**
* @brief 线
*/
RunStatus _eRunStatus;
/**
* @brief 线
*/
XNThreadMap _threadList;
/**
* @brief
*/
XNFunInfoMap _funList;
/**
* @brief 线ID
*/
XNThreadIDSet _threadIDMap;
};
} // namespace XNSim

View File

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

View File

@ -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::XNThreadStatusPubSubType>(
"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

View File

@ -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&:09999
*/
const XN_UINT32 &GetRunPriority();
/**
* @brief 线
* @param uRunPriority: UINT32类型09999
*/
void SetRunPriority(const XN_UINT32 &uRunPriority);
/**
* @brief 线CPU亲和性掩码
* @return const UINT32&:
* CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
const XN_UINT32 &GetCPUAffinity();
/**
* @brief 线CPU亲和性掩码
* @param uCPUAffinity:
* UINT32类型CPU亲和性掩码CPU核是否使用0使1使
* 0x00000003使0,1CPU
*/
void SetCPUAffinity(const XN_UINT32 &uCPUAffinity);
/**
* @brief 线
* @param fun:XNCallBack函数包装器类型
* @param freq:FreqLevel类型
* @param pos:UINT32类型
* @param
* priorty:UINT32类型990
* @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

View File

@ -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,1CPU
*/
XN_UINT32 _uAffinity = 0;
/**
* @brief 线
*/
XN_DOUBLE _setFreq = BASE_RUN_FREQ;
/**
* @brief 线
*/
std::vector<std::map<XN_UINT32, std::vector<XNCallBack>>> _funVec;
#ifdef XN_WINDOWS
/**
* @brief 线
*/
XN_THREAD _thread;
/**
* @brief 线
*/
XN_MUTEX _mutex;
/**
* @brief 线
*/
XN_THREAD_MUTEX _mtx = std::unique_lock<XN_MUTEX>(_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

View File

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

View File

@ -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::system_clock::duration>(
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
// *>("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<int64_t>(BASE_RUN_INTER * 1.0E6));
XNThreadMutexUnlock(&(d->_mtx));
}
} // namespace XNSim

View File

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

View File

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