V0.35.1.250625_alpha:服务开发页面增加了代码生成功能

This commit is contained in:
jinchao 2025-06-25 09:42:39 +08:00
parent 38b224f0c4
commit e390b04de6
46 changed files with 1071 additions and 1723 deletions

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNUDPService</Name>
<Description>UDP通信服务</Description>
<Author>Jin</Author>
<Version>1.0.0</Version>
<CreateTime>2025-02-04 10:00:00</CreateTime>
<ChangeTime>2025-02-04 10:00:00</ChangeTime>
<CommandList>
<Command Name="TestCmd" Description="Test" Call="TestCall"/>
</CommandList>
<UDP>
<LocalPort>12345</LocalPort>
<TargetHost>127.0.0.1</TargetHost>
<TargetPort>54321</TargetPort>
</UDP>
</Service>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNUDPTestService</Name>
<Description>UDP通信服务</Description>
<Author>Jin</Author>
<Version>1.0.0</Version>
<CreateTime>2025-02-04 10:00:00</CreateTime>
<ChangeTime>2025-02-04 10:00:00</ChangeTime>
<CommandList>
<Command Name="TestCmd" Description="Test" Call="TestCall"/>
</CommandList>
<UDP>
<LocalPort>54321</LocalPort>
<TargetHost>127.0.0.1</TargetHost>
<TargetPort>12345</TargetPort>
</UDP>
</Service>

Binary file not shown.

View File

@ -0,0 +1,49 @@
cmake_minimum_required(VERSION 3.16)
project(XNTCPService LANGUAGES CXX)
set(SERVICE_VERSION "1.0.0.0")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(DEFINED ENV{XNCore})
set(XNCore_PATH $ENV{XNCore})
else()
message(FATAL_ERROR "Environment variable XNCore is not set.")
endif()
include_directories(${XNCore_PATH}/include)
add_library(XNTCPService SHARED
XNTCPService_global.h
XNTCPService.cpp
XNTCPService.h
XNTCPService_p.h
)
set_target_properties(XNTCPService PROPERTIES
LIBRARY_OUTPUT_NAME "libXNTCPService.so.1.0.0.0"
PREFIX ""
SUFFIX ""
SKIP_BUILD_RPATH TRUE
BUILD_WITH_INSTALL_RPATH TRUE
)
target_link_libraries(XNTCPService PRIVATE
${XNCore_PATH}/lib/libXNCore.so
)
target_compile_definitions(XNTCPService PRIVATE XNTCPSERVICE_LIBRARY)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${XNCore_PATH}/Services" CACHE PATH "Install path prefix" FORCE)
endif()
install(TARGETS XNTCPService BUNDLE DESTINATION . LIBRARY DESTINATION . RUNTIME DESTINATION .)
file(GLOB CONFIG_FILE "*.scfg")
install(FILES ${CONFIG_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX} RENAME "${CMAKE_PROJECT_NAME}_V${SERVICE_VERSION}.scfg")

View File

@ -0,0 +1,29 @@
#include "XNTCPService.h"
#include "XNTCPService_p.h"
#include <XNCore/XNServiceManager.h>
XN_SERVICE_INITIALIZE(XNTCPService)
XNTCPService::XNTCPService() : XNServiceObject(new XNTCPServicePrivate())
{
}
XNTCPService::~XNTCPService() {
}
XNTCPService::XNTCPService(PrivateType *p) : XNServiceObject(p)
{
}
void XNTCPService::Initialize() {
T_D();
SuperType::Initialize();
/* 在这里进行其它初始化 */
}
void XNTCPService::PrepareForExecute() {
T_D();
SuperType::PrepareForExecute();
/* 在这里进行其它运行前准备工作 */
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "XNTCPService_global.h"
#include <XNCore/XNServiceObject.h>
struct XNTCPServicePrivate;
class XNTCPSERVICE_EXPORT XNTCPService : public XNServiceObject
{
XN_METATYPE(XNTCPService, XNServiceObject)
XN_DECLARE_PRIVATE(XNTCPService)
public:
XNTCPService();
virtual ~XNTCPService();
protected:
XNTCPService(PrivateType *p);
public:
virtual void Initialize() override;
virtual void PrepareForExecute() override;
};
XNCLASS_PTR_DECLARE(XNTCPService)

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNTCPService</Name>
<Description>TCP通信服务</Description>
<Author>Jin</Author>
<Version>1.0.0.0</Version>
<CreateTime>2025-06-25 09:16:45</CreateTime>
<ChangeTime>2025-06-25 09:16:26</ChangeTime>
<CommandList/>
</Service>

View File

@ -0,0 +1,11 @@
#ifndef XNTCPSERVICE_GLOBAL_H
#define XNTCPSERVICE_GLOBAL_H
#if defined(XNTCPSERVICE_LIBRARY)
#define XNTCPSERVICE_EXPORT __attribute__((visibility("default")))
#else
#define XNTCPSERVICE_EXPORT __attribute__((visibility("default")))
#endif
#endif // XNTCPSERVICE_GLOBAL_H

View File

@ -0,0 +1,7 @@
#pragma once
#include <XNCore/XNServiceObject_p.h>
struct XNTCPServicePrivate : public XNServiceObjectPrivate{
};

Binary file not shown.

View File

@ -2,19 +2,18 @@ cmake_minimum_required(VERSION 3.16)
project(XNUDPService LANGUAGES CXX)
set(MODEL_VERSION "1.0.0.0")
set(SERVICE_VERSION "1.0.0.0")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
#
if(DEFINED ENV{XNCore})
set(XNCore_PATH $ENV{XNCore})
else()
message(FATAL_ERROR "Environment variable XNCore is not set.")
endif()
# XNCore_PATH include
include_directories(${XNCore_PATH}/include)
add_library(XNUDPService SHARED
@ -25,7 +24,7 @@ add_library(XNUDPService SHARED
)
set_target_properties(XNUDPService PROPERTIES
LIBRARY_OUTPUT_NAME "libXNUDPService.so.${MODEL_VERSION}"
LIBRARY_OUTPUT_NAME "libXNUDPService.so.1.0.0.0"
PREFIX ""
SUFFIX ""
SKIP_BUILD_RPATH TRUE
@ -42,18 +41,9 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${XNCore_PATH}/Services" CACHE PATH "Install path prefix" FORCE)
endif()
include(GNUInstallDirs)
install(TARGETS XNUDPService
BUNDLE DESTINATION .
LIBRARY DESTINATION .
RUNTIME DESTINATION .
)
install(TARGETS XNUDPService BUNDLE DESTINATION . LIBRARY DESTINATION . RUNTIME DESTINATION .)
#
file(GLOB CONFIG_FILE "*.scfg")
# 使 install
install(FILES ${CONFIG_FILE}
DESTINATION ${CMAKE_INSTALL_PREFIX}
RENAME "XNUDPService_V${MODEL_VERSION}.mcfg"
)
install(FILES ${CONFIG_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX} RENAME "${CMAKE_PROJECT_NAME}_V${SERVICE_VERSION}.scfg")

View File

@ -0,0 +1,29 @@
#include "XNUDPService.h"
#include "XNUDPService_p.h"
#include <XNCore/XNServiceManager.h>
XN_SERVICE_INITIALIZE(XNUDPService)
XNUDPService::XNUDPService() : XNServiceObject(new XNUDPServicePrivate())
{
}
XNUDPService::~XNUDPService() {
}
XNUDPService::XNUDPService(PrivateType *p) : XNServiceObject(p)
{
}
void XNUDPService::Initialize() {
T_D();
SuperType::Initialize();
/* 在这里进行其它初始化 */
}
void XNUDPService::PrepareForExecute() {
T_D();
SuperType::PrepareForExecute();
/* 在这里进行其它运行前准备工作 */
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "XNUDPService_global.h"
#include <XNCore/XNServiceObject.h>
struct XNUDPServicePrivate;
class XNUDPSERVICE_EXPORT XNUDPService : public XNServiceObject
{
XN_METATYPE(XNUDPService, XNServiceObject)
XN_DECLARE_PRIVATE(XNUDPService)
public:
XNUDPService();
virtual ~XNUDPService();
protected:
XNUDPService(PrivateType *p);
public:
virtual void Initialize() override;
virtual void PrepareForExecute() override;
};
XNCLASS_PTR_DECLARE(XNUDPService)

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNUDPService</Name>
<Description>UDP通信服务提供UDP数据的发送与接收接口</Description>
<Author>Jin</Author>
<Version>1.0.0.0</Version>
<CreateTime>2025-02-04 10:00:00</CreateTime>
<ChangeTime>2025-02-04 10:00:00</ChangeTime>
<CommandList/>
</Service>

View File

@ -8,3 +8,4 @@
#endif
#endif // XNUDPSERVICE_GLOBAL_H

View File

@ -0,0 +1,7 @@
#pragma once
#include <XNCore/XNServiceObject_p.h>
struct XNUDPServicePrivate : public XNServiceObjectPrivate{
};

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNTCPService</Name>
<Description>TCP通信服务</Description>
<Author>Jin</Author>
<Version>1.0.0.0</Version>
<CreateTime>2025-06-25 09:16:45</CreateTime>
<ChangeTime>2025-06-25 09:16:26</ChangeTime>
<CommandList/>
</Service>

Binary file not shown.

Binary file not shown.

View File

@ -245,7 +245,7 @@ bool XNScenarioManager::ParseConfig(const std::string &ConfigID)
std::string modelPath = rootPath + "/Models";
GetFramework()->SetModelPath(modelPath);
// 设置服务库目录
std::string servicePath = rootPath + "/Services";
std::string servicePath = XNCorePath + "/Services";
GetFramework()->SetServicePath(servicePath);
// 设置域ID
uint32_t domainID = std::stoul(XNSim::getStringFromSqlite3(stmt, 7));

View File

@ -250,7 +250,7 @@ bool XNServiceGen::GenerateSourceFile()
bool XNServiceGen::GenerateConfigFile()
{
std::string configPath = m_codePath + "/" + m_className + ".mcfg";
std::string configPath = m_codePath + "/" + m_className + ".scfg";
std::ofstream configFile(configPath);
if (!configFile.is_open()) {
return false;

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10)
project(XNModelGenTest)
project(XNServiceGenTest)
# C++
set(CMAKE_CXX_STANDARD 11)
@ -9,13 +9,13 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_library(DL_LIBRARY dl)
#
add_executable(test_xnmodel test_xnmodel.cpp)
add_executable(test_xnservice test_xnservice.cpp)
#
target_link_libraries(test_xnmodel ${DL_LIBRARY})
target_link_libraries(test_xnservice ${DL_LIBRARY})
#
set_target_properties(test_xnmodel PROPERTIES
set_target_properties(test_xnservice PROPERTIES
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_RPATH "${CMAKE_SOURCE_DIR}/.."
)

View File

@ -1,129 +0,0 @@
#include <iostream>
#include <cstring>
#include <dlfcn.h>
// 函数指针类型定义
typedef int (*XNModelCodeGenFunc)(const char *className, int classNameLen, const char *version,
int versionLen, const char *planeName, int planeNameLen,
char *errorMsg, int errorMsgLen);
typedef int (*XNModelCodeZipFunc)(const char *className, int classNameLen, const char *version,
int versionLen, const char *planeName, int planeNameLen,
char *dstPath, int dstPathLen, char *errorMsg, int errorMsgLen);
typedef int (*XNModelCodeUnzipFunc)(const char *className, int classNameLen, const char *version,
int versionLen, const char *planeName, int planeNameLen,
const char *srcPath, int srcPathLen, char *errorMsg,
int errorMsgLen);
typedef int (*XNModelCodeCompileFunc)(const char *className, int classNameLen, const char *version,
int versionLen, const char *planeName, int planeNameLen,
char *errorMsg, int errorMsgLen);
// 测试参数
const char *className = "XNAerodynamics";
const char *version = "2.0.3.5";
const char *planeName = "C909";
void printResult(const std::string &testName, int result, const char *errorMsg)
{
std::cout << testName << " 结果: " << result << std::endl;
if (result == 0) {
std::cout << "" << testName << " 成功!" << std::endl;
} else {
std::cout << "" << testName << " 失败!" << std::endl;
}
if (strlen(errorMsg) > 0) {
std::cout << "错误信息: " << errorMsg << std::endl;
}
std::cout << std::endl;
}
int main()
{
// 动态加载.so库 - 修改路径指向build目录
void *handle = dlopen("../../build/libXNModelGenServer.so", RTLD_LAZY);
if (!handle) {
std::cerr << "无法加载库文件: " << dlerror() << std::endl;
return -1;
}
// 获取函数指针
XNModelCodeGenFunc XNModelCodeGen = (XNModelCodeGenFunc)dlsym(handle, "XNModelCodeGen");
XNModelCodeZipFunc XNModelCodeZip = (XNModelCodeZipFunc)dlsym(handle, "XNModelCodeZip");
XNModelCodeUnzipFunc XNModelCodeUnzip = (XNModelCodeUnzipFunc)dlsym(handle, "XNModelCodeUnzip");
XNModelCodeCompileFunc XNModelCodeCompile =
(XNModelCodeCompileFunc)dlsym(handle, "XNModelCodeCompile");
if (!XNModelCodeGen || !XNModelCodeZip || !XNModelCodeUnzip || !XNModelCodeCompile) {
std::cerr << "无法找到函数: " << dlerror() << std::endl;
dlclose(handle);
return -1;
}
int classNameLen = strlen(className);
int versionLen = strlen(version);
int planeNameLen = strlen(planeName);
// 错误消息缓冲区
char errorMsg[1024];
int errorMsgLen = sizeof(errorMsg);
std::cout << "开始测试XNModelGen函数..." << std::endl;
std::cout << "参数:" << std::endl;
std::cout << " className: " << className << " (长度: " << classNameLen << ")" << std::endl;
std::cout << " version: " << version << " (长度: " << versionLen << ")" << std::endl;
std::cout << " planeName: " << planeName << " (长度: " << planeNameLen << ")" << std::endl;
std::cout << std::endl;
// 测试1: XNModelCodeGen
std::cout << "=== 测试1: XNModelCodeGen ===" << std::endl;
memset(errorMsg, 0, sizeof(errorMsg));
int result1 = XNModelCodeGen(className, classNameLen, version, versionLen, planeName,
planeNameLen, errorMsg, errorMsgLen);
printResult("XNModelCodeGen", result1, errorMsg);
// 测试2: XNModelCodeZip
std::cout << "=== 测试2: XNModelCodeZip ===" << std::endl;
char dstPath[1024];
int dstPathLen = sizeof(dstPath);
memset(errorMsg, 0, sizeof(errorMsg));
memset(dstPath, 0, sizeof(dstPath));
int result2 = XNModelCodeZip(className, classNameLen, version, versionLen, planeName,
planeNameLen, dstPath, dstPathLen, errorMsg, errorMsgLen);
printResult("XNModelCodeZip", result2, errorMsg);
if (result2 == 0 && strlen(dstPath) > 0) {
std::cout << "生成的zip文件路径: " << dstPath << std::endl;
}
// 测试3: XNModelCodeUnzip
std::cout << "=== 测试3: XNModelCodeUnzip ===" << std::endl;
const char *srcZipPath = dstPath; // 使用上面生成的zip文件路径
int srcZipPathLen = strlen(srcZipPath);
memset(errorMsg, 0, sizeof(errorMsg));
int result3 = XNModelCodeUnzip(className, classNameLen, version, versionLen, planeName,
planeNameLen, srcZipPath, srcZipPathLen, errorMsg, errorMsgLen);
printResult("XNModelCodeUnzip", result3, errorMsg);
// 测试4: XNModelCodeCompile
std::cout << "=== 测试4: XNModelCodeCompile ===" << std::endl;
memset(errorMsg, 0, sizeof(errorMsg));
int result4 = XNModelCodeCompile(className, classNameLen, version, versionLen, planeName,
planeNameLen, errorMsg, errorMsgLen);
printResult("XNModelCodeCompile", result4, errorMsg);
// 清理资源
dlclose(handle);
std::cout << "=== 测试总结 ===" << std::endl;
std::cout << "XNModelCodeGen: " << (result1 == 0 ? "成功" : "失败") << std::endl;
std::cout << "XNModelCodeZip: " << (result2 == 0 ? "成功" : "失败") << std::endl;
std::cout << "XNModelCodeUnzip: " << (result3 == 0 ? "成功" : "失败") << std::endl;
std::cout << "XNModelCodeCompile: " << (result4 == 0 ? "成功" : "失败") << std::endl;
return (result1 == 0 && result2 == 0 && result3 == 0 && result4 == 0) ? 0 : -1;
}

View File

@ -0,0 +1,126 @@
#include <iostream>
#include <cstring>
#include <dlfcn.h>
// 函数指针类型定义
typedef int (*XNServiceCodeGenFunc)(const char *className, int classNameLen, const char *version,
int versionLen, char *errorMsg, int errorMsgLen);
typedef int (*XNServiceCodeZipFunc)(const char *className, int classNameLen, const char *version,
int versionLen, char *dstPath, int dstPathLen, char *errorMsg,
int errorMsgLen);
typedef int (*XNServiceCodeUnzipFunc)(const char *className, int classNameLen, const char *version,
int versionLen, const char *srcPath, int srcPathLen,
char *errorMsg, int errorMsgLen);
typedef int (*XNServiceCodeCompileFunc)(const char *className, int classNameLen,
const char *version, int versionLen, char *errorMsg,
int errorMsgLen);
// 测试参数
const char *className = "XNUDPService";
const char *version = "1.0.0.0";
const char *planeName = "XNUDPServer";
void printResult(const std::string &testName, int result, const char *errorMsg)
{
std::cout << testName << " 结果: " << result << std::endl;
if (result == 0) {
std::cout << "" << testName << " 成功!" << std::endl;
} else {
std::cout << "" << testName << " 失败!" << std::endl;
}
if (strlen(errorMsg) > 0) {
std::cout << "错误信息: " << errorMsg << std::endl;
}
std::cout << std::endl;
}
int main()
{
// 动态加载.so库 - 修改路径指向build目录
void *handle = dlopen("../../build/libXNServiceGenServer.so", RTLD_LAZY);
if (!handle) {
std::cerr << "无法加载库文件: " << dlerror() << std::endl;
return -1;
}
// 获取函数指针
XNServiceCodeGenFunc XNServiceCodeGen = (XNServiceCodeGenFunc)dlsym(handle, "XNServiceCodeGen");
XNServiceCodeZipFunc XNServiceCodeZip = (XNServiceCodeZipFunc)dlsym(handle, "XNServiceCodeZip");
XNServiceCodeUnzipFunc XNServiceCodeUnzip =
(XNServiceCodeUnzipFunc)dlsym(handle, "XNServiceCodeUnzip");
XNServiceCodeCompileFunc XNServiceCodeCompile =
(XNServiceCodeCompileFunc)dlsym(handle, "XNServiceCodeCompile");
if (!XNServiceCodeGen || !XNServiceCodeZip || !XNServiceCodeUnzip || !XNServiceCodeCompile) {
std::cerr << "无法找到函数: " << dlerror() << std::endl;
dlclose(handle);
return -1;
}
int classNameLen = strlen(className);
int versionLen = strlen(version);
// 错误消息缓冲区
char errorMsg[1024];
int errorMsgLen = sizeof(errorMsg);
std::cout << "开始测试XNModelGen函数..." << std::endl;
std::cout << "参数:" << std::endl;
std::cout << " className: " << className << " (长度: " << classNameLen << ")" << std::endl;
std::cout << " version: " << version << " (长度: " << versionLen << ")" << std::endl;
std::cout << std::endl;
// 测试1: XNModelCodeGen
std::cout << "=== 测试1: XNModelCodeGen ===" << std::endl;
memset(errorMsg, 0, sizeof(errorMsg));
int result1 =
XNServiceCodeGen(className, classNameLen, version, versionLen, errorMsg, errorMsgLen);
printResult("XNServiceCodeGen", result1, errorMsg);
// 测试2: XNModelCodeZip
std::cout << "=== 测试2: XNModelCodeZip ===" << std::endl;
char dstPath[1024];
int dstPathLen = sizeof(dstPath);
memset(errorMsg, 0, sizeof(errorMsg));
memset(dstPath, 0, sizeof(dstPath));
int result2 = XNServiceCodeZip(className, classNameLen, version, versionLen, dstPath,
dstPathLen, errorMsg, errorMsgLen);
printResult("XNServiceCodeZip", result2, errorMsg);
if (result2 == 0 && strlen(dstPath) > 0) {
std::cout << "生成的zip文件路径: " << dstPath << std::endl;
}
// 测试3: XNModelCodeUnzip
std::cout << "=== 测试3: XNModelCodeUnzip ===" << std::endl;
const char *srcZipPath = dstPath; // 使用上面生成的zip文件路径
int srcZipPathLen = strlen(srcZipPath);
memset(errorMsg, 0, sizeof(errorMsg));
int result3 = XNServiceCodeUnzip(className, classNameLen, version, versionLen, srcZipPath,
srcZipPathLen, errorMsg, errorMsgLen);
printResult("XNServiceCodeUnzip", result3, errorMsg);
// 测试4: XNModelCodeCompile
std::cout << "=== 测试4: XNModelCodeCompile ===" << std::endl;
memset(errorMsg, 0, sizeof(errorMsg));
int result4 =
XNServiceCodeCompile(className, classNameLen, version, versionLen, errorMsg, errorMsgLen);
printResult("XNServiceCodeCompile", result4, errorMsg);
// 清理资源
dlclose(handle);
std::cout << "=== 测试总结 ===" << std::endl;
std::cout << "XNServiceCodeGen: " << (result1 == 0 ? "成功" : "失败") << std::endl;
std::cout << "XNServiceCodeZip: " << (result2 == 0 ? "成功" : "失败") << std::endl;
std::cout << "XNServiceCodeUnzip: " << (result3 == 0 ? "成功" : "失败") << std::endl;
std::cout << "XNServiceCodeCompile: " << (result4 == 0 ? "成功" : "失败") << std::endl;
return (result1 == 0 && result2 == 0 && result3 == 0 && result4 == 0) ? 0 : -1;
}

View File

@ -1,9 +0,0 @@
{
"configurations": [
{
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}

View File

@ -1,77 +0,0 @@
{
"files.associations": {
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"future": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"ranges": "cpp",
"span": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
}
}

View File

@ -1,424 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 14.0.1, 2025-01-26T10:40:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{5b958118-2d32-49ab-8eab-9018ac74c7d6}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">5</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ClangdSettings">
<value type="bool" key="blockIndexing">true</value>
<value type="bool" key="useGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.7.2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.7.2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.672.linux_gcc_64_kit</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMake.Build.Type">Debug</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=Debug</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="CMake.Build.Type">Release</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-RelWithDebInfo</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
<value type="QString" key="CMake.Build.Type">MinSizeRel</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=MinSizeRel</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-MinSizeRel</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -1,229 +0,0 @@
#include "XNUDPService.h"
#include "XNUDPService_p.h"
#include <XNCore/XNServiceManager.h>
#include <XNCore/XNDDSManager.h>
#include <fstream>
#include <sstream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <XNCore/XNByteArray.h>
XN_SERVICE_INITIALIZE(XNUDPService)
XNUDPService::XNUDPService() : XNServiceObject(new XNUDPServicePrivate())
{
}
XNUDPService::~XNUDPService()
{
T_D();
if (d->udpSocket >= 0) {
close(d->udpSocket);
d->udpSocket = -1;
}
};
XNUDPService::XNUDPService(PrivateType *p) : XNServiceObject(p)
{
}
void XNUDPService::Initialize()
{
XNServiceObject::Initialize();
T_D();
if (d->_initialType == 0) {
// 读取配置文件
std::ifstream file(GetXmlPath());
if (!file.is_open()) {
LOG_WARNING("无法打开配置文件:%1使用默认值", GetXmlPath().c_str());
d->localPort = 12345;
d->targetHost = "127.0.0.1";
d->targetPort = 54321;
return;
}
std::stringstream buffer;
buffer << file.rdbuf();
std::string content = buffer.str();
file.close();
// 简单的XML解析
size_t udpPos = content.find("<UDP>");
if (udpPos != std::string::npos) {
size_t localPortPos = content.find("<LocalPort>", udpPos);
size_t targetHostPos = content.find("<TargetHost>", udpPos);
size_t targetPortPos = content.find("<TargetPort>", udpPos);
if (localPortPos != std::string::npos) {
size_t endPos = content.find("</LocalPort>", localPortPos);
d->localPort =
std::stoi(content.substr(localPortPos + 11, endPos - localPortPos - 11));
}
if (targetHostPos != std::string::npos) {
size_t endPos = content.find("</TargetHost>", targetHostPos);
d->targetHost = content.substr(targetHostPos + 12, endPos - targetHostPos - 12);
}
if (targetPortPos != std::string::npos) {
size_t endPos = content.find("</TargetPort>", targetPortPos);
d->targetPort =
std::stoi(content.substr(targetPortPos + 12, endPos - targetPortPos - 12));
}
} else {
LOG_WARNING("未找到UDP配置, 使用默认值");
d->localPort = 12345;
d->targetHost = "127.0.0.1";
d->targetPort = 54321;
}
} else {
try {
if (d->_otherParams.contains("LocalPort")) {
d->localPort = d->_otherParams["LocalPort"].get<int>();
}
if (d->_otherParams.contains("TargetHost")) {
d->targetHost = d->_otherParams["TargetHost"].get<std::string>();
}
if (d->_otherParams.contains("TargetPort")) {
d->targetPort = d->_otherParams["TargetPort"].get<int>();
}
LOG_INFO("UDP配置: 本地端口:%1, 目标主机:%2, 目标端口:%3", d->localPort, d->targetHost,
d->targetPort);
} catch (const std::exception &e) {
LOG_WARNING("解析JSON参数失败: %1, 使用默认值", e.what());
d->localPort = 12345;
d->targetHost = "127.0.0.1";
d->targetPort = 54321;
}
}
}
void XNUDPService::PrepareForExecute()
{
XNServiceObject::PrepareForExecute();
T_D();
// 初始化UDP socket
d->udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (d->udpSocket < 0) {
LOG_WARNING("无法创建UDP socket");
return;
}
// 设置非阻塞模式
int flags = fcntl(d->udpSocket, F_GETFL, 0);
fcntl(d->udpSocket, F_SETFL, flags | O_NONBLOCK);
// 绑定本地端口
struct sockaddr_in localAddr;
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = INADDR_ANY;
localAddr.sin_port = htons(d->localPort);
if (bind(d->udpSocket, (struct sockaddr *)&localAddr, sizeof(localAddr)) < 0) {
LOG_WARNING("UDP socket 绑定失败, 端口:%d", d->localPort);
close(d->udpSocket);
d->udpSocket = -1;
return;
}
RegisterRTEventHandler("SendUDPData",
std::bind(&XNUDPService::SendData, this, std::placeholders::_1));
}
void XNUDPService::HandleIncomingData()
{
T_D();
if (d->udpSocket < 0)
return;
char buffer[65536];
struct sockaddr_in senderAddr;
socklen_t senderLen = sizeof(senderAddr);
while (true) {
ssize_t bytesRead = recvfrom(d->udpSocket, buffer, sizeof(buffer), 0,
(struct sockaddr *)&senderAddr, &senderLen);
if (bytesRead <= 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
break; // 没有更多数据
}
LOG_WARNING("读取UDP socket失败");
break;
}
if (bytesRead <= 8) {
LOG_WARNING("UDP 数据包小于8字节");
continue;
}
// 将数据转换为XNByteArray
XNByteArray datagram;
datagram.resize(bytesRead);
memcpy(datagram.data(), buffer, bytesRead);
if (datagram[0] != 0xa6) {
LOG_WARNING("UDP 数据包头无效, 头:%1", datagram[0]);
continue;
}
if (datagram[5] != 0x00) {
LOG_WARNING("UDP 数据包传输方向错误, 方向:%1", datagram[5]);
continue;
}
uint16_t dataSize = ((uint16_t)datagram[6] << 8) | (uint16_t)datagram[7];
if (dataSize != bytesRead) {
LOG_WARNING("UDP 数据包大小无效, 大小:%d, 实际大小:%zd", dataSize, bytesRead - 8);
continue;
}
uint8_t planeHeader = datagram[1];
uint8_t ataHeader = datagram[2];
uint8_t modelHeader = datagram[3];
uint8_t structHeader = datagram[4];
if (planeHeader == 0xc0) { //C909数据
if (ataHeader == 0x04) { //ATA04章节数据
if (modelHeader == 0x00 && structHeader == 0x00) { //气动输入数据
TriggerRTEvent("C909::ATA04::AeroInput", datagram);
continue;
} else if (modelHeader == 0x01 && structHeader == 0x00) { //地操输入数据
TriggerRTEvent("C909::ATA04::GhInput", datagram);
continue;
} else if (modelHeader == 0x02 && structHeader == 0x00) { //质量输入数据
TriggerRTEvent("C909::ATA04::WbInput", datagram);
continue;
}
}
} else {
TriggerRTEvent("ReceiveUDPData", datagram);
}
}
}
void XNUDPService::SendData(const std::any &data)
{
T_D();
if (d->udpSocket < 0) {
LOG_WARNING("UDP socket not initialized");
return;
}
struct sockaddr_in targetAddr;
memset(&targetAddr, 0, sizeof(targetAddr));
targetAddr.sin_family = AF_INET;
targetAddr.sin_port = htons(d->targetPort);
inet_pton(AF_INET, d->targetHost.c_str(), &targetAddr.sin_addr);
XNByteArray packet = std::any_cast<XNByteArray>(data);
ssize_t bytesSent = sendto(d->udpSocket, packet.data(), packet.size(), 0,
(struct sockaddr *)&targetAddr, sizeof(targetAddr));
if (bytesSent < 0) {
LOG_WARNING("Failed to send UDP datagram: %s", strerror(errno));
}
}

View File

@ -1,27 +0,0 @@
#pragma once
#include "XNUDPService_global.h"
#include <XNCore/XNServiceObject.h>
#include <string>
#include <memory>
struct XNUDPServicePrivate;
class XNUDPSERVICE_EXPORT XNUDPService : public XNServiceObject
{
XN_METATYPE(XNUDPService, XNServiceObject)
XN_DECLARE_PRIVATE(XNUDPService)
public:
explicit XNUDPService();
virtual ~XNUDPService();
protected:
XNUDPService(PrivateType *p);
public:
virtual void Initialize() override;
virtual void PrepareForExecute() override;
void HandleIncomingData();
void SendData(const std::any &data);
};
XNCLASS_PTR_DECLARE(XNUDPService)

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNUDPService</Name>
<Description>UDP通信服务</Description>
<Author>Jin</Author>
<Version>1.0.0</Version>
<CreateTime>2025-02-04 10:00:00</CreateTime>
<ChangeTime>2025-02-04 10:00:00</ChangeTime>
<CommandList>
<Command Name="TestCmd" Description="Test" Call="TestCall"/>
</CommandList>
<UDP>
<LocalPort>12345</LocalPort>
<TargetHost>127.0.0.1</TargetHost>
<TargetPort>54321</TargetPort>
</UDP>
</Service>

View File

@ -1,15 +0,0 @@
#pragma once
#include <XNCore/XNServiceObject_p.h>
#include <string>
#include <memory>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
struct XNUDPServicePrivate : public XNServiceObjectPrivate {
int udpSocket{-1};
std::string targetHost;
uint16_t targetPort{0};
uint16_t localPort{0};
};

View File

@ -1,9 +0,0 @@
{
"configurations": [
{
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}

View File

@ -1,5 +0,0 @@
{
"files.associations": {
"functional": "cpp"
}
}

View File

@ -1,65 +0,0 @@
cmake_minimum_required(VERSION 3.16)
project(XNUDPTestService LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#
if(DEFINED ENV{XNCore})
set(XNCore_PATH $ENV{XNCore})
else()
message(FATAL_ERROR "Environment variable XNCore is not set.")
endif()
# XNCore_PATH include
include_directories(${XNCore_PATH}/include)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network Xml)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Network Xml)
add_library(XNUDPTestService SHARED
XNUDPTestService_global.h
XNUDPTestService.cpp
XNUDPTestService.h
XNUDPTestService_p.h
)
target_link_libraries(XNUDPTestService PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Xml
${XNCore_PATH}/lib/libXNCore.so
)
# Qt
get_target_property(QT_LIB_DIR Qt${QT_VERSION_MAJOR}::Core LOCATION)
get_filename_component(QT_LIB_DIR ${QT_LIB_DIR} DIRECTORY)
# rpath
set_target_properties(XNUDPTestService PROPERTIES
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_RPATH "${QT_LIB_DIR}"
)
target_compile_definitions(XNUDPTestService PRIVATE XNUDPSERVICE_LIBRARY)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${XNCore_PATH}/Services" CACHE PATH "Install path prefix" FORCE)
endif()
include(GNUInstallDirs)
install(TARGETS XNUDPTestService
BUNDLE DESTINATION .
LIBRARY DESTINATION .
RUNTIME DESTINATION .
)
#
file(GLOB CONFIG_FILE "*.scfg")
# 使 install
install(FILES ${CONFIG_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX})

View File

@ -1,424 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 14.0.1, 2025-01-26T10:40:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{5b958118-2d32-49ab-8eab-9018ac74c7d6}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">5</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ClangdSettings">
<value type="bool" key="blockIndexing">true</value>
<value type="bool" key="useGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.7.2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.7.2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.672.linux_gcc_64_kit</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMake.Build.Type">Debug</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=Debug</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="CMake.Build.Type">Release</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-RelWithDebInfo</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
<value type="QString" key="CMake.Build.Type">MinSizeRel</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Unix Makefiles
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
-DCMAKE_BUILD_TYPE:STRING=MinSizeRel</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/media/jin/E/MyCode/xnsim/XNModels/XNAerodynamics/build/Desktop_Qt_6_7_2-MinSizeRel</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

View File

@ -1,133 +0,0 @@
#include "XNUDPTestService.h"
#include "XNUDPTestService_p.h"
#include <XNCore/XNServiceManager.h>
#include <XNCore/XNDDSManager.h>
#include <QFile>
#include <QDomDocument>
XN_DLL_INITIALIZE(XNUDPTestService)
XN_REGISTER_SERVICE_BEGIN_SERVICE(XNUDPTestService)
XN_REGISTER_SERVICE_END_SERVICE(XNUDPTestService)
XNUDPTestService::XNUDPTestService(QObject *parent)
: XNServiceObject(*new XNUDPTestServicePrivate(this), parent)
{
}
XNUDPTestService::~XNUDPTestService()
{
}
XNUDPTestService::XNUDPTestService(XNUDPTestServicePrivate &dd, QObject *parent)
: XNServiceObject(dd, parent)
{
}
void XNUDPTestService::OnInitialize()
{
Q_D(XNUDPTestService);
XNServiceObject::OnInitialize();
// 读取配置文件
QFile file(GetXmlPath());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
LOG_WARNING("Failed to open config file:%1", GetXmlPath());
return;
}
QDomDocument doc;
if (!doc.setContent(&file)) {
file.close();
LOG_WARNING("Failed to parse config file:%1", GetXmlPath());
return;
}
file.close();
// 读取UDP配置
QDomElement udpElement = doc.documentElement().firstChildElement("UDP");
if (!udpElement.isNull()) {
d->localPort = udpElement.firstChildElement("LocalPort").text().toUInt();
d->targetHost = udpElement.firstChildElement("TargetHost").text();
d->targetPort = udpElement.firstChildElement("TargetPort").text().toUInt();
} else {
LOG_WARNING("UDP configuration not found, using default values");
d->localPort = 12345;
d->targetHost = "127.0.0.1";
d->targetPort = 54321;
}
}
void XNUDPTestService::OnPrepareForExecute()
{
Q_D(XNUDPTestService);
XNServiceObject::OnPrepareForExecute();
// 初始化UDP socket
d->udpSocket = new QUdpSocket(this);
// 绑定本地端口
if (!d->udpSocket->bind(QHostAddress::Any, d->localPort)) {
LOG_WARNING("UDP socket bind failed on port:%1", d->localPort);
return;
}
// 连接UDP socket的信号
//connect(d->udpSocket, &QUdpSocket::readyRead, this, &XNUDPTestService::HandleIncomingData);
RegisterRTEventHandler("SendTestUDPData",
std::bind(&XNUDPTestService::SendData, this, std::placeholders::_1));
}
void XNUDPTestService::HandleIncomingData()
{
Q_D(XNUDPTestService);
return;
while (d->udpSocket->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(d->udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
d->udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
// 处理接收到的数据
if (datagram.size() <= 5 || datagram[0] != 0x0b || datagram[4] != datagram.size()) {
LOG_WARNING("Invalid UDP datagram received");
continue;
}
if (datagram[1] == 0x04) {
if (datagram[2] == 0x00 && datagram[3] == 0x00) {
TriggerRTEvent("ATA04AeroInput", datagram);
continue;
} else if (datagram[2] == 0x01 && datagram[3] == 0x00) {
TriggerRTEvent("ATA04GhInput", datagram);
continue;
} else if (datagram[2] == 0x02 && datagram[3] == 0x00) {
TriggerRTEvent("ATA04WbInput", datagram);
continue;
}
}
// TODO: 根据具体需求处理其它数据
//TriggerRTEvent("ReceiveUDPData", datagram);
}
}
void XNUDPTestService::SendData(const QVariant &data)
{
Q_D(XNUDPTestService);
if (!d->udpSocket) {
LOG_WARNING("UDP socket not initialized");
return;
}
// 将QVariant转换为字节数组
QByteArray datagram = data.toByteArray();
// 发送数据
qint64 bytesSent =
d->udpSocket->writeDatagram(datagram, QHostAddress(d->targetHost), d->targetPort);
if (bytesSent == -1) {
LOG_WARNING("Failed to send UDP datagram:%1", d->udpSocket->errorString());
}
}

View File

@ -1,29 +0,0 @@
#pragma once
#include "XNUDPTestService_global.h"
#include <XNCore/XNServiceObject.h>
#include <QVariant>
class XNUDPTestServicePrivate;
class XNUDPTESTSERVICE_EXPORT XNUDPTestService : public XNServiceObject
{
Q_OBJECT
Q_DISABLE_COPY(XNUDPTestService)
Q_DECLARE_PRIVATE(XNUDPTestService)
XN_DECLARE_DDS_SERVICE()
public:
explicit XNUDPTestService(QObject *parent = nullptr);
virtual ~XNUDPTestService();
protected:
XNUDPTestService(XNUDPTestServicePrivate &dd, QObject *parent = nullptr);
public slots:
virtual void OnInitialize() override;
virtual void OnPrepareForExecute() override;
void HandleIncomingData();
public:
void SendData(const QVariant &data);
};
Q_DECLARE_METATYPE(XNUDPTestService)

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Service>
<Name>XNUDPTestService</Name>
<Description>UDP通信服务</Description>
<Author>Jin</Author>
<Version>1.0.0</Version>
<CreateTime>2025-02-04 10:00:00</CreateTime>
<ChangeTime>2025-02-04 10:00:00</ChangeTime>
<CommandList>
<Command Name="TestCmd" Description="Test" Call="TestCall"/>
</CommandList>
<UDP>
<LocalPort>54321</LocalPort>
<TargetHost>127.0.0.1</TargetHost>
<TargetPort>12345</TargetPort>
</UDP>
</Service>

View File

@ -1,12 +0,0 @@
#ifndef XNUDPTESTSERVICE_GLOBAL_H
#define XNUDPTESTSERVICE_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(XNUDPTESTSERVICE_LIBRARY)
# define XNUDPTESTSERVICE_EXPORT Q_DECL_EXPORT
#else
# define XNUDPTESTSERVICE_EXPORT Q_DECL_IMPORT
#endif
#endif // XNUDPTESTSERVICE_GLOBAL_H

View File

@ -1,17 +0,0 @@
#pragma once
#include <XNCore/XNServiceObject_p.h>
#include <QUdpSocket>
#include <QString>
class XNUDPTestServicePrivate : public XNServiceObjectPrivate
{
public:
Q_DECLARE_PUBLIC(XNUDPTestService)
XNUDPTestServicePrivate(XNUDPTestService *q) : XNServiceObjectPrivate(q) {}
QUdpSocket *udpSocket{nullptr};
QString targetHost;
quint16 targetPort{0};
quint16 localPort{0};
};

View File

@ -407,7 +407,7 @@ class ServiceDevelopment extends HTMLElement {
async init() {
try {
const response = await fetch('/api/services');
const response = await fetch('/api/service-dev/services');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
@ -421,7 +421,7 @@ class ServiceDevelopment extends HTMLElement {
async fetchServiceVersions(className, serviceName) {
try {
const response = await fetch(`/api/service-versions/${encodeURIComponent(className)}`);
const response = await fetch(`/api/service-dev/service-versions/${encodeURIComponent(className)}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
@ -466,7 +466,7 @@ class ServiceDevelopment extends HTMLElement {
versionData.OtherParam = '{}';
}
const response = await fetch('/api/service-versions', {
const response = await fetch('/api/service-dev/service-versions', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@ -1758,7 +1758,7 @@ class ServiceDevelopment extends HTMLElement {
Description: serviceData.Description || ''
};
const response = await fetch('/api/services', {
const response = await fetch('/api/service-dev/services', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@ -1779,31 +1779,376 @@ class ServiceDevelopment extends HTMLElement {
}
// 生成模板代码
generateTemplateCode() {
console.log('生成模板代码功能');
// TODO: 实现生成模板代码的具体功能
alert('生成模板代码功能即将上线');
async generateTemplateCode() {
try {
// 检查是否有当前版本数据
if (!this.currentVersion || !this.currentVersion.ClassName || !this.currentVersion.Version) {
alert('请先保存版本信息,然后再生成模板代码');
return;
}
// 找到对应的按钮并更新状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('生成模板代码') ||
btn.onclick && btn.onclick.toString().includes('generateTemplateCode')
);
const originalText = button ? button.textContent : '生成模板代码';
if (button) {
button.textContent = '正在生成...';
button.disabled = true;
}
// 调用生成代码API
const response = await fetch('/api/service-dev/generate-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
className: this.currentVersion.ClassName,
version: this.currentVersion.Version
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || `HTTP错误! 状态码: ${response.status}`);
}
const result = await response.json();
if (result.success) {
alert(`模板代码生成成功!\n${result.message}`);
} else {
throw new Error(result.error || '生成失败');
}
} catch (error) {
console.error('生成模板代码失败:', error);
alert(`生成模板代码失败: ${error.message}`);
} finally {
// 恢复按钮状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('正在生成...') ||
btn.textContent.includes('生成模板代码')
);
if (button) {
button.textContent = '生成模板代码';
button.disabled = false;
}
}
}
// 下载模板代码
downloadTemplateCode() {
console.log('下载模板代码功能');
// TODO: 实现下载模板代码的具体功能
alert('下载模板代码功能即将上线');
async downloadTemplateCode() {
try {
// 检查是否有当前版本数据
if (!this.currentVersion || !this.currentVersion.ClassName || !this.currentVersion.Version) {
alert('请先保存版本信息,然后再下载模板代码');
return;
}
// 找到对应的按钮并更新状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('下载模板代码') ||
btn.onclick && btn.onclick.toString().includes('downloadTemplateCode')
);
const originalText = button ? button.textContent : '下载模板代码';
if (button) {
button.textContent = '正在打包...';
button.disabled = true;
}
// 第一步调用打包API
const zipResponse = await fetch('/api/service-dev/zip-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
className: this.currentVersion.ClassName,
version: this.currentVersion.Version
})
});
if (!zipResponse.ok) {
const errorData = await zipResponse.json();
throw new Error(errorData.error || `打包失败! 状态码: ${zipResponse.status}`);
}
const zipResult = await zipResponse.json();
if (!zipResult.success) {
throw new Error(zipResult.error || '打包失败');
}
// 更新按钮状态为下载中
if (button) {
button.textContent = '正在下载...';
}
// 第二步调用下载API
const downloadResponse = await fetch('/api/service-dev/download-zip', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
filePath: zipResult.dstPath
})
});
if (!downloadResponse.ok) {
const errorData = await downloadResponse.json();
throw new Error(errorData.error || `下载失败! 状态码: ${downloadResponse.status}`);
}
// 获取文件名
const fileName = `${this.currentVersion.ClassName}_${this.currentVersion.Version}.zip`;
// 创建下载链接
const blob = await downloadResponse.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
alert(`模板代码下载成功!\n文件路径: ${zipResult.dstPath}\n文件名: ${fileName}`);
} catch (error) {
console.error('下载模板代码失败:', error);
alert(`下载模板代码失败: ${error.message}`);
} finally {
// 恢复按钮状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('正在下载...') ||
btn.textContent.includes('正在打包...') ||
btn.textContent.includes('下载模板代码')
);
if (button) {
button.textContent = '下载模板代码';
button.disabled = false;
}
}
}
// 上传服务代码
uploadServiceCode() {
console.log('上传服务代码功能');
// TODO: 实现上传服务代码的具体功能
alert('上传服务代码功能即将上线');
async uploadServiceCode() {
try {
// 检查是否有当前版本数据
if (!this.currentVersion || !this.currentVersion.ClassName || !this.currentVersion.Version) {
alert('请先保存版本信息,然后再上传服务代码');
return;
}
// 找到对应的按钮并更新状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('上传服务代码') ||
btn.onclick && btn.onclick.toString().includes('uploadServiceCode')
);
const originalText = button ? button.textContent : '上传服务代码';
if (button) {
button.textContent = '选择文件中...';
button.disabled = true;
}
// 创建文件输入元素
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.zip';
fileInput.style.display = 'none';
// 添加到DOM
document.body.appendChild(fileInput);
// 监听文件选择
fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0];
if (!file) {
// 恢复按钮状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('选择文件中...') ||
btn.textContent.includes('上传服务代码')
);
if (button) {
button.textContent = '上传服务代码';
button.disabled = false;
}
document.body.removeChild(fileInput);
return;
}
try {
// 验证文件类型
if (!file.name.toLowerCase().endsWith('.zip')) {
throw new Error('请选择ZIP格式的压缩包文件');
}
// 更新按钮状态为上传中
if (button) {
button.textContent = '正在上传...';
}
// 第一步:上传文件
const formData = new FormData();
formData.append('file', file);
formData.append('className', this.currentVersion.ClassName);
formData.append('version', this.currentVersion.Version);
const uploadResponse = await fetch('/api/service-dev/upload-zip', {
method: 'POST',
body: formData
});
if (!uploadResponse.ok) {
const errorData = await uploadResponse.json();
throw new Error(errorData.error || `上传失败! 状态码: ${uploadResponse.status}`);
}
const uploadResult = await uploadResponse.json();
if (!uploadResult.success) {
throw new Error(uploadResult.error || '上传失败');
}
// 更新按钮状态为解压中
if (button) {
button.textContent = '正在解压...';
}
// 第二步:解压文件
const unzipResponse = await fetch('/api/service-dev/unzip-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
className: this.currentVersion.ClassName,
version: this.currentVersion.Version,
srcPath: uploadResult.filePath
})
});
if (!unzipResponse.ok) {
const errorData = await unzipResponse.json();
throw new Error(errorData.error || `解压失败! 状态码: ${unzipResponse.status}`);
}
const unzipResult = await unzipResponse.json();
if (unzipResult.success) {
alert(`服务代码上传并解压成功!\n原始文件名: ${uploadResult.originalName}\n保存路径: ${uploadResult.filePath}\n${unzipResult.message}`);
} else {
throw new Error(unzipResult.error || '解压失败');
}
} catch (error) {
console.error('上传服务代码失败:', error);
alert(`上传服务代码失败: ${error.message}`);
} finally {
// 恢复按钮状态
if (button) {
button.textContent = '上传服务代码';
button.disabled = false;
}
// 清理文件输入元素
document.body.removeChild(fileInput);
}
});
// 触发文件选择对话框
fileInput.click();
} catch (error) {
console.error('上传服务代码失败:', error);
alert(`上传服务代码失败: ${error.message}`);
// 恢复按钮状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('选择文件中...') ||
btn.textContent.includes('正在上传...') ||
btn.textContent.includes('正在解压...') ||
btn.textContent.includes('上传服务代码')
);
if (button) {
button.textContent = '上传服务代码';
button.disabled = false;
}
}
}
// 服务编译发布
compileAndPublishService() {
console.log('服务编译发布功能');
// TODO: 实现服务编译发布的具体功能
alert('服务编译发布功能即将上线');
async compileAndPublishService() {
try {
// 检查是否有当前版本数据
if (!this.currentVersion || !this.currentVersion.ClassName || !this.currentVersion.Version) {
alert('请先保存版本信息,然后再编译发布服务');
return;
}
// 找到对应的按钮并更新状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('服务编译发布') ||
btn.onclick && btn.onclick.toString().includes('compileAndPublishService')
);
const originalText = button ? button.textContent : '服务编译发布';
if (button) {
button.textContent = '正在编译...';
button.disabled = true;
}
// 调用编译API
const response = await fetch('/api/service-dev/compile-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
className: this.currentVersion.ClassName,
version: this.currentVersion.Version
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || `HTTP错误! 状态码: ${response.status}`);
}
const result = await response.json();
if (result.success) {
alert(`服务编译发布成功!\n${result.message}`);
} else {
throw new Error(result.error || '编译失败');
}
} catch (error) {
console.error('服务编译发布失败:', error);
alert(`服务编译发布失败: ${error.message}`);
} finally {
// 恢复按钮状态
const buttons = this.shadowRoot.querySelectorAll('button');
const button = Array.from(buttons).find(btn =>
btn.textContent.includes('正在编译...') ||
btn.textContent.includes('服务编译发布')
);
if (button) {
button.textContent = '服务编译发布';
button.disabled = false;
}
}
}
}

View File

@ -1,11 +1,20 @@
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const {
getServices,
getServiceVersionsByClassName,
saveServiceVersion,
createService
} = require('../utils/service-utils');
const {
serviceCodeGen,
serviceCodeZip,
serviceCodeUnzip,
serviceCodeCompile
} = require('../utils/xnCoreService');
// 获取所有服务列表
router.get('/services', (req, res) => {
@ -105,4 +114,222 @@ router.post('/services', (req, res) => {
}
});
// 生成服务代码
router.post('/generate-code', (req, res) => {
try {
const { className, version } = req.body;
if (!className || !version) {
return res.status(400).json({ error: '缺少必要的参数className 和 version' });
}
const result = serviceCodeGen(className, version);
if (result.includes('成功')) {
res.json({ success: true, message: result });
} else {
res.status(500).json({ success: false, error: result });
}
} catch (error) {
console.error(`生成服务代码失败: ${error.message}`);
res.status(500).json({ error: '生成服务代码失败', details: error.message });
}
});
// 压缩服务代码
router.post('/zip-code', (req, res) => {
try {
const { className, version } = req.body;
if (!className || !version) {
return res.status(400).json({ error: '缺少必要的参数className 和 version' });
}
const result = serviceCodeZip(className, version);
if (result.success) {
res.json({
success: true,
message: result.message,
dstPath: result.dstPath
});
} else {
res.status(500).json({ success: false, error: result.message });
}
} catch (error) {
console.error(`压缩服务代码失败: ${error.message}`);
res.status(500).json({ error: '压缩服务代码失败', details: error.message });
}
});
// 解压服务代码
router.post('/unzip-code', (req, res) => {
try {
const { className, version, srcPath } = req.body;
if (!className || !version || !srcPath) {
return res.status(400).json({ error: '缺少必要的参数className、version 和 srcPath' });
}
const result = serviceCodeUnzip(className, version, srcPath);
if (result.includes('成功')) {
res.json({ success: true, message: result });
} else {
res.status(500).json({ success: false, error: result });
}
} catch (error) {
console.error(`解压服务代码失败: ${error.message}`);
res.status(500).json({ error: '解压服务代码失败', details: error.message });
}
});
// 编译服务代码
router.post('/compile-code', (req, res) => {
try {
const { className, version } = req.body;
if (!className || !version) {
return res.status(400).json({ error: '缺少必要的参数className 和 version' });
}
const result = serviceCodeCompile(className, version);
if (result.includes('成功')) {
res.json({ success: true, message: result });
} else {
res.status(500).json({ success: false, error: result });
}
} catch (error) {
console.error(`编译服务代码失败: ${error.message}`);
res.status(500).json({ error: '编译服务代码失败', details: error.message });
}
});
// 下载ZIP文件
router.post('/download-zip', (req, res) => {
try {
const { filePath } = req.body;
if (!filePath) {
return res.status(400).json({ error: '缺少文件路径参数' });
}
// 检查文件是否存在
if (!fs.existsSync(filePath)) {
return res.status(404).json({ error: '文件不存在' });
}
// 检查文件是否为ZIP格式
if (!filePath.toLowerCase().endsWith('.zip')) {
return res.status(400).json({ error: '只能下载ZIP格式的文件' });
}
// 获取文件名
const fileName = path.basename(filePath);
// 设置响应头
res.setHeader('Content-Type', 'application/zip');
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
// 发送文件
res.sendFile(filePath);
} catch (error) {
console.error(`下载ZIP文件失败: ${error.message}`);
res.status(500).json({ error: '下载ZIP文件失败', details: error.message });
}
});
// 配置multer用于文件上传
const storage = multer.diskStorage({
destination: function (req, file, cb) {
// 获取XNCore环境变量
const xnCorePath = process.env.XNCore || '';
if (!xnCorePath) {
return cb(new Error('XNCore环境变量未设置'));
}
// 创建ServiceProjects目录
const serviceProjectsDir = path.join(xnCorePath, 'ServiceProjects');
if (!fs.existsSync(serviceProjectsDir)) {
fs.mkdirSync(serviceProjectsDir, { recursive: true });
}
cb(null, serviceProjectsDir);
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const upload = multer({
storage: storage,
fileFilter: function (req, file, cb) {
// 只允许ZIP文件
if (file.mimetype === 'application/zip' || file.originalname.toLowerCase().endsWith('.zip')) {
cb(null, true);
} else {
cb(new Error('只允许上传ZIP格式的文件'), false);
}
},
limits: {
fileSize: 100 * 1024 * 1024 // 限制100MB
}
});
// 上传ZIP文件
router.post('/upload-zip', upload.single('file'), (req, res) => {
try {
// 检查XNCore环境变量
const xnCorePath = process.env.XNCore || '';
if (!xnCorePath) {
return res.status(500).json({ error: 'XNCore环境变量未设置' });
}
if (!req.file) {
return res.status(400).json({ error: '没有选择文件' });
}
const filePath = req.file.path;
const fileName = req.file.filename;
// 验证文件是否成功保存到ServiceProjects目录
if (!fs.existsSync(filePath)) {
return res.status(500).json({ error: '文件上传失败,文件未保存到目标目录' });
}
res.json({
success: true,
message: '文件上传成功',
filePath: filePath,
fileName: fileName,
originalName: req.file.originalname,
uploadDir: path.dirname(filePath)
});
} catch (error) {
console.error(`上传ZIP文件失败: ${error.message}`);
res.status(500).json({ error: '上传ZIP文件失败', details: error.message });
}
});
// 处理multer错误
router.use('/upload-zip', (error, req, res, next) => {
if (error instanceof multer.MulterError) {
if (error.code === 'LIMIT_FILE_SIZE') {
return res.status(400).json({ error: '文件大小超过限制最大100MB' });
}
return res.status(400).json({ error: `文件上传错误: ${error.message}` });
}
if (error.message === 'XNCore环境变量未设置') {
return res.status(500).json({ error: 'XNCore环境变量未设置无法上传文件' });
}
if (error.message.includes('只允许上传ZIP格式的文件')) {
return res.status(400).json({ error: '只允许上传ZIP格式的文件' });
}
console.error('文件上传错误:', error);
res.status(500).json({ error: '文件上传失败', details: error.message });
});
module.exports = router;

View File

@ -94,7 +94,7 @@ app.use('/api', authRoutes);
app.use('/api', versionRoutes);
app.use('/api/filesystem', filesystemRoutes);
app.use('/api', systemInfoRoutes);
app.use('/api', serviceApiRoutes);
app.use('/api/service-dev', serviceApiRoutes);
app.use('/api', ataChaptersRoutes);
app.use('/api', simulationRoutes);
app.use('/api/udp-monitor', udpMonitorRoutes);

View File

@ -27,6 +27,10 @@ const interfaceGenLibPath = path.join(xnCorePath, 'lib', interfaceGenLibName);
const modelGenLibName = `${libPrefix}XNModelGenServer${libExtension}`;
const modelGenLibPath = path.join(xnCorePath, 'lib', modelGenLibName);
// ServiceGenServer库配置
const serviceGenLibName = `${libPrefix}XNServiceGenServer${libExtension}`;
const serviceGenLibPath = path.join(xnCorePath, 'lib', serviceGenLibName);
// 定义Buffer类型
const BufferType = ref.refType(ref.types.void);
const StringType = ref.types.CString;
@ -37,6 +41,7 @@ let loginLib;
let monitorLib;
let interfaceGenLib;
let modelGenLib;
let serviceGenLib;
try {
loginLib = ffi.Library(loginLibPath, {
@ -115,6 +120,17 @@ try {
console.error(`加载 ${modelGenLibName} 失败:`, error);
}
try {
serviceGenLib = ffi.Library(serviceGenLibPath, {
'XNServiceCodeGen': ['int', [StringType, 'int', StringType, 'int', StringType, 'int']],
'XNServiceCodeZip': ['int', [StringType, 'int', StringType, 'int', StringType, 'int', StringType, 'int']],
'XNServiceCodeUnzip': ['int', [StringType, 'int', StringType, 'int', StringType, 'int', StringType, 'int']],
'XNServiceCodeCompile': ['int', [StringType, 'int', StringType, 'int', StringType, 'int']]
});
} catch (error) {
console.error(`加载 ${serviceGenLibName} 失败:`, error);
}
// 注册进程退出时的清理函数
function performCleanup() {
console.log('正在执行清理操作...');
@ -907,11 +923,108 @@ function modelCodeCompile(className, version, planeName) {
}
}
// ========== XNServiceGenServer 封装函数 ==========
// 生成服务代码
function serviceCodeGen(className, version) {
if (!serviceGenLib) {
return '服务生成库未加载';
}
try {
const errorMsg = Buffer.alloc(1024);
const result = serviceGenLib.XNServiceCodeGen(
className, className.length,
version, version.length,
errorMsg, errorMsg.length
);
if (result !== 0) {
return `生成服务代码失败: ${errorMsg.toString('utf8').replace(/\0/g, '')}`;
}
return '生成服务代码成功';
} catch (error) {
return `生成服务代码失败: ${error.message}`;
}
}
// 压缩服务代码
function serviceCodeZip(className, version) {
if (!serviceGenLib) {
return '服务生成库未加载';
}
try {
const dstPath = Buffer.alloc(1024);
const errorMsg = Buffer.alloc(1024);
const result = serviceGenLib.XNServiceCodeZip(
className, className.length,
version, version.length,
dstPath, dstPath.length,
errorMsg, errorMsg.length
);
if (result !== 0) {
return `压缩服务代码失败: ${errorMsg.toString('utf8').replace(/\0/g, '')}`;
}
return {
success: true,
dstPath: dstPath.toString('utf8').replace(/\0/g, ''),
message: '压缩服务代码成功'
};
} catch (error) {
return {
success: false,
message: `压缩服务代码失败: ${error.message}`
};
}
}
// 解压服务代码
function serviceCodeUnzip(className, version, srcPath) {
if (!serviceGenLib) {
return '服务生成库未加载';
}
try {
const errorMsg = Buffer.alloc(1024);
const result = serviceGenLib.XNServiceCodeUnzip(
className, className.length,
version, version.length,
srcPath, srcPath.length,
errorMsg, errorMsg.length
);
if (result !== 0) {
return `解压服务代码失败: ${errorMsg.toString('utf8').replace(/\0/g, '')}`;
}
return '解压服务代码成功';
} catch (error) {
return `解压服务代码失败: ${error.message}`;
}
}
// 编译服务代码
function serviceCodeCompile(className, version) {
if (!serviceGenLib) {
return '服务生成库未加载';
}
try {
const errorMsg = Buffer.alloc(1024);
const result = serviceGenLib.XNServiceCodeCompile(
className, className.length,
version, version.length,
errorMsg, errorMsg.length
);
if (result !== 0) {
return `编译服务代码失败: ${errorMsg.toString('utf8').replace(/\0/g, '')}`;
}
return '编译服务代码成功';
} catch (error) {
return `编译服务代码失败: ${error.message}`;
}
}
module.exports = {
loginLib,
monitorLib,
interfaceGenLib,
modelGenLib,
serviceGenLib,
performCleanup,
stringToBuffer,
initializeMonitor,
@ -954,5 +1067,9 @@ module.exports = {
modelCodeGen,
modelCodeZip,
modelCodeUnzip,
modelCodeCompile
modelCodeCompile,
serviceCodeGen,
serviceCodeZip,
serviceCodeUnzip,
serviceCodeCompile
};