613 lines
18 KiB
C++
Executable File
613 lines
18 KiB
C++
Executable File
/**
|
|
* @file XNEngine.cpp
|
|
* @author jinchao
|
|
* @brief 引擎类
|
|
* @version 1.0
|
|
* @date 2025-02-14
|
|
*
|
|
* @copyright Copyright (c) 2025 COMAC
|
|
*
|
|
*/
|
|
#include "XNEngine.h"
|
|
#include "../XNCore/XNTimeManager.h"
|
|
#include "../XNCore/XNThreadManager.h"
|
|
#include "../XNCore/XNDDSManager.h"
|
|
#include "../XNCore/XNEventManager.h"
|
|
#include "../XNCore/XNServiceManager.h"
|
|
#include "../XNCore/XNModelManager.h"
|
|
#include "../XNCore/XNScenarioManager.h"
|
|
#include <sqlite3.h>
|
|
|
|
// 引擎类构造函数
|
|
XNEngine::XNEngine()
|
|
{
|
|
// 创建框架对象
|
|
framework = std::make_shared<XNFramework>();
|
|
// 引擎状态写入器
|
|
engineStatusWriter = nullptr;
|
|
// 测试模式
|
|
isTestMode = false;
|
|
// 初始化类型
|
|
initializeType = 0;
|
|
}
|
|
|
|
// 引擎类析构函数
|
|
XNEngine::~XNEngine()
|
|
{
|
|
}
|
|
|
|
// 仿真控制监听器
|
|
void XNEngine::SimControlListener(const XNSim::XNSimControl::XNRuntimeControl &cmd)
|
|
{
|
|
if (!framework) {
|
|
return;
|
|
}
|
|
if (cmd.XNSimCmd() == 1) {
|
|
// 如果命令是暂停
|
|
framework->SimControl(0, SimControlCmd::Suspend);
|
|
} else if (cmd.XNSimCmd() == 2) {
|
|
// 如果命令是继续
|
|
framework->SimControl(0, SimControlCmd::Continue);
|
|
} else if (cmd.XNSimCmd() == 3) {
|
|
// 如果命令是终止
|
|
framework->SimControl(0, SimControlCmd::Abort);
|
|
//TODO 后续收到结束指令后再结束,还需要最后发一次终止状态
|
|
engineRunning = false;
|
|
}
|
|
}
|
|
|
|
// 解析配置文件
|
|
bool XNEngine::ParseConfig(const std::string &XmlPath)
|
|
{
|
|
size_t index = XmlPath.find_last_of('.');
|
|
if (index != std::string::npos) {
|
|
std::string suffix = XmlPath.substr(index);
|
|
if (suffix != ".xml" && suffix != ".sce") {
|
|
std::cerr << "0x1005 配置文件不是 .xml 或 .sce 文件, 引擎将退出!" << std::endl;
|
|
return false;
|
|
}
|
|
} else {
|
|
std::cerr << "0x1006 配置文件没有 .xml 或 .sce 的后缀名, 引擎将退出!" << std::endl;
|
|
return false;
|
|
}
|
|
// 打开配置文件
|
|
std::ifstream file(XmlPath);
|
|
if (!file.is_open()) {
|
|
std::cerr << "0x1007 打开配置文件失败, 引擎将退出!" << std::endl;
|
|
return false;
|
|
}
|
|
// 解析配置文件
|
|
tinyxml2::XMLDocument doc;
|
|
if (doc.LoadFile(XmlPath.c_str()) != tinyxml2::XML_SUCCESS) {
|
|
std::cerr << "0x1008 解析配置文件失败, 引擎将退出!" << std::endl;
|
|
return false;
|
|
}
|
|
// 获取根元素
|
|
tinyxml2::XMLElement *root = doc.FirstChildElement("Scenario");
|
|
if (!root) {
|
|
std::cerr << "0x1009 配置文件中未找到 Scenario 根元素, 引擎将退出!" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// 顺便读取一下CPU亲和性
|
|
int cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
|
std::cout << "当前CPU核心数-> " << cpus << std::endl;
|
|
|
|
// 设置CPU亲和性
|
|
cpu_set_t mask;
|
|
CPU_ZERO(&mask);
|
|
CPUAffinity = 0;
|
|
|
|
//获取CPU亲和性配置
|
|
tinyxml2::XMLElement *envNode = root->FirstChildElement("Environment");
|
|
if (envNode) {
|
|
const char *cpuAffinityStr = envNode->Attribute("CPUAffinity");
|
|
if (cpuAffinityStr) {
|
|
std::string affinityStr(cpuAffinityStr);
|
|
std::istringstream iss(affinityStr);
|
|
std::string cpuIndex;
|
|
while (std::getline(iss, cpuIndex, ',')) {
|
|
try {
|
|
int index = std::stoi(cpuIndex);
|
|
if (index >= 0 && index < cpus) {
|
|
CPUAffinity |= (1 << index);
|
|
CPU_SET(index, &mask);
|
|
}
|
|
} catch (const std::exception &e) {
|
|
std::cerr << "0x1010 无效的CPU亲和性值: " << cpuIndex << std::endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sched_setaffinity(0, sizeof(mask), &mask) == -1) {
|
|
std::cerr << "0x1011 设置引擎CPU亲和性失败-> " << strerror(errno) << std::endl;
|
|
return false;
|
|
}
|
|
std::cout << "成功设置引擎CPU亲和性-> " << CPUAffinity << std::endl;
|
|
|
|
// 锁定内存
|
|
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
|
|
std::cerr << "0x1012 锁定引擎内存失败-> " << strerror(errno) << std::endl;
|
|
return false;
|
|
}
|
|
std::cout << "成功锁定引擎内存!" << std::endl;
|
|
|
|
// 获取配置文件中的日志元素
|
|
bool isDebug = false;
|
|
bool isInfo = false;
|
|
bool isWarn = false;
|
|
bool isError = false;
|
|
// 获取配置文件中的控制台输出元素
|
|
tinyxml2::XMLElement *consoleOutputNode = root->FirstChildElement("ConsoleOutput");
|
|
if (!consoleOutputNode) {
|
|
std::cout << "0x1013 配置文件中未找到 ConsoleOutput 元素, 控制台将输出所有日志!"
|
|
<< std::endl;
|
|
} else {
|
|
// 获取配置文件中的调试日志输出元素
|
|
const char *debugConsoleOutput = consoleOutputNode->Attribute("Debug");
|
|
if (debugConsoleOutput
|
|
&& (strcmp(debugConsoleOutput, "true") == 0 || strcmp(debugConsoleOutput, "1") == 0
|
|
|| strcmp(debugConsoleOutput, "True") == 0
|
|
|| strcmp(debugConsoleOutput, "TRUE") == 0)) {
|
|
isDebug = true;
|
|
} else {
|
|
isDebug = false;
|
|
}
|
|
|
|
// 获取配置文件中的信息日志输出元素
|
|
const char *infoConsoleOutput = consoleOutputNode->Attribute("Info");
|
|
if (infoConsoleOutput
|
|
&& (strcmp(infoConsoleOutput, "true") == 0 || strcmp(infoConsoleOutput, "1") == 0
|
|
|| strcmp(infoConsoleOutput, "True") == 0
|
|
|| strcmp(infoConsoleOutput, "TRUE") == 0)) {
|
|
isInfo = true;
|
|
} else {
|
|
isInfo = false;
|
|
}
|
|
|
|
// 获取配置文件中的警告日志输出元素
|
|
const char *warningConsoleOutput = consoleOutputNode->Attribute("Warning");
|
|
if (warningConsoleOutput
|
|
&& (strcmp(warningConsoleOutput, "true") == 0 || strcmp(warningConsoleOutput, "1") == 0
|
|
|| strcmp(warningConsoleOutput, "True") == 0
|
|
|| strcmp(warningConsoleOutput, "TRUE") == 0)) {
|
|
isWarn = true;
|
|
} else {
|
|
isWarn = false;
|
|
}
|
|
|
|
// 获取配置文件中的错误日志输出元素
|
|
const char *errorConsoleOutput = consoleOutputNode->Attribute("Error");
|
|
if (errorConsoleOutput
|
|
&& (strcmp(errorConsoleOutput, "true") == 0 || strcmp(errorConsoleOutput, "1") == 0
|
|
|| strcmp(errorConsoleOutput, "True") == 0
|
|
|| strcmp(errorConsoleOutput, "TRUE") == 0)) {
|
|
isError = true;
|
|
} else {
|
|
isError = false;
|
|
}
|
|
}
|
|
// 设置控制台输出
|
|
SetConsoleOutput(isDebug, isInfo, isWarn, isError);
|
|
|
|
tinyxml2::XMLElement *logNode = root->FirstChildElement("Log");
|
|
if (!logNode) {
|
|
std::cout << "0x1014 配置文件中未找到 Log 元素, 日志文件将记录所有日志!" << std::endl;
|
|
} else {
|
|
// 获取配置文件中的调试日志输出元素
|
|
const char *debugLog = logNode->Attribute("Debug");
|
|
if (debugLog
|
|
&& (strcmp(debugLog, "true") == 0 || strcmp(debugLog, "1") == 0
|
|
|| strcmp(debugLog, "True") == 0 || strcmp(debugLog, "TRUE") == 0)) {
|
|
isDebug = true;
|
|
} else {
|
|
isDebug = false;
|
|
}
|
|
|
|
// 获取配置文件中的信息日志输出元素
|
|
const char *infoLog = logNode->Attribute("Info");
|
|
if (infoLog
|
|
&& (strcmp(infoLog, "true") == 0 || strcmp(infoLog, "1") == 0
|
|
|| strcmp(infoLog, "True") == 0 || strcmp(infoLog, "TRUE") == 0)) {
|
|
isInfo = true;
|
|
} else {
|
|
isInfo = false;
|
|
}
|
|
|
|
// 获取配置文件中的警告日志输出元素
|
|
const char *warningLog = logNode->Attribute("Warning");
|
|
if (warningLog
|
|
&& (strcmp(warningLog, "true") == 0 || strcmp(warningLog, "1") == 0
|
|
|| strcmp(warningLog, "True") == 0 || strcmp(warningLog, "TRUE") == 0)) {
|
|
isWarn = true;
|
|
} else {
|
|
isWarn = false;
|
|
}
|
|
|
|
// 获取配置文件中的错误日志输出元素
|
|
const char *errorLog = logNode->Attribute("Error");
|
|
if (errorLog
|
|
&& (strcmp(errorLog, "true") == 0 || strcmp(errorLog, "1") == 0
|
|
|| strcmp(errorLog, "True") == 0 || strcmp(errorLog, "TRUE") == 0)) {
|
|
isError = true;
|
|
} else {
|
|
isError = false;
|
|
}
|
|
}
|
|
|
|
// 设置日志级别
|
|
SetLogLevel(isDebug, isInfo, isWarn, isError);
|
|
|
|
// 关闭配置文件
|
|
file.close();
|
|
// 返回成功
|
|
return true;
|
|
}
|
|
|
|
// 设置控制台输出
|
|
bool XNEngine::SetConsoleOutput(bool isDebug, bool isInfo, bool isWarn, bool isError)
|
|
{
|
|
if (isDebug) {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Debug, true);
|
|
} else {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Debug, false);
|
|
}
|
|
if (isInfo) {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Info, true);
|
|
} else {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Info, false);
|
|
}
|
|
if (isWarn) {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Warning, true);
|
|
} else {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Warning, false);
|
|
}
|
|
if (isError) {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Error, true);
|
|
} else {
|
|
XNLogger::instance().enableConsoleOutput(XNLogger::LogLevel::Error, false);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// 设置日志级别
|
|
bool XNEngine::SetLogLevel(bool isDebug, bool isInfo, bool isWarn, bool isError)
|
|
{
|
|
if (isDebug) {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Debug, true);
|
|
} else {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Debug, false);
|
|
}
|
|
if (isInfo) {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Info, true);
|
|
} else {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Info, false);
|
|
}
|
|
if (isWarn) {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Warning, true);
|
|
} else {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Warning, false);
|
|
}
|
|
if (isError) {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Error, true);
|
|
} else {
|
|
XNLogger::instance().enableFileOutput(XNLogger::LogLevel::Error, false);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// 发布引擎状态
|
|
void XNEngine::PublishEngineStatus()
|
|
{
|
|
if (!framework) {
|
|
return;
|
|
}
|
|
// 如果引擎状态写入器存在
|
|
if (engineStatusWriter) {
|
|
// 创建引擎状态对象
|
|
XNSim::XNSimStatus::XNEngineStatus engineStatus;
|
|
// 创建内核状态对象
|
|
XNSim::XNSimStatus::XNCoreStatus coreStatus;
|
|
// 设置引擎名称
|
|
engineStatus.XNEngineName("XNEngine");
|
|
// 设置引擎ID
|
|
engineStatus.XNEngineID(getpid());
|
|
// 设置引擎亲和性
|
|
engineStatus.XNEngineAff(CPUAffinity);
|
|
// 获取时间管理器
|
|
XNTimeManagerPtr timeManager = framework->GetTimeManager();
|
|
// 如果时间管理器存在
|
|
if (timeManager) {
|
|
// 设置引擎状态
|
|
engineStatus.XNEngineSt((uint32_t)timeManager->GetStatus());
|
|
// 设置内核状态
|
|
coreStatus.XNTMStatus((uint32_t)timeManager->GetFrameObjectStatus());
|
|
} else {
|
|
// 设置引擎状态
|
|
engineStatus.XNEngineSt(4);
|
|
// 设置内核状态
|
|
coreStatus.XNTMStatus(2);
|
|
}
|
|
// 获取线程管理器
|
|
XNThreadManagerPtr threadManager = framework->GetThreadManager();
|
|
// 如果线程管理器存在
|
|
if (threadManager) {
|
|
// 设置内核状态
|
|
coreStatus.XNThMStatus((uint32_t)threadManager->GetFrameObjectStatus());
|
|
// 设置引擎状态
|
|
engineStatus.XNThCnt(threadManager->GetThreadCount());
|
|
} else {
|
|
// 设置内核状态
|
|
coreStatus.XNThMStatus(2);
|
|
}
|
|
// 获取DDS管理器
|
|
XNDDSManagerPtr ddsManager = framework->GetDDSManager();
|
|
// 如果DDS管理器存在
|
|
if (ddsManager) {
|
|
// 设置内核状态
|
|
coreStatus.XNDMStatus((uint32_t)ddsManager->GetFrameObjectStatus());
|
|
} else {
|
|
// 设置内核状态
|
|
coreStatus.XNDMStatus(2);
|
|
}
|
|
// 获取事件管理器
|
|
XNEventManagerPtr eventManager = framework->GetEventManager();
|
|
// 如果事件管理器存在
|
|
if (eventManager) {
|
|
// 设置内核状态
|
|
coreStatus.XNEMStatus((uint32_t)eventManager->GetFrameObjectStatus());
|
|
} else {
|
|
// 设置内核状态
|
|
coreStatus.XNEMStatus(2);
|
|
}
|
|
// 获取服务管理器
|
|
XNServiceManagerPtr serviceManager = framework->GetServiceManager();
|
|
// 如果服务管理器存在
|
|
if (serviceManager) {
|
|
// 设置内核状态
|
|
coreStatus.XNSMStatus((uint32_t)serviceManager->GetFrameObjectStatus());
|
|
} else {
|
|
// 设置内核状态
|
|
coreStatus.XNSMStatus(2);
|
|
}
|
|
// 获取模型管理器
|
|
XNModelManagerPtr modelManager = framework->GetModelManager();
|
|
// 如果模型管理器存在
|
|
if (modelManager) {
|
|
// 设置内核状态
|
|
coreStatus.XNMMStatus((uint32_t)modelManager->GetFrameObjectStatus());
|
|
} else {
|
|
// 设置内核状态
|
|
coreStatus.XNMMStatus(2);
|
|
}
|
|
// 获取场景管理器
|
|
XNScenarioManagerPtr scenarioManager = framework->GetScenarioManager();
|
|
// 如果场景管理器存在
|
|
if (scenarioManager) {
|
|
// 设置内核状态
|
|
coreStatus.XNSDStatus((uint32_t)scenarioManager->GetFrameObjectStatus());
|
|
} else {
|
|
// 设置内核状态
|
|
coreStatus.XNSDStatus(2);
|
|
}
|
|
// 设置框架状态
|
|
coreStatus.XNFWStatus((uint32_t)frameworkStatus);
|
|
// 设置引擎状态
|
|
engineStatus.XNCoreSt(coreStatus);
|
|
// 写入引擎状态
|
|
engineStatusWriter->write(&engineStatus);
|
|
// 记录调试日志
|
|
LOG_DEBUG("引擎运行状态 DDS 写入成功!");
|
|
}
|
|
}
|
|
|
|
// 运行引擎
|
|
bool XNEngine::Run(const std::string &XmlPath, const uint32_t InitializeType)
|
|
{
|
|
if (!framework) {
|
|
return false;
|
|
}
|
|
if (InitializeType == 0) {
|
|
// 解析配置文件
|
|
bool isReady = ParseConfig(XmlPath);
|
|
// 如果解析配置文件失败
|
|
if (!isReady) {
|
|
// 返回失败
|
|
return false;
|
|
}
|
|
|
|
} else if (InitializeType == 1) {
|
|
// 解析数据库
|
|
bool isReady = ParseDataBase(XmlPath);
|
|
// 如果解析数据库失败
|
|
if (!isReady) {
|
|
// 返回失败
|
|
return false;
|
|
}
|
|
}
|
|
// 设置场景XML路径
|
|
framework->SetScenarioXml(XmlPath);
|
|
// 设置CPU亲和性
|
|
framework->SetCpuAffinity(CPUAffinity);
|
|
// 单次触发初始化信号
|
|
bool ret = framework->Initialize(InitializeType);
|
|
// 如果初始化失败
|
|
if (!ret) {
|
|
LOG_ERROR("0x1012 初始化失败, 引擎将退出!");
|
|
// 返回失败
|
|
return false;
|
|
}
|
|
// 如果初始化成功
|
|
// 设置框架状态
|
|
frameworkStatus = XNFrameObjectStatus::Initialized;
|
|
// 记录信息日志
|
|
LOG_INFO("引擎初始化成功!");
|
|
// 如果测试模式
|
|
if (isTestMode) {
|
|
// 记录信息日志
|
|
LOG_INFO("引擎测试通过!");
|
|
// 返回成功
|
|
return true;
|
|
}
|
|
ret = framework->PrepareForExecute();
|
|
// 如果准备执行失败
|
|
if (!ret) {
|
|
LOG_ERROR("0x1013 准备执行失败, 引擎将退出!");
|
|
// 返回失败
|
|
return false;
|
|
}
|
|
// 设置框架状态
|
|
frameworkStatus = XNFrameObjectStatus::Ready;
|
|
// 获取DDS管理器
|
|
XNDDSManagerPtr ddsManager = framework->GetDDSManager();
|
|
// 如果DDS管理器存在
|
|
if (ddsManager) {
|
|
// 注册仿真控制订阅者
|
|
auto func = std::bind(&XNEngine::SimControlListener, this, std::placeholders::_1);
|
|
ddsManager->RegisterSubscriber<XNSim::XNSimControl::XNRuntimeControlPubSubType>(
|
|
"XNSim::XNSimControl::XNRuntimeControl", 0, func);
|
|
// 触发仿真控制信号
|
|
framework->SimControl(0, SimControlCmd::Start);
|
|
// 注册引擎状态发布者
|
|
engineStatusWriter =
|
|
ddsManager->RegisterPublisher<XNSim::XNSimStatus::XNEngineStatusPubSubType>(
|
|
"XNSim::XNSimStatus::XNEngineStatus", 0);
|
|
// 如果引擎状态写入器存在
|
|
if (engineStatusWriter) {
|
|
// 设置引擎运行标志
|
|
engineRunning = true;
|
|
while (engineRunning) {
|
|
// 发布一次初始状态
|
|
PublishEngineStatus();
|
|
// 等待1秒
|
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
|
}
|
|
if (!engineRunning) {
|
|
// 取消注册引擎状态发布者
|
|
//ddsManager->UnregisterPublisher("XNSim::XNSimStatus::XNEngineStatus");
|
|
//ddsManager->UnregisterSubscriber("XNSim::XNSimControl::XNRuntimeControl");
|
|
}
|
|
}
|
|
} else {
|
|
// 记录错误日志
|
|
LOG_ERROR("0x1014 无法发送引擎运行状态, 引擎将退出!");
|
|
}
|
|
|
|
// 返回成功
|
|
return true;
|
|
}
|
|
|
|
// 运行引擎
|
|
bool XNEngine::ParseDataBase(const std::string &ConfigId)
|
|
{
|
|
// 获取数据库路径
|
|
std::string dbPath = std::getenv("XNCore");
|
|
if (dbPath.empty()) {
|
|
LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!");
|
|
return false;
|
|
}
|
|
dbPath += "/database/XNSim.db";
|
|
|
|
// 打开数据库
|
|
sqlite3 *db;
|
|
if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
|
|
LOG_ERROR("0x1016 打开数据库失败: %1", sqlite3_errmsg(db));
|
|
return false;
|
|
}
|
|
|
|
// 准备SQL语句
|
|
std::string sql = "SELECT * FROM Configuration WHERE ConfID = ?";
|
|
sqlite3_stmt *stmt;
|
|
if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
|
|
LOG_ERROR("0x1017 准备SQL语句失败: %1", sqlite3_errmsg(db));
|
|
sqlite3_close(db);
|
|
return false;
|
|
}
|
|
|
|
// 绑定参数
|
|
int configIdInt = std::stoi(ConfigId);
|
|
if (sqlite3_bind_int(stmt, 1, configIdInt) != SQLITE_OK) {
|
|
LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db));
|
|
sqlite3_finalize(stmt);
|
|
sqlite3_close(db);
|
|
return false;
|
|
}
|
|
|
|
// 执行查询
|
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
|
LOG_ERROR("0x1019 未找到配置ID为%1的记录", ConfigId);
|
|
sqlite3_finalize(stmt);
|
|
sqlite3_close(db);
|
|
return false;
|
|
}
|
|
|
|
int cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
|
std::cout << "当前CPU核心数-> " << cpus << std::endl;
|
|
|
|
// 设置CPU亲和性
|
|
cpu_set_t mask;
|
|
CPU_ZERO(&mask);
|
|
CPUAffinity = 0;
|
|
|
|
// 读取配置信息
|
|
std::string CPUAff = XNSim::getStringFromSqlite3(stmt, 6);
|
|
//std::string CPUAff = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 6));
|
|
|
|
std::istringstream iss(CPUAff);
|
|
std::string cpuIndex;
|
|
while (std::getline(iss, cpuIndex, ',')) {
|
|
try {
|
|
int index = std::stoi(cpuIndex);
|
|
if (index >= 0 && index < cpus) {
|
|
CPUAffinity |= (1 << index);
|
|
CPU_SET(index, &mask);
|
|
}
|
|
} catch (const std::exception &e) {
|
|
std::cerr << "0x1010 无效的CPU亲和性值: " << cpuIndex << std::endl;
|
|
}
|
|
}
|
|
|
|
if (sched_setaffinity(0, sizeof(mask), &mask) == -1) {
|
|
std::cerr << "0x1011 设置引擎CPU亲和性失败-> " << strerror(errno) << std::endl;
|
|
return false;
|
|
}
|
|
std::cout << "成功设置引擎CPU亲和性-> " << CPUAffinity << std::endl;
|
|
|
|
// 锁定内存
|
|
if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
|
|
std::cerr << "0x1012 锁定引擎内存失败-> " << strerror(errno) << std::endl;
|
|
return false;
|
|
}
|
|
std::cout << "成功锁定引擎内存!" << std::endl;
|
|
|
|
auto readBoolean = [](sqlite3_stmt *stmt, int column) -> bool {
|
|
return sqlite3_column_int(stmt, column) != 0;
|
|
};
|
|
|
|
bool isDebug = readBoolean(stmt, 11);
|
|
bool isInfo = readBoolean(stmt, 12);
|
|
bool isWarn = readBoolean(stmt, 13);
|
|
bool isError = readBoolean(stmt, 14);
|
|
|
|
SetConsoleOutput(isDebug, isInfo, isWarn, isError);
|
|
|
|
isDebug = readBoolean(stmt, 15);
|
|
isInfo = readBoolean(stmt, 16);
|
|
isWarn = readBoolean(stmt, 17);
|
|
isError = readBoolean(stmt, 18);
|
|
|
|
SetLogLevel(isDebug, isInfo, isWarn, isError);
|
|
|
|
// 清理资源
|
|
sqlite3_finalize(stmt);
|
|
sqlite3_close(db);
|
|
return true;
|
|
}
|
|
// 设置测试模式
|
|
void XNEngine::SetTestMode(bool isTestMode)
|
|
{
|
|
// 设置测试模式
|
|
this->isTestMode = isTestMode;
|
|
}
|