添加win32支持,重构XNCore模块结构
This commit is contained in:
parent
069ea0ea37
commit
e6392c5228
1
.gitignore
vendored
1
.gitignore
vendored
@ -39,3 +39,4 @@ build/
|
||||
log/
|
||||
logs/
|
||||
Packages/
|
||||
ThirdPart/
|
||||
|
23
XNCore/.vscode/settings.json
vendored
23
XNCore/.vscode/settings.json
vendored
@ -81,6 +81,27 @@
|
||||
"unordered_set": "cpp",
|
||||
"fstream": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"valarray": "cpp"
|
||||
"valarray": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"charconv": "cpp",
|
||||
"format": "cpp",
|
||||
"ios": "cpp",
|
||||
"locale": "cpp",
|
||||
"queue": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp"
|
||||
}
|
||||
}
|
@ -2,86 +2,130 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(XNCore LANGUAGES CXX)
|
||||
|
||||
# 第三方库路径(需要根据实际情况修改)
|
||||
set(THIRD_PARTY_DIR "I:/MyPrj/XNSim/ThirdPart")
|
||||
|
||||
# Windows平台设置32位编译
|
||||
if(WIN32)
|
||||
set(CMAKE_GENERATOR_PLATFORM "Win32" CACHE STRING "Target platform" FORCE)
|
||||
set(CMAKE_VS_PLATFORM_NAME "Win32" CACHE STRING "Win32/x64 build." FORCE)
|
||||
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE)
|
||||
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS FALSE)
|
||||
|
||||
set(CMAKE_SIZEOF_VOID_P 4)
|
||||
|
||||
add_definitions(-DWIN32 -D_WINDOWS)
|
||||
|
||||
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if(WIN32)
|
||||
# 设置OpenSSL路径(使用缓存变量)
|
||||
set(OPENSSL_ROOT_DIR "${THIRD_PARTY_DIR}/openssl" CACHE PATH "OpenSSL root directory")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include" CACHE PATH "OpenSSL include directory")
|
||||
set(OPENSSL_LIBRARIES "${OPENSSL_ROOT_DIR}/lib" CACHE PATH "OpenSSL library directory")
|
||||
set(OPENSSL_CRYPTO_LIBRARY "${OPENSSL_ROOT_DIR}/lib/libcrypto.lib" CACHE FILEPATH "OpenSSL crypto library")
|
||||
set(OPENSSL_SSL_LIBRARY "${OPENSSL_ROOT_DIR}/lib/libssl.lib" CACHE FILEPATH "OpenSSL ssl library")
|
||||
|
||||
# 验证OpenSSL目录
|
||||
if(NOT EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/ssl.h")
|
||||
message(FATAL_ERROR "OpenSSL headers not found in ${OPENSSL_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
# 设置SQLite3路径
|
||||
set(SQLITE3_ROOT_DIR "${THIRD_PARTY_DIR}/sqlite3/")
|
||||
set(SQLITE3_INCLUDE_DIR "${SQLITE3_ROOT_DIR}/include")
|
||||
set(SQLITE3_LIBRARIE "${SQLITE3_ROOT_DIR}/lib/sqlite3.lib")
|
||||
|
||||
# 设置tinyxml2路径
|
||||
set(TINYXML2_INCLUDE_DIR "${THIRD_PARTY_DIR}/tinyxml2-6.0.0/")
|
||||
file(GLOB TINYXML2_SOURCES "${THIRD_PARTY_DIR}/tinyxml2-6.0.0/*.cpp")
|
||||
else()
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
if(NOT fastcdr_FOUND)
|
||||
find_package(fastcdr 2 REQUIRED)
|
||||
endif()
|
||||
|
||||
if(NOT fastdds_FOUND)
|
||||
find_package(fastdds 3 REQUIRED)
|
||||
endif()
|
||||
|
||||
file(GLOB DDS_XNIDL_SOURCES_CXX "XNIDL/*.cxx")
|
||||
set(XNCORE_SOURCES "")
|
||||
set(XNCORE_IDL_SOURCES "")
|
||||
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
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(XNScenarioManager)
|
||||
add_subdirectory(XNServiceManager)
|
||||
add_subdirectory(XNServiceObject)
|
||||
add_subdirectory(XNThreadManager)
|
||||
add_subdirectory(XNThreadObject)
|
||||
add_subdirectory(XNTimeManager)
|
||||
add_subdirectory(XNIDL)
|
||||
|
||||
add_library(XNCore SHARED
|
||||
XNCore_global.h
|
||||
XNCore_Function.cpp
|
||||
XNTypeTraits.h
|
||||
XNByteArray.h
|
||||
XNObject.h
|
||||
XNObject.cpp
|
||||
XNObject_p.h
|
||||
XNFramework.cpp
|
||||
XNFramework.h
|
||||
XNFramework_p.h
|
||||
XNBaseFrameObject.h
|
||||
XNBaseFrameObject.cpp
|
||||
XNBaseFrameObject_p.h
|
||||
XNLogger.h
|
||||
XNLogger.cpp
|
||||
XNTimeManager.h
|
||||
XNTimeManager_p.h
|
||||
XNTimeManager.cpp
|
||||
XNThread.h
|
||||
XNThread.cpp
|
||||
XNThread_p.h
|
||||
XNThreadManager.h
|
||||
XNThreadManager_p.h
|
||||
XNThreadManager.cpp
|
||||
XNModelObject.h
|
||||
XNModelObject_p.h
|
||||
XNModelObject.cpp
|
||||
XNModelManager.h
|
||||
XNModelManager_p.h
|
||||
XNModelManager.cpp
|
||||
XNScenarioManager.h
|
||||
XNScenarioManager_p.h
|
||||
XNScenarioManager.cpp
|
||||
XNDDSManager.h
|
||||
XNDDSManager.cpp
|
||||
XNServiceManager.h
|
||||
XNServiceManager_p.h
|
||||
XNServiceManager.cpp
|
||||
XNEventManager.h
|
||||
XNEventManager_p.h
|
||||
XNEventManager.cpp
|
||||
XNServiceObject.h
|
||||
XNServiceObject_p.h
|
||||
XNServiceObject.cpp
|
||||
XNDDSInterface.h
|
||||
XNDDSInterface.cpp
|
||||
${DDS_XNIDL_SOURCES_CXX}
|
||||
)
|
||||
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}
|
||||
)
|
||||
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
|
||||
pthread
|
||||
OpenSSL::SSL
|
||||
OpenSSL::Crypto
|
||||
nlohmann_json
|
||||
sqlite3
|
||||
dl
|
||||
)
|
||||
${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)
|
||||
|
||||
@ -97,11 +141,9 @@ install(TARGETS XNCore
|
||||
RUNTIME DESTINATION .
|
||||
)
|
||||
|
||||
# 添加自定义命令和目标以拷贝所有头文件
|
||||
file(GLOB HEADER_FILES "*.h")
|
||||
|
||||
# 使用 install 命令在安装时拷贝头文件
|
||||
install(FILES ${HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/XNCore)
|
||||
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)
|
7
XNCore/XNBaseFrameObject/CMakeLists.txt
Normal file
7
XNCore/XNBaseFrameObject/CMakeLists.txt
Normal 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)
|
0
XNCore/XNBaseFrameObject.cpp → XNCore/XNBaseFrameObject/XNBaseFrameObject.cpp
Executable file → Normal file
0
XNCore/XNBaseFrameObject.cpp → XNCore/XNBaseFrameObject/XNBaseFrameObject.cpp
Executable file → Normal file
0
XNCore/XNBaseFrameObject.h → XNCore/XNBaseFrameObject/XNBaseFrameObject.h
Executable file → Normal file
0
XNCore/XNBaseFrameObject.h → XNCore/XNBaseFrameObject/XNBaseFrameObject.h
Executable file → Normal file
0
XNCore/XNBaseFrameObject_p.h → XNCore/XNBaseFrameObject/XNBaseFrameObject_p.h
Executable file → Normal file
0
XNCore/XNBaseFrameObject_p.h → XNCore/XNBaseFrameObject/XNBaseFrameObject_p.h
Executable file → Normal file
@ -1,99 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* @brief 自定义字节数组容器类
|
||||
* @details 提供类似QByteArray的功能,用于处理二进制数据
|
||||
*/
|
||||
class XNByteArray
|
||||
{
|
||||
public:
|
||||
XNByteArray() = default;
|
||||
explicit XNByteArray(size_t size) : data_(size) {}
|
||||
|
||||
/**
|
||||
* @brief 从原始数据构造
|
||||
* @param buffer 原始数据缓冲区
|
||||
* @param size 数据大小
|
||||
*/
|
||||
XNByteArray(const uint8_t *buffer, size_t size) : data_(buffer, buffer + size) {}
|
||||
|
||||
/**
|
||||
* @brief 获取数据指针
|
||||
* @return 数据指针
|
||||
*/
|
||||
uint8_t *data() { return data_.data(); }
|
||||
|
||||
/**
|
||||
* @brief 获取常量数据指针
|
||||
* @return 常量数据指针
|
||||
*/
|
||||
const uint8_t *data() const { return data_.data(); }
|
||||
|
||||
/**
|
||||
* @brief 获取数据大小
|
||||
* @return 数据大小
|
||||
*/
|
||||
size_t size() const { return data_.size(); }
|
||||
|
||||
/**
|
||||
* @brief 调整大小
|
||||
* @param size 新大小
|
||||
*/
|
||||
void resize(size_t size) { data_.resize(size); }
|
||||
|
||||
/**
|
||||
* @brief 清空数据
|
||||
*/
|
||||
void clear() { data_.clear(); }
|
||||
|
||||
/**
|
||||
* @brief 追加数据
|
||||
* @param buffer 要追加的数据
|
||||
* @param size 数据大小
|
||||
*/
|
||||
void append(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t 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 字节值
|
||||
*/
|
||||
uint8_t &operator[](size_t index) { return data_[index]; }
|
||||
|
||||
/**
|
||||
* @brief 获取指定位置的字节(常量版本)
|
||||
* @param index 索引
|
||||
* @return 字节值
|
||||
*/
|
||||
const uint8_t &operator[](size_t index) const { return data_[index]; }
|
||||
|
||||
/**
|
||||
* @brief 检查是否为空
|
||||
* @return 是否为空
|
||||
*/
|
||||
bool isEmpty() const { return data_.empty(); }
|
||||
|
||||
/**
|
||||
* @brief 预分配空间
|
||||
* @param size 要预分配的大小
|
||||
*/
|
||||
void reserve(size_t size) { data_.reserve(size); }
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> data_;
|
||||
};
|
@ -1,58 +0,0 @@
|
||||
#include "XNCore_global.h"
|
||||
|
||||
namespace XNSim
|
||||
{
|
||||
XNTimePoint parseISOTime(const std::string &timeStr)
|
||||
{
|
||||
std::tm tm = {};
|
||||
std::istringstream ss(timeStr);
|
||||
ss >> std::get_time(&tm, "%Y-%m-%dT%H:%M:%S");
|
||||
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
|
||||
return tp;
|
||||
}
|
||||
|
||||
// 辅助函数:分割字符串
|
||||
std::vector<std::string> split(const std::string &str, const std::string &delim)
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
size_t prev = 0, pos = 0;
|
||||
do {
|
||||
pos = str.find(delim, prev);
|
||||
if (pos == std::string::npos)
|
||||
pos = str.length();
|
||||
std::string token = str.substr(prev, pos - prev);
|
||||
if (!token.empty())
|
||||
tokens.push_back(token);
|
||||
prev = pos + delim.length();
|
||||
} while (pos < str.length() && prev < str.length());
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// 辅助函数:获取文件名(不含扩展名)
|
||||
std::string getFileNameWithoutExt(const std::string &path)
|
||||
{
|
||||
size_t lastDot = path.find_last_of('.');
|
||||
if (lastDot != std::string::npos) {
|
||||
return path.substr(0, lastDot);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 安全地将字符串转换为整数
|
||||
* @param str 要转换的字符串
|
||||
* @param defaultValue 转换失败时的默认值
|
||||
* @return 转换后的整数值
|
||||
*/
|
||||
int safe_stoi(const std::string &str, int defaultValue)
|
||||
{
|
||||
if (str.empty()) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return std::stoi(str);
|
||||
} catch (const std::exception &) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
} // namespace XNSim
|
@ -1,291 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(XNCORE_LIBRARY)
|
||||
# define XNCORE_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
# define XNCORE_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#define FORCEINLINE __attribute__((always_inline))
|
||||
|
||||
#ifdef __linux__
|
||||
# include <pthread.h>
|
||||
# include <sched.h>
|
||||
# include <sys/timeb.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/stat.h>
|
||||
# include <errno.h>
|
||||
# include <time.h>
|
||||
# include <memory>
|
||||
# include <errno.h>
|
||||
# include <unistd.h>
|
||||
# include <limits.h>
|
||||
# include <functional>
|
||||
# include <map>
|
||||
# include <unordered_map>
|
||||
# include <vector>
|
||||
# include <set>
|
||||
# include <any>
|
||||
# include <string>
|
||||
# include <thread>
|
||||
# include <mutex>
|
||||
# include <condition_variable>
|
||||
# include <queue>
|
||||
# include <tinyxml2.h>
|
||||
# include <chrono>
|
||||
# include <iomanip>
|
||||
# include <sstream>
|
||||
# include <dlfcn.h>
|
||||
# include <filesystem>
|
||||
# include <array>
|
||||
# include <cstring>
|
||||
# include <iostream>
|
||||
# include <sqlite3.h>
|
||||
# include <nlohmann/json.hpp>
|
||||
#endif
|
||||
|
||||
#include <fastdds/dds/domain/DomainParticipant.hpp>
|
||||
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
|
||||
#include <fastdds/dds/publisher/DataWriter.hpp>
|
||||
#include <fastdds/dds/publisher/Publisher.hpp>
|
||||
#include <fastdds/dds/subscriber/DataReader.hpp>
|
||||
#include <fastdds/dds/subscriber/Subscriber.hpp>
|
||||
#include <fastdds/dds/topic/TypeSupport.hpp>
|
||||
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
|
||||
#include <fastcdr/xcdr/optional.hpp>
|
||||
#define FAST_DDS_MACRO eprosima::fastdds::dds
|
||||
|
||||
using XN_JSON = nlohmann::json;
|
||||
|
||||
/**
|
||||
* @brief 默认基频定义,单位 Hz
|
||||
*/
|
||||
#define BASE_RUN_FREQ 100.0
|
||||
|
||||
/**
|
||||
* @brief 默认基础运行间隔定义 单位纳秒
|
||||
*/
|
||||
#define BASE_RUN_INTER (1.0E9 / BASE_RUN_FREQ)
|
||||
|
||||
//模型周期性回调函数类型别名
|
||||
using XNCallBack = std::function<void()>;
|
||||
|
||||
//DDS回调函数类型别名
|
||||
using XNDDSCallBack = std::function<void(void *)>;
|
||||
|
||||
//事件回调函数类型别名
|
||||
using XNEventCallback = std::function<void(const std::any &)>;
|
||||
|
||||
/**
|
||||
* @brief 纳秒睡眠相关时间结构体
|
||||
* @details 用于线程睡眠时间控制
|
||||
*/
|
||||
struct PERIOD_INFO {
|
||||
/**
|
||||
* @brief 系统提供的时间记录结构体,精确到纳秒
|
||||
*/
|
||||
timespec next_period;
|
||||
/**
|
||||
* @brief 睡眠时长,单位纳秒
|
||||
*/
|
||||
long period_ns;
|
||||
};
|
||||
/**
|
||||
* @brief 系统时间点类型别名
|
||||
*/
|
||||
using XNTimePoint = std::chrono::system_clock::time_point;
|
||||
|
||||
/**
|
||||
* @brief 系统运行状态枚举类
|
||||
*/
|
||||
enum class RunStatus {
|
||||
/**
|
||||
* @brief 未开始
|
||||
*/
|
||||
NotStart = 0,
|
||||
/**
|
||||
* @brief 运行中
|
||||
*/
|
||||
Runing,
|
||||
/**
|
||||
* @brief 暂停
|
||||
*/
|
||||
Suspend,
|
||||
/**
|
||||
* @brief 中止
|
||||
*/
|
||||
Aborted,
|
||||
/**
|
||||
* @brief 结束
|
||||
*/
|
||||
Finished
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 仿真控制命令枚举类
|
||||
*/
|
||||
enum class SimControlCmd {
|
||||
/**
|
||||
* @brief 开始
|
||||
*/
|
||||
Start,
|
||||
/**
|
||||
* @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
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#define XN_CAST(from, to) XNStaticCastHelper<to>(from)
|
||||
|
||||
#define XN_THISPTR std::static_pointer_cast<ThisType>(shared_from_this())
|
||||
|
||||
#define XNCLASS_PTR_DECLARE(a) \
|
||||
using a##Ptr = std::shared_ptr<class a>; \
|
||||
using a##WPtr = std::weak_ptr<class a>; \
|
||||
using a##UPtr = std::unique_ptr<class a>; \
|
||||
using a##ConsPtr = std::shared_ptr<const class a>;
|
||||
|
||||
#define XNSTRUCT_PTR_DECLARE(a) \
|
||||
using a##Ptr = std::shared_ptr<struct a>; \
|
||||
using a##WPtr = std::weak_ptr<struct a>; \
|
||||
using a##UPtr = std::unique_ptr<struct a>; \
|
||||
using a##ConsPtr = std::shared_ptr<const struct a>;
|
||||
|
||||
#define XN_NOCOPYABLE(Class) \
|
||||
public: \
|
||||
using NoCopyable = Class; \
|
||||
\
|
||||
private: \
|
||||
Class(const Class &) = delete; \
|
||||
Class &operator=(const Class &) = delete;
|
||||
|
||||
#define XN_DECLARE_PRIVATE(Class) \
|
||||
XN_NOCOPYABLE(Class) \
|
||||
protected: \
|
||||
friend class Class##Private; \
|
||||
inline Class##Private *GetPP() const \
|
||||
{ \
|
||||
return reinterpret_cast<Class##Private *>(_Private_Ptr); \
|
||||
} \
|
||||
using PrivateType = Class##Private;
|
||||
|
||||
#define T_D() PrivateType *const d = GetPP()
|
||||
|
||||
struct XNNullClass {
|
||||
};
|
||||
|
||||
#define XN_METATYPE_P(cls) \
|
||||
public: \
|
||||
using ThisType = cls; \
|
||||
using SuperType = XNNullClass;
|
||||
|
||||
#define XN_METATYPE(cls, sup) \
|
||||
public: \
|
||||
using ThisType = cls; \
|
||||
using SuperType = sup;
|
||||
|
||||
#define XN_UNUSED(x) (void)x
|
||||
|
||||
namespace XNSim
|
||||
{
|
||||
template <typename T>
|
||||
constexpr typename std::underlying_type<T>::type enumValue(T e)
|
||||
{
|
||||
return static_cast<typename std::underlying_type<T>::type>(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将ISO格式的时间字符串转换为系统时间点
|
||||
* @param timeStr ISO格式的时间字符串 (YYYY-MM-DDTHH:mm:ss)
|
||||
* @return 系统时间点
|
||||
*/
|
||||
extern "C" XNTimePoint XNCORE_EXPORT parseISOTime(const std::string &timeStr);
|
||||
|
||||
extern "C" std::vector<std::string> XNCORE_EXPORT split(const std::string &str,
|
||||
const std::string &delim);
|
||||
|
||||
extern "C" std::string XNCORE_EXPORT getFileNameWithoutExt(const std::string &path);
|
||||
|
||||
extern "C" int XNCORE_EXPORT safe_stoi(const std::string &str, int defaultValue = 0);
|
||||
|
||||
inline std::string getStringFromSqlite3(sqlite3_stmt *stmt, int column)
|
||||
{
|
||||
const char *text = reinterpret_cast<const char *>(sqlite3_column_text(stmt, column));
|
||||
if (text == nullptr) {
|
||||
return "";
|
||||
}
|
||||
return std::string(text);
|
||||
}
|
||||
} // namespace XNSim
|
6
XNCore/XNDDSInterface/CMakeLists.txt
Normal file
6
XNCore/XNDDSInterface/CMakeLists.txt
Normal 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)
|
6
XNCore/XNDDSManager/CMakeLists.txt
Normal file
6
XNCore/XNDDSManager/CMakeLists.txt
Normal 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)
|
0
XNCore/XNDDSManager.cpp → XNCore/XNDDSManager/XNDDSManager.cpp
Executable file → Normal file
0
XNCore/XNDDSManager.cpp → XNCore/XNDDSManager/XNDDSManager.cpp
Executable file → Normal file
0
XNCore/XNDDSManager.h → XNCore/XNDDSManager/XNDDSManager.h
Executable file → Normal file
0
XNCore/XNDDSManager.h → XNCore/XNDDSManager/XNDDSManager.h
Executable file → Normal file
7
XNCore/XNEventManager/CMakeLists.txt
Normal file
7
XNCore/XNEventManager/CMakeLists.txt
Normal 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)
|
0
XNCore/XNEventManager.cpp → XNCore/XNEventManager/XNEventManager.cpp
Executable file → Normal file
0
XNCore/XNEventManager.cpp → XNCore/XNEventManager/XNEventManager.cpp
Executable file → Normal file
0
XNCore/XNEventManager.h → XNCore/XNEventManager/XNEventManager.h
Executable file → Normal file
0
XNCore/XNEventManager.h → XNCore/XNEventManager/XNEventManager.h
Executable file → Normal file
0
XNCore/XNEventManager_p.h → XNCore/XNEventManager/XNEventManager_p.h
Executable file → Normal file
0
XNCore/XNEventManager_p.h → XNCore/XNEventManager/XNEventManager_p.h
Executable file → Normal file
7
XNCore/XNFramework/CMakeLists.txt
Normal file
7
XNCore/XNFramework/CMakeLists.txt
Normal 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)
|
0
XNCore/XNFramework.cpp → XNCore/XNFramework/XNFramework.cpp
Executable file → Normal file
0
XNCore/XNFramework.cpp → XNCore/XNFramework/XNFramework.cpp
Executable file → Normal file
0
XNCore/XNFramework.h → XNCore/XNFramework/XNFramework.h
Executable file → Normal file
0
XNCore/XNFramework.h → XNCore/XNFramework/XNFramework.h
Executable file → Normal file
170
XNCore/XNFramework_p.h → XNCore/XNFramework/XNFramework_p.h
Executable file → Normal file
170
XNCore/XNFramework_p.h → XNCore/XNFramework/XNFramework_p.h
Executable file → Normal file
@ -1,85 +1,85 @@
|
||||
/**
|
||||
* @file XNFramework_p.h
|
||||
* @author jinchao
|
||||
* @brief 框架类的私有数据成员
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XNObject_p.h"
|
||||
|
||||
/**
|
||||
* @brief 框架类的私有数据成员
|
||||
*/
|
||||
struct XNFrameworkPrivate : public XNObjectPrivate {
|
||||
|
||||
/**
|
||||
* @brief DDS管理器
|
||||
*/
|
||||
XNDDSManagerPtr ddsManager;
|
||||
|
||||
/**
|
||||
* @brief 事件管理器
|
||||
*/
|
||||
XNEventManagerPtr eventManager;
|
||||
|
||||
/**
|
||||
* @brief 模型管理器
|
||||
*/
|
||||
XNModelManagerPtr modelManager;
|
||||
|
||||
/**
|
||||
* @brief 场景管理器
|
||||
*/
|
||||
XNScenarioManagerPtr scenarioManager;
|
||||
|
||||
/**
|
||||
* @brief 服务管理器
|
||||
*/
|
||||
XNServiceManagerPtr serviceManager;
|
||||
|
||||
/**
|
||||
* @brief 线程管理器
|
||||
*/
|
||||
XNThreadManagerPtr threadManager;
|
||||
|
||||
/**
|
||||
* @brief 时间管理器
|
||||
*/
|
||||
XNTimeManagerPtr timeManager;
|
||||
|
||||
/**
|
||||
* @brief 工作路径
|
||||
*/
|
||||
std::string workPath;
|
||||
|
||||
/**
|
||||
* @brief 模型路径
|
||||
*/
|
||||
std::string modelPath;
|
||||
|
||||
/**
|
||||
* @brief 服务路径
|
||||
*/
|
||||
std::string servicePath;
|
||||
|
||||
/**
|
||||
* @brief CPU亲和性
|
||||
*/
|
||||
uint32_t uCpuAffinity;
|
||||
|
||||
/**
|
||||
* @brief 场景XML
|
||||
*/
|
||||
std::string scenarioXml;
|
||||
|
||||
/**
|
||||
* @brief 构型ID
|
||||
*/
|
||||
uint32_t configId;
|
||||
};
|
||||
/**
|
||||
* @file XNFramework_p.h
|
||||
* @author jinchao
|
||||
* @brief 框架类的私有数据成员
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XNObject_p.h"
|
||||
|
||||
/**
|
||||
* @brief 框架类的私有数据成员
|
||||
*/
|
||||
struct XNFrameworkPrivate : public XNObjectPrivate {
|
||||
|
||||
/**
|
||||
* @brief DDS管理器
|
||||
*/
|
||||
XNDDSManagerPtr ddsManager;
|
||||
|
||||
/**
|
||||
* @brief 事件管理器
|
||||
*/
|
||||
XNEventManagerPtr eventManager;
|
||||
|
||||
/**
|
||||
* @brief 模型管理器
|
||||
*/
|
||||
XNModelManagerPtr modelManager;
|
||||
|
||||
/**
|
||||
* @brief 场景管理器
|
||||
*/
|
||||
XNScenarioManagerPtr scenarioManager;
|
||||
|
||||
/**
|
||||
* @brief 服务管理器
|
||||
*/
|
||||
XNServiceManagerPtr serviceManager;
|
||||
|
||||
/**
|
||||
* @brief 线程管理器
|
||||
*/
|
||||
XNThreadManagerPtr threadManager;
|
||||
|
||||
/**
|
||||
* @brief 时间管理器
|
||||
*/
|
||||
XNTimeManagerPtr timeManager;
|
||||
|
||||
/**
|
||||
* @brief 工作路径
|
||||
*/
|
||||
std::string workPath;
|
||||
|
||||
/**
|
||||
* @brief 模型路径
|
||||
*/
|
||||
std::string modelPath;
|
||||
|
||||
/**
|
||||
* @brief 服务路径
|
||||
*/
|
||||
std::string servicePath;
|
||||
|
||||
/**
|
||||
* @brief CPU亲和性
|
||||
*/
|
||||
uint32_t uCpuAffinity;
|
||||
|
||||
/**
|
||||
* @brief 场景XML
|
||||
*/
|
||||
std::string scenarioXml;
|
||||
|
||||
/**
|
||||
* @brief 构型ID
|
||||
*/
|
||||
uint32_t configId;
|
||||
};
|
20
XNCore/XNGlobalDefine/CMakeLists.txt
Normal file
20
XNCore/XNGlobalDefine/CMakeLists.txt
Normal 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)
|
100
XNCore/XNGlobalDefine/XNByteArray.h
Normal file
100
XNCore/XNGlobalDefine/XNByteArray.h
Normal 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
|
40
XNCore/XNGlobalDefine/XNCore_global.h
Normal file
40
XNCore/XNGlobalDefine/XNCore_global.h
Normal file
@ -0,0 +1,40 @@
|
||||
#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)
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif defined(__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
|
20
XNCore/XNGlobalDefine/XNDDS.h
Normal file
20
XNCore/XNGlobalDefine/XNDDS.h
Normal file
@ -0,0 +1,20 @@
|
||||
#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 {
|
||||
// DDS回调函数类型别名
|
||||
using XNDDSCallBack = std::function<void(void *)>;
|
||||
} // namespace XNSim
|
19
XNCore/XNGlobalDefine/XNDataBase.h
Normal file
19
XNCore/XNGlobalDefine/XNDataBase.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
// sqlite3头文件
|
||||
#include "XNCore_global.h"
|
||||
#include "XNString.h"
|
||||
#include "XNType.h"
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace XNSim {
|
||||
FORCEINLINE XN_STRING getStringFromSqlite3(sqlite3_stmt *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
|
36
XNCore/XNGlobalDefine/XNDefine.h
Normal file
36
XNCore/XNGlobalDefine/XNDefine.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "XNByteArray.h"
|
||||
#include "XNCore_global.h"
|
||||
#include "XNDDS.h"
|
||||
#include "XNDataBase.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 <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)
|
104
XNCore/XNGlobalDefine/XNEnum.h
Normal file
104
XNCore/XNGlobalDefine/XNEnum.h
Normal file
@ -0,0 +1,104 @@
|
||||
#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
|
||||
};
|
||||
|
||||
} // namespace XNSim
|
36
XNCore/XNGlobalDefine/XNFile.h
Normal file
36
XNCore/XNGlobalDefine/XNFile.h
Normal file
@ -0,0 +1,36 @@
|
||||
#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;
|
||||
}
|
||||
} // namespace XNSim
|
9
XNCore/XNGlobalDefine/XNJson.h
Normal file
9
XNCore/XNGlobalDefine/XNJson.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
// json头文件
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace XNSim {
|
||||
// json类型别名
|
||||
using XN_JSON = nlohmann::json;
|
||||
} // namespace XNSim
|
42
XNCore/XNGlobalDefine/XNMemory.h
Normal file
42
XNCore/XNGlobalDefine/XNMemory.h
Normal 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>;
|
45
XNCore/XNGlobalDefine/XNMeta.h
Normal file
45
XNCore/XNGlobalDefine/XNMeta.h
Normal 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
|
73
XNCore/XNGlobalDefine/XNString.h
Normal file
73
XNCore/XNGlobalDefine/XNString.h
Normal 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
|
19
XNCore/XNGlobalDefine/XNThread.h
Normal file
19
XNCore/XNGlobalDefine/XNThread.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <any>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
namespace XNSim {
|
||||
// 线程相关抽象
|
||||
using XN_MUTEX = std::mutex;
|
||||
using XN_CV = std::condition_variable;
|
||||
|
||||
// 模型周期性回调函数类型别名
|
||||
using XNCallBack = std::function<void()>;
|
||||
|
||||
// 事件回调函数类型别名
|
||||
using XNEventCallback = std::function<void(const std::any &)>;
|
||||
} // namespace XNSim
|
42
XNCore/XNGlobalDefine/XNTime.h
Normal file
42
XNCore/XNGlobalDefine/XNTime.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include "XNCore_global.h"
|
||||
#include "XNString.h"
|
||||
#include "XNType.h"
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <time.h>
|
||||
|
||||
namespace XNSim {
|
||||
/**
|
||||
* @brief 纳秒睡眠相关时间结构体
|
||||
* @details 用于线程睡眠时间控制
|
||||
*/
|
||||
struct PERIOD_INFO {
|
||||
/**
|
||||
* @brief 系统提供的时间记录结构体,精确到纳秒
|
||||
*/
|
||||
timespec next_period;
|
||||
/**
|
||||
* @brief 睡眠时长,单位纳秒
|
||||
*/
|
||||
XN_INT64 period_ns;
|
||||
};
|
||||
|
||||
// 系统时间点类型别名
|
||||
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;
|
||||
}
|
||||
} // namespace XNSim
|
19
XNCore/XNGlobalDefine/XNType.h
Normal file
19
XNCore/XNGlobalDefine/XNType.h
Normal file
@ -0,0 +1,19 @@
|
||||
#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;
|
||||
} // namespace XNSim
|
70
XNCore/XNGlobalDefine/XNTypeTraits.h
Normal file
70
XNCore/XNGlobalDefine/XNTypeTraits.h
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#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
|
4
XNCore/XNGlobalDefine/XNXml.h
Normal file
4
XNCore/XNGlobalDefine/XNXml.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
// tinyxml2头文件
|
||||
#include <tinyxml2.h>
|
11
XNCore/XNIDL/CMakeLists.txt
Normal file
11
XNCore/XNIDL/CMakeLists.txt
Normal 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_IDL_SOURCES ${XNCORE_IDL_SOURCES} ${XNIDL_SOURCES} PARENT_SCOPE)
|
@ -1,118 +0,0 @@
|
||||
#include "XNLogger.h"
|
||||
|
||||
XNLogger::XNLogger()
|
||||
: consoleOutputEnabled{true, true, true, true}, fileOutputEnabled{true, true, true, true}
|
||||
{
|
||||
// 获取当前工作目录
|
||||
std::filesystem::path currentDir = std::filesystem::current_path();
|
||||
std::filesystem::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";
|
||||
}
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
/**
|
||||
* @file XNLogger.h
|
||||
* @author jinchao
|
||||
* @brief 日志类
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <type_traits>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
/**
|
||||
* @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 std::string &message);
|
||||
|
||||
/**
|
||||
* @brief 启用控制台输出
|
||||
* @param level 日志等级
|
||||
* @param enable 是否启用
|
||||
*/
|
||||
void enableConsoleOutput(LogLevel level, bool enable);
|
||||
|
||||
/**
|
||||
* @brief 启用文件输出
|
||||
* @param level 日志等级
|
||||
* @param enable 是否启用
|
||||
*/
|
||||
void enableFileOutput(LogLevel level, bool enable);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
*/
|
||||
XNLogger();
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~XNLogger();
|
||||
|
||||
/**
|
||||
* @brief 禁止拷贝构造
|
||||
*/
|
||||
XNLogger(const XNLogger &) = delete;
|
||||
|
||||
/**
|
||||
* @brief 禁止赋值
|
||||
*/
|
||||
XNLogger &operator=(const XNLogger &) = delete;
|
||||
|
||||
/**
|
||||
* @brief 日志文件路径
|
||||
*/
|
||||
std::string logFilePath;
|
||||
|
||||
/**
|
||||
* @brief 控制台输出控制
|
||||
*/
|
||||
bool consoleOutputEnabled[5];
|
||||
|
||||
/**
|
||||
* @brief 文件输出控制
|
||||
*/
|
||||
bool fileOutputEnabled[5];
|
||||
|
||||
/**
|
||||
* @brief 日志文件
|
||||
*/
|
||||
std::ofstream logFile;
|
||||
|
||||
/**
|
||||
* @brief 互斥锁
|
||||
*/
|
||||
std::mutex mutex;
|
||||
|
||||
/**
|
||||
* @brief 日志等级转换为字符串
|
||||
* @param level 日志等级
|
||||
* @return 日志等级字符串
|
||||
*/
|
||||
std::string logLevelToString(LogLevel level) const;
|
||||
|
||||
/**
|
||||
* @brief 获取当前时间字符串
|
||||
* @return 格式化的时间字符串
|
||||
*/
|
||||
std::string getCurrentTimeString() const;
|
||||
|
||||
/**
|
||||
* @brief 控制台输出字体恢复颜色常量
|
||||
*/
|
||||
const std::string COLOR_RESET = "\033[0m";
|
||||
|
||||
/**
|
||||
* @brief 调试颜色常量
|
||||
*/
|
||||
const std::string COLOR_DEBUG = "\033[34m"; // 蓝色
|
||||
|
||||
/**
|
||||
* @brief 信息颜色常量
|
||||
*/
|
||||
const std::string COLOR_INFO = "\033[32m"; // 绿色
|
||||
|
||||
/**
|
||||
* @brief 警告颜色常量
|
||||
*/
|
||||
const std::string COLOR_WARNING = "\033[33m"; // 黄色
|
||||
|
||||
/**
|
||||
* @brief 错误颜色常量
|
||||
*/
|
||||
const std::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 std::string &message, Args... args)
|
||||
{
|
||||
std::string formattedMessage = formatMessage(message, args...);
|
||||
XNLogger::instance().log(level, formattedMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 不带参数的日志输出
|
||||
* @param level 日志等级
|
||||
* @param message 日志消息
|
||||
*/
|
||||
inline static void log(XNLogger::LogLevel level, const std::string &message)
|
||||
{
|
||||
XNLogger::instance().log(level, message);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief 将参数转换为字符串
|
||||
* @tparam T 参数类型
|
||||
* @param arg 要转换的参数
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
template <typename T>
|
||||
static std::string convertToString(const T &arg)
|
||||
{
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
return std::to_string(arg); // 处理数值类型
|
||||
} else if constexpr (std::is_same_v<T, std::string>) {
|
||||
return arg;
|
||||
} else if constexpr (std::is_convertible_v<T, std::string>) {
|
||||
return std::string(arg);
|
||||
} else if constexpr (std::is_same_v<T, char *> || std::is_same_v<T, const char *>) {
|
||||
return std::string(arg);
|
||||
} else {
|
||||
static_assert(std::is_arithmetic_v<T> || std::is_same_v<T, std::string>
|
||||
|| std::is_convertible_v<T, std::string> || std::is_same_v<T, char *>
|
||||
|| std::is_same_v<T, const char *>,
|
||||
"A01021001: 不支持的类型转换,详见XNLogger.cpp:line 199");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 格式化日志消息,顺序替换%1、%2、%3……
|
||||
* @tparam Args 参数类型
|
||||
* @param message 日志消息
|
||||
* @param args 参数包
|
||||
* @return 格式化后的消息
|
||||
*/
|
||||
template <typename... Args>
|
||||
static std::string formatMessage(const std::string &message, Args &&...args)
|
||||
{
|
||||
static_assert(sizeof...(Args) <= 9,
|
||||
"A01021002: 单条日志参数数量超过限制,详见XNLogger.cpp:line 216");
|
||||
|
||||
std::string result = message;
|
||||
// 使用初始化列表展开参数包
|
||||
int index = 1;
|
||||
// 使用lambda和std::initializer_list展开参数包
|
||||
(void)std::initializer_list<int>{(
|
||||
[&result, &index](const auto &value) {
|
||||
std::string placeholder = "%" + std::to_string(index++);
|
||||
size_t pos = result.find(placeholder);
|
||||
if (pos != std::string::npos) {
|
||||
result.replace(pos, placeholder.length(), convertToString(value));
|
||||
}
|
||||
}(args),
|
||||
0)...};
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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__)
|
6
XNCore/XNLogger/CMakeLists.txt
Normal file
6
XNCore/XNLogger/CMakeLists.txt
Normal 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)
|
114
XNCore/XNLogger/XNLogger.cpp
Normal file
114
XNCore/XNLogger/XNLogger.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
#include "XNLogger.h"
|
||||
|
||||
XNLogger::XNLogger()
|
||||
: consoleOutputEnabled{true, true, true, true},
|
||||
fileOutputEnabled{true, true, true, true} {
|
||||
// 获取当前工作目录
|
||||
XN_PATH currentDir = XNGetCurrentPath();
|
||||
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";
|
||||
}
|
||||
}
|
248
XNCore/XNLogger/XNLogger.h
Normal file
248
XNCore/XNLogger/XNLogger.h
Normal file
@ -0,0 +1,248 @@
|
||||
/**
|
||||
* @file XNLogger.h
|
||||
* @author jinchao
|
||||
* @brief 日志类
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include "XNCore_Function.h"
|
||||
#include "XNTypeDefine.h"
|
||||
#include "XNTypeTraits.h"
|
||||
|
||||
/**
|
||||
* @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.cpp:line 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.cpp:line 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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @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__)
|
7
XNCore/XNModelManager/CMakeLists.txt
Normal file
7
XNCore/XNModelManager/CMakeLists.txt
Normal 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)
|
0
XNCore/XNModelManager.cpp → XNCore/XNModelManager/XNModelManager.cpp
Executable file → Normal file
0
XNCore/XNModelManager.cpp → XNCore/XNModelManager/XNModelManager.cpp
Executable file → Normal file
0
XNCore/XNModelManager.h → XNCore/XNModelManager/XNModelManager.h
Executable file → Normal file
0
XNCore/XNModelManager.h → XNCore/XNModelManager/XNModelManager.h
Executable file → Normal file
0
XNCore/XNModelManager_p.h → XNCore/XNModelManager/XNModelManager_p.h
Executable file → Normal file
0
XNCore/XNModelManager_p.h → XNCore/XNModelManager/XNModelManager_p.h
Executable file → Normal file
7
XNCore/XNModelObject/CMakeLists.txt
Normal file
7
XNCore/XNModelObject/CMakeLists.txt
Normal 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)
|
0
XNCore/XNModelObject.cpp → XNCore/XNModelObject/XNModelObject.cpp
Executable file → Normal file
0
XNCore/XNModelObject.cpp → XNCore/XNModelObject/XNModelObject.cpp
Executable file → Normal file
0
XNCore/XNModelObject.h → XNCore/XNModelObject/XNModelObject.h
Executable file → Normal file
0
XNCore/XNModelObject.h → XNCore/XNModelObject/XNModelObject.h
Executable file → Normal file
0
XNCore/XNModelObject_p.h → XNCore/XNModelObject/XNModelObject_p.h
Executable file → Normal file
0
XNCore/XNModelObject_p.h → XNCore/XNModelObject/XNModelObject_p.h
Executable file → Normal file
@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @file XNObject.h
|
||||
* @author jinchao
|
||||
* @brief 基础对象类
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "XNCore_global.h"
|
||||
#include "XNLogger.h"
|
||||
|
||||
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
|
||||
*/
|
||||
uint32_t GetUniqueId();
|
||||
|
||||
/**
|
||||
* @brief 设置唯一ID
|
||||
* @param uniqueId 唯一ID
|
||||
*/
|
||||
void SetUniqueId(const uint32_t &uniqueId);
|
||||
|
||||
/**
|
||||
* @brief 获取对象名称
|
||||
* @return 对象名称
|
||||
*/
|
||||
const std::string &GetObjectName();
|
||||
|
||||
/**
|
||||
* @brief 设置对象名称
|
||||
* @param name 对象名称
|
||||
*/
|
||||
void SetObjectName(const std::string &name);
|
||||
};
|
||||
|
||||
class XNFramework;
|
||||
class XNDDSManager;
|
||||
class XNEventManager;
|
||||
class XNModelManager;
|
||||
class XNScenarioManager;
|
||||
class XNServiceManager;
|
||||
class XNThreadManager;
|
||||
class XNTimeManager;
|
||||
|
||||
XNCLASS_PTR_DECLARE(XNFramework)
|
||||
XNCLASS_PTR_DECLARE(XNDDSManager)
|
||||
XNCLASS_PTR_DECLARE(XNEventManager)
|
||||
XNCLASS_PTR_DECLARE(XNModelManager)
|
||||
XNCLASS_PTR_DECLARE(XNScenarioManager)
|
||||
XNCLASS_PTR_DECLARE(XNServiceManager)
|
||||
XNCLASS_PTR_DECLARE(XNThreadManager)
|
||||
XNCLASS_PTR_DECLARE(XNTimeManager)
|
7
XNCore/XNObject/CMakeLists.txt
Normal file
7
XNCore/XNObject/CMakeLists.txt
Normal 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)
|
90
XNCore/XNObject.cpp → XNCore/XNObject/XNObject.cpp
Executable file → Normal file
90
XNCore/XNObject.cpp → XNCore/XNObject/XNObject.cpp
Executable file → Normal file
@ -1,45 +1,45 @@
|
||||
#include "XNObject.h"
|
||||
#include "XNObject_p.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t XNObject::GetUniqueId()
|
||||
{
|
||||
return _Private_Ptr->uUniqueID;
|
||||
}
|
||||
|
||||
void XNObject::SetUniqueId(const uint32_t &uniqueId)
|
||||
{
|
||||
_Private_Ptr->uUniqueID = uniqueId;
|
||||
}
|
||||
|
||||
const std::string &XNObject::GetObjectName()
|
||||
{
|
||||
return _Private_Ptr->sObjectName;
|
||||
}
|
||||
|
||||
void XNObject::SetObjectName(const std::string &name)
|
||||
{
|
||||
_Private_Ptr->sObjectName = name;
|
||||
}
|
||||
#include "XNObject.h"
|
||||
#include "XNObject_p.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t XNObject::GetUniqueId()
|
||||
{
|
||||
return _Private_Ptr->uUniqueID;
|
||||
}
|
||||
|
||||
void XNObject::SetUniqueId(const uint32_t &uniqueId)
|
||||
{
|
||||
_Private_Ptr->uUniqueID = uniqueId;
|
||||
}
|
||||
|
||||
const std::string &XNObject::GetObjectName()
|
||||
{
|
||||
return _Private_Ptr->sObjectName;
|
||||
}
|
||||
|
||||
void XNObject::SetObjectName(const std::string &name)
|
||||
{
|
||||
_Private_Ptr->sObjectName = name;
|
||||
}
|
91
XNCore/XNObject/XNObject.h
Normal file
91
XNCore/XNObject/XNObject.h
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @file XNObject.h
|
||||
* @author jinchao
|
||||
* @brief 基础对象类
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "XNCore_global.h"
|
||||
#include "XNLogger.h"
|
||||
|
||||
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
|
||||
*/
|
||||
uint32_t GetUniqueId();
|
||||
|
||||
/**
|
||||
* @brief 设置唯一ID
|
||||
* @param uniqueId 唯一ID
|
||||
*/
|
||||
void SetUniqueId(const uint32_t &uniqueId);
|
||||
|
||||
/**
|
||||
* @brief 获取对象名称
|
||||
* @return 对象名称
|
||||
*/
|
||||
const std::string &GetObjectName();
|
||||
|
||||
/**
|
||||
* @brief 设置对象名称
|
||||
* @param name 对象名称
|
||||
*/
|
||||
void SetObjectName(const std::string &name);
|
||||
};
|
||||
|
||||
class XNFramework;
|
||||
class XNDDSManager;
|
||||
class XNEventManager;
|
||||
class XNModelManager;
|
||||
class XNScenarioManager;
|
||||
class XNServiceManager;
|
||||
class XNThreadManager;
|
||||
class XNTimeManager;
|
||||
|
||||
XNCLASS_PTR_DECLARE(XNFramework)
|
||||
XNCLASS_PTR_DECLARE(XNDDSManager)
|
||||
XNCLASS_PTR_DECLARE(XNEventManager)
|
||||
XNCLASS_PTR_DECLARE(XNModelManager)
|
||||
XNCLASS_PTR_DECLARE(XNScenarioManager)
|
||||
XNCLASS_PTR_DECLARE(XNServiceManager)
|
||||
XNCLASS_PTR_DECLARE(XNThreadManager)
|
||||
XNCLASS_PTR_DECLARE(XNTimeManager)
|
68
XNCore/XNObject_p.h → XNCore/XNObject/XNObject_p.h
Executable file → Normal file
68
XNCore/XNObject_p.h → XNCore/XNObject/XNObject_p.h
Executable file → Normal file
@ -1,34 +1,34 @@
|
||||
/**
|
||||
* @file XNObject_p.h
|
||||
* @author jinchao
|
||||
* @brief 基础对象类的私有数据成员
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "XNObject.h"
|
||||
|
||||
/**
|
||||
* @brief 基础对象类的私有数据成员
|
||||
*/
|
||||
struct XNObjectPrivate {
|
||||
virtual ~XNObjectPrivate();
|
||||
/**
|
||||
* @brief 基础对象类指针
|
||||
*/
|
||||
XNObject *_Public_Ptr;
|
||||
|
||||
/**
|
||||
* @brief 唯一ID
|
||||
*/
|
||||
uint32_t uUniqueID;
|
||||
|
||||
/**
|
||||
* @brief 对象名称
|
||||
*/
|
||||
std::string sObjectName;
|
||||
};
|
||||
/**
|
||||
* @file XNObject_p.h
|
||||
* @author jinchao
|
||||
* @brief 基础对象类的私有数据成员
|
||||
* @version 1.0
|
||||
* @date 2025-01-08
|
||||
*
|
||||
* @copyright Copyright (c) 2025 COMAC
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "XNObject.h"
|
||||
|
||||
/**
|
||||
* @brief 基础对象类的私有数据成员
|
||||
*/
|
||||
struct XNObjectPrivate {
|
||||
virtual ~XNObjectPrivate();
|
||||
/**
|
||||
* @brief 基础对象类指针
|
||||
*/
|
||||
XNObject *_Public_Ptr;
|
||||
|
||||
/**
|
||||
* @brief 唯一ID
|
||||
*/
|
||||
uint32_t uUniqueID;
|
||||
|
||||
/**
|
||||
* @brief 对象名称
|
||||
*/
|
||||
std::string sObjectName;
|
||||
};
|
7
XNCore/XNScenarioManager/CMakeLists.txt
Normal file
7
XNCore/XNScenarioManager/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
set(XNSCENARIOMANAGER_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XNScenarioManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XNScenarioManager_p.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XNScenarioManager.cpp
|
||||
)
|
||||
|
||||
set(XNCORE_SOURCES ${XNCORE_SOURCES} ${XNSCENARIOMANAGER_SOURCES} PARENT_SCOPE)
|
0
XNCore/XNScenarioManager.cpp → XNCore/XNScenarioManager/XNScenarioManager.cpp
Executable file → Normal file
0
XNCore/XNScenarioManager.cpp → XNCore/XNScenarioManager/XNScenarioManager.cpp
Executable file → Normal file
0
XNCore/XNScenarioManager.h → XNCore/XNScenarioManager/XNScenarioManager.h
Executable file → Normal file
0
XNCore/XNScenarioManager.h → XNCore/XNScenarioManager/XNScenarioManager.h
Executable file → Normal file
0
XNCore/XNScenarioManager_p.h → XNCore/XNScenarioManager/XNScenarioManager_p.h
Executable file → Normal file
0
XNCore/XNScenarioManager_p.h → XNCore/XNScenarioManager/XNScenarioManager_p.h
Executable file → Normal file
7
XNCore/XNServiceManager/CMakeLists.txt
Normal file
7
XNCore/XNServiceManager/CMakeLists.txt
Normal 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)
|
0
XNCore/XNServiceManager.cpp → XNCore/XNServiceManager/XNServiceManager.cpp
Executable file → Normal file
0
XNCore/XNServiceManager.cpp → XNCore/XNServiceManager/XNServiceManager.cpp
Executable file → Normal file
0
XNCore/XNServiceManager.h → XNCore/XNServiceManager/XNServiceManager.h
Executable file → Normal file
0
XNCore/XNServiceManager.h → XNCore/XNServiceManager/XNServiceManager.h
Executable file → Normal file
0
XNCore/XNServiceManager_p.h → XNCore/XNServiceManager/XNServiceManager_p.h
Executable file → Normal file
0
XNCore/XNServiceManager_p.h → XNCore/XNServiceManager/XNServiceManager_p.h
Executable file → Normal file
7
XNCore/XNServiceObject/CMakeLists.txt
Normal file
7
XNCore/XNServiceObject/CMakeLists.txt
Normal 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)
|
0
XNCore/XNServiceObject.cpp → XNCore/XNServiceObject/XNServiceObject.cpp
Executable file → Normal file
0
XNCore/XNServiceObject.cpp → XNCore/XNServiceObject/XNServiceObject.cpp
Executable file → Normal file
0
XNCore/XNServiceObject.h → XNCore/XNServiceObject/XNServiceObject.h
Executable file → Normal file
0
XNCore/XNServiceObject.h → XNCore/XNServiceObject/XNServiceObject.h
Executable file → Normal file
0
XNCore/XNServiceObject_p.h → XNCore/XNServiceObject/XNServiceObject_p.h
Executable file → Normal file
0
XNCore/XNServiceObject_p.h → XNCore/XNServiceObject/XNServiceObject_p.h
Executable file → Normal file
7
XNCore/XNThreadManager/CMakeLists.txt
Normal file
7
XNCore/XNThreadManager/CMakeLists.txt
Normal 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)
|
0
XNCore/XNThreadManager.cpp → XNCore/XNThreadManager/XNThreadManager.cpp
Executable file → Normal file
0
XNCore/XNThreadManager.cpp → XNCore/XNThreadManager/XNThreadManager.cpp
Executable file → Normal file
0
XNCore/XNThreadManager.h → XNCore/XNThreadManager/XNThreadManager.h
Executable file → Normal file
0
XNCore/XNThreadManager.h → XNCore/XNThreadManager/XNThreadManager.h
Executable file → Normal file
0
XNCore/XNThreadManager_p.h → XNCore/XNThreadManager/XNThreadManager_p.h
Executable file → Normal file
0
XNCore/XNThreadManager_p.h → XNCore/XNThreadManager/XNThreadManager_p.h
Executable file → Normal file
7
XNCore/XNThreadObject/CMakeLists.txt
Normal file
7
XNCore/XNThreadObject/CMakeLists.txt
Normal 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)
|
0
XNCore/XNThread.cpp → XNCore/XNThreadObject/XNThreadObject.cpp
Executable file → Normal file
0
XNCore/XNThread.cpp → XNCore/XNThreadObject/XNThreadObject.cpp
Executable file → Normal file
0
XNCore/XNThread.h → XNCore/XNThreadObject/XNThreadObject.h
Executable file → Normal file
0
XNCore/XNThread.h → XNCore/XNThreadObject/XNThreadObject.h
Executable file → Normal file
7
XNCore/XNTimeManager/CMakeLists.txt
Normal file
7
XNCore/XNTimeManager/CMakeLists.txt
Normal 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)
|
0
XNCore/XNTimeManager.cpp → XNCore/XNTimeManager/XNTimeManager.cpp
Executable file → Normal file
0
XNCore/XNTimeManager.cpp → XNCore/XNTimeManager/XNTimeManager.cpp
Executable file → Normal file
0
XNCore/XNTimeManager.h → XNCore/XNTimeManager/XNTimeManager.h
Executable file → Normal file
0
XNCore/XNTimeManager.h → XNCore/XNTimeManager/XNTimeManager.h
Executable file → Normal file
0
XNCore/XNTimeManager_p.h → XNCore/XNTimeManager/XNTimeManager_p.h
Executable file → Normal file
0
XNCore/XNTimeManager_p.h → XNCore/XNTimeManager/XNTimeManager_p.h
Executable file → Normal file
@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
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 {
|
||||
};
|
||||
|
||||
// 变量模板简化使用
|
||||
template <typename T>
|
||||
inline constexpr bool is_std_array_v = is_std_array<T>::value;
|
||||
|
||||
/**
|
||||
* @brief 获取类型的数组大小
|
||||
* @tparam T 要检查的类型
|
||||
* @return 如果是std::array,返回其大小;否则返回1
|
||||
*/
|
||||
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> {
|
||||
};
|
||||
|
||||
// 变量模板简化使用
|
||||
template <typename T>
|
||||
inline constexpr std::size_t array_size_v = array_size<T>::value;
|
||||
|
||||
// 获取类型大小的辅助函数
|
||||
template <typename T>
|
||||
constexpr size_t getTypeSize()
|
||||
{
|
||||
if constexpr (is_std_array_v<T>) {
|
||||
// 对于std::array,计算所有元素的总大小
|
||||
return getTypeSize<typename T::value_type>() * array_size_v<T>;
|
||||
} else {
|
||||
return sizeof(T);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user