2025-04-28 12:25:20 +08:00
|
|
|
|
/**
|
|
|
|
|
* @file XNScenarioManager.cpp
|
|
|
|
|
* @author jinchao
|
|
|
|
|
* @brief 运行环境描述管理器类源文件
|
|
|
|
|
* @version 1.0
|
|
|
|
|
* @date 2024-11-07
|
|
|
|
|
*
|
|
|
|
|
* @copyright Copyright (c) 2024 XN
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
#include "XNScenarioManager.h"
|
|
|
|
|
#include "XNScenarioManager_p.h"
|
|
|
|
|
#include "XNFramework.h"
|
2025-05-20 15:39:40 +08:00
|
|
|
|
#include "XNDDSManager.h"
|
|
|
|
|
#include "XNThreadManager.h"
|
|
|
|
|
#include "XNModelManager.h"
|
|
|
|
|
#include "XNServiceManager.h"
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <streambuf>
|
|
|
|
|
#include <cerrno>
|
|
|
|
|
#include <tinyxml2.h>
|
2025-04-28 12:25:20 +08:00
|
|
|
|
|
|
|
|
|
// 默认构造函数
|
2025-05-20 15:39:40 +08:00
|
|
|
|
XNScenarioManager::XNScenarioManager() : XNBaseFrameObject(new XNScenarioManagerPrivate())
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
|
SetUniqueId(5);
|
|
|
|
|
SetObjectName("XNScenarioManager");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XNScenarioManager::~XNScenarioManager()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
|
XNScenarioManager::XNScenarioManager(PrivateType *p) : XNBaseFrameObject(p)
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取运行环境名称
|
2025-05-20 15:39:40 +08:00
|
|
|
|
const std::string &XNScenarioManager::GetSimName()
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
|
return d->_ScenarioName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置运行环境名称
|
2025-05-20 15:39:40 +08:00
|
|
|
|
void XNScenarioManager::SetSimName(const std::string &simName)
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
|
T_D();
|
2025-04-28 12:25:20 +08:00
|
|
|
|
d->_ScenarioName = simName;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
|
// 初始化
|
|
|
|
|
bool XNScenarioManager::Initialize()
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
|
T_D();
|
|
|
|
|
LOG_INFO("XNScenarioManager Initialize Success!");
|
|
|
|
|
d->_status = XNFrameObjectStatus::Initialized;
|
|
|
|
|
return true;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
|
bool XNScenarioManager::PrepareForExecute()
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
|
T_D();
|
|
|
|
|
d->_status = XNFrameObjectStatus::Ready;
|
|
|
|
|
LOG_INFO("XNScenarioManager is prepared!");
|
|
|
|
|
return true;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-27 15:16:11 +08:00
|
|
|
|
// 运行环境配置文件解析
|
|
|
|
|
bool XNScenarioManager::AnalysisScenarioXml(const std::string &XmlPath, uint32_t initialType)
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-27 15:16:11 +08:00
|
|
|
|
T_D();
|
|
|
|
|
if (initialType == 0) {
|
|
|
|
|
return ParseScenarioXml(XmlPath);
|
|
|
|
|
} else {
|
|
|
|
|
return ParseConfig(XmlPath);
|
2025-05-20 15:39:40 +08:00
|
|
|
|
}
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-27 15:16:11 +08:00
|
|
|
|
// 解析运行环境描述文件
|
|
|
|
|
bool XNScenarioManager::ParseScenarioXml(const std::string &XmlPath)
|
2025-04-28 12:25:20 +08:00
|
|
|
|
{
|
2025-05-20 15:39:40 +08:00
|
|
|
|
T_D();
|
|
|
|
|
std::ifstream file(XmlPath);
|
|
|
|
|
if (!file.is_open()) {
|
|
|
|
|
LOG_ERROR("0x2100 打开运行环境描述文件: %1出错,错误信息: %2", XmlPath, strerror(errno));
|
|
|
|
|
return false;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
tinyxml2::XMLDocument doc;
|
|
|
|
|
if (doc.LoadFile(XmlPath.c_str()) != tinyxml2::XML_SUCCESS) {
|
2025-04-28 12:25:20 +08:00
|
|
|
|
LOG_ERROR("0x2100 解析XML文件: %1 失败", XmlPath);
|
|
|
|
|
file.close();
|
2025-05-20 15:39:40 +08:00
|
|
|
|
return false;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
tinyxml2::XMLElement *root = doc.FirstChildElement("Scenario");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 读取环境信息
|
2025-05-20 15:39:40 +08:00
|
|
|
|
tinyxml2::XMLElement *envInfo = root->FirstChildElement("Environment");
|
|
|
|
|
std::string OSName = envInfo->Attribute("OSName");
|
|
|
|
|
std::string version = envInfo->Attribute("Version");
|
|
|
|
|
std::string kernel = envInfo->Attribute("RTXVersion");
|
2025-05-27 15:16:11 +08:00
|
|
|
|
std::string planeName = envInfo->Attribute("PlaneName");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 设置工作目录
|
2025-05-20 15:39:40 +08:00
|
|
|
|
std::string rootPath = envInfo->Attribute("WorkPath");
|
|
|
|
|
GetFramework()->SetWorkPath(rootPath);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 设置模型库目录
|
2025-05-20 15:39:40 +08:00
|
|
|
|
std::string modelPath = rootPath + envInfo->Attribute("ModelsPath");
|
|
|
|
|
GetFramework()->SetModelPath(modelPath);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 设置服务库目录
|
2025-05-20 15:39:40 +08:00
|
|
|
|
std::string servicePath = rootPath + envInfo->Attribute("ServicesPath");
|
|
|
|
|
GetFramework()->SetServicePath(servicePath);
|
|
|
|
|
// 设置域ID
|
|
|
|
|
uint32_t domainID = std::stoul(envInfo->Attribute("DomainID"));
|
|
|
|
|
GetFramework()->GetDDSManager()->SetDomainID(domainID);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 读取CPU亲和性
|
2025-05-20 15:39:40 +08:00
|
|
|
|
std::string cpuAff = envInfo->Attribute("CPUAffinity");
|
2025-05-27 15:16:11 +08:00
|
|
|
|
std::vector<std::string> cpuAffList = XNSim::split(cpuAff, ",");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
|
|
|
|
|
//读取服务列表
|
2025-05-20 15:39:40 +08:00
|
|
|
|
tinyxml2::XMLElement *serviceList = root->FirstChildElement("ServicesList");
|
|
|
|
|
if (serviceList) {
|
|
|
|
|
tinyxml2::XMLElement *service = serviceList->FirstChildElement("Service");
|
|
|
|
|
while (service) {
|
|
|
|
|
std::string serviceName = service->Attribute("Name");
|
|
|
|
|
std::string libName = service->Attribute("ClassName");
|
2025-05-27 15:16:11 +08:00
|
|
|
|
std::string serviceVersion = service->Attribute("Version");
|
|
|
|
|
libName = XNSim::getFileNameWithoutExt(libName);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
std::string dynamicLibName = servicePath + "/lib" + libName + ".so." + serviceVersion;
|
2025-05-20 15:39:40 +08:00
|
|
|
|
// 加载动态库
|
2025-05-27 15:16:11 +08:00
|
|
|
|
GetFramework()->GetServiceManager()->LoadService(dynamicLibName, libName,
|
|
|
|
|
serviceVersion, 0);
|
2025-05-20 15:39:40 +08:00
|
|
|
|
service = service->NextSiblingElement("Service");
|
|
|
|
|
}
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 读取模型分组
|
2025-05-20 15:39:40 +08:00
|
|
|
|
tinyxml2::XMLElement *modelGroup = root->FirstChildElement("ModelGroup");
|
|
|
|
|
while (modelGroup) {
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 读取模型分组名称
|
2025-05-20 15:39:40 +08:00
|
|
|
|
std::string modelGroupName = modelGroup->Attribute("Name");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 读取模型分组频率
|
2025-05-20 15:39:40 +08:00
|
|
|
|
double modelGroupFreq = std::stod(modelGroup->Attribute("Freq"));
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 读取模型分组优先级
|
2025-05-27 15:16:11 +08:00
|
|
|
|
int modelGroupPriority = XNSim::safe_stoi(modelGroup->Attribute("Priority"));
|
2025-04-28 12:25:20 +08:00
|
|
|
|
if (modelGroupPriority > 99 || modelGroupPriority < 0) {
|
2025-05-20 15:39:40 +08:00
|
|
|
|
LOG_ERROR("0x2100 模型分组优先级设置错误,优先级值:%d", modelGroupPriority);
|
|
|
|
|
return false;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
// 读取模型分组CPU亲和性
|
2025-05-20 15:39:40 +08:00
|
|
|
|
std::string modelGroupCPUAff = modelGroup->Attribute("CPUAff");
|
2025-05-27 15:16:11 +08:00
|
|
|
|
std::vector<std::string> modelGroupCPUAffList = XNSim::split(modelGroupCPUAff, ",");
|
2025-05-20 15:39:40 +08:00
|
|
|
|
|
|
|
|
|
// 验证CPU亲和性
|
|
|
|
|
for (const auto &cpu : modelGroupCPUAffList) {
|
|
|
|
|
if (std::find(cpuAffList.begin(), cpuAffList.end(), cpu) == cpuAffList.end()) {
|
|
|
|
|
LOG_ERROR("0x2100 模型分组CPU亲和性设置错误,CPU亲和性值:%s,进程CPU亲和性值:%s",
|
|
|
|
|
cpu.c_str(), cpuAff.c_str());
|
|
|
|
|
return false;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
|
2025-04-28 12:25:20 +08:00
|
|
|
|
int ThreadCpuAffinity = 0;
|
2025-05-20 15:39:40 +08:00
|
|
|
|
for (const auto &cpu : modelGroupCPUAffList) {
|
|
|
|
|
auto it = std::find(cpuAffList.begin(), cpuAffList.end(), cpu);
|
|
|
|
|
if (it != cpuAffList.end()) {
|
|
|
|
|
ThreadCpuAffinity |= 1 << std::distance(cpuAffList.begin(), it);
|
|
|
|
|
}
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
|
// 添加线程池
|
|
|
|
|
uint32_t threadID = GetFramework()->GetThreadManager()->AddThreadPool(
|
|
|
|
|
modelGroupName, modelGroupFreq, modelGroupPriority, ThreadCpuAffinity);
|
2025-04-28 12:25:20 +08:00
|
|
|
|
|
|
|
|
|
// 读取模型列表
|
2025-05-20 15:39:40 +08:00
|
|
|
|
tinyxml2::XMLElement *model = modelGroup->FirstChildElement("Model");
|
|
|
|
|
while (model) {
|
|
|
|
|
std::string modelName = model->Attribute("Name");
|
|
|
|
|
std::string libName = model->Attribute("ClassName");
|
2025-05-27 15:16:11 +08:00
|
|
|
|
std::string modelVersion = model->Attribute("Version");
|
|
|
|
|
libName = XNSim::getFileNameWithoutExt(libName);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
std::string dynamicLibName = modelPath + "/lib" + libName + ".so." + modelVersion;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
// 加载动态库
|
2025-05-27 15:16:11 +08:00
|
|
|
|
GetFramework()->GetModelManager()->LoadModel(dynamicLibName, libName, modelVersion,
|
|
|
|
|
planeName, 0, threadID);
|
2025-05-20 15:39:40 +08:00
|
|
|
|
model = model->NextSiblingElement("Model");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
|
|
|
|
|
modelGroup = modelGroup->NextSiblingElement("ModelGroup");
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-20 15:39:40 +08:00
|
|
|
|
return true;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
|
|
|
|
|
|
// 解析构型配置文件
|
|
|
|
|
bool XNScenarioManager::ParseConfig(const std::string &ConfigID)
|
|
|
|
|
{
|
|
|
|
|
T_D();
|
|
|
|
|
// 获取数据库路径
|
2025-06-04 14:00:46 +08:00
|
|
|
|
std::string XNCorePath = std::getenv("XNCore");
|
|
|
|
|
if (XNCorePath.empty()) {
|
2025-05-27 15:16:11 +08:00
|
|
|
|
LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-06-04 14:00:46 +08:00
|
|
|
|
std::string dbPath = XNCorePath + "/database/XNSim.db";
|
2025-05-27 15:16:11 +08:00
|
|
|
|
|
|
|
|
|
// 打开数据库
|
|
|
|
|
sqlite3 *db;
|
|
|
|
|
if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1016 打开数据库失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 准备SQL语句
|
|
|
|
|
std::string sql = "SELECT * FROM Configuration WHERE ConfID = ?";
|
|
|
|
|
sqlite3_stmt *stmt;
|
|
|
|
|
if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1017 准备SQL语句失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绑定参数
|
|
|
|
|
int configIdInt = XNSim::safe_stoi(ConfigID);
|
|
|
|
|
if (sqlite3_bind_int(stmt, 1, configIdInt) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行查询
|
|
|
|
|
if (sqlite3_step(stmt) != SQLITE_ROW) {
|
|
|
|
|
LOG_ERROR("0x1019 未找到配置ID为%1的记录", ConfigID);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
std::string planeName = XNSim::getStringFromSqlite3(stmt, 1);
|
|
|
|
|
std::string osName = XNSim::getStringFromSqlite3(stmt, 3);
|
|
|
|
|
std::string version = XNSim::getStringFromSqlite3(stmt, 4);
|
|
|
|
|
std::string kernel = XNSim::getStringFromSqlite3(stmt, 5);
|
|
|
|
|
std::string rootPath = XNSim::getStringFromSqlite3(stmt, 7);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
if (rootPath.empty()) {
|
|
|
|
|
LOG_WARNING("0x1020 未设置工作目录,使用默认工作目录: %1", XNCorePath);
|
|
|
|
|
rootPath = XNCorePath;
|
|
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
|
GetFramework()->SetWorkPath(rootPath);
|
|
|
|
|
// 设置模型库目录
|
|
|
|
|
std::string modelPath = rootPath + XNSim::getStringFromSqlite3(stmt, 8);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
if (modelPath.empty()) {
|
|
|
|
|
LOG_WARNING("0x1020 未设置模型库目录,使用默认模型库目录: %1/Models", XNCorePath);
|
|
|
|
|
modelPath = XNCorePath + "/Models";
|
|
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
|
GetFramework()->SetModelPath(modelPath);
|
|
|
|
|
// 设置服务库目录
|
|
|
|
|
std::string servicePath = rootPath + XNSim::getStringFromSqlite3(stmt, 9);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
if (servicePath.empty()) {
|
|
|
|
|
LOG_WARNING("0x1020 未设置服务库目录,使用默认服务库目录: %1/Services", XNCorePath);
|
|
|
|
|
servicePath = XNCorePath + "/Services";
|
|
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
|
GetFramework()->SetServicePath(servicePath);
|
|
|
|
|
// 设置域ID
|
|
|
|
|
uint32_t domainID = std::stoul(XNSim::getStringFromSqlite3(stmt, 10));
|
2025-06-04 14:00:46 +08:00
|
|
|
|
if (domainID == 0 || domainID > 225) {
|
|
|
|
|
LOG_WARNING("0x1020 域ID设置错误,使用默认域ID: 10");
|
|
|
|
|
domainID = 10;
|
|
|
|
|
}
|
2025-05-27 15:16:11 +08:00
|
|
|
|
GetFramework()->GetDDSManager()->SetDomainID(domainID);
|
|
|
|
|
// 读取CPU亲和性
|
|
|
|
|
std::string cpuAff = XNSim::getStringFromSqlite3(stmt, 6);
|
|
|
|
|
std::vector<std::string> cpuAffList = XNSim::split(cpuAff, ",");
|
|
|
|
|
|
|
|
|
|
//查询LoadServices表读取服务信息
|
|
|
|
|
std::string servicesSql = "SELECT * FROM LoadServices WHERE ConfID = ?";
|
|
|
|
|
sqlite3_stmt *servicesStmt;
|
|
|
|
|
if (sqlite3_prepare_v2(db, servicesSql.c_str(), -1, &servicesStmt, nullptr) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1020 准备LoadServices查询语句失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 绑定参数
|
|
|
|
|
if (sqlite3_bind_int(servicesStmt, 1, configIdInt) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1021 绑定LoadServices参数失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行查询并处理结果
|
|
|
|
|
while (sqlite3_step(servicesStmt) == SQLITE_ROW) {
|
|
|
|
|
// 获取服务信息
|
|
|
|
|
std::string ClassName = XNSim::getStringFromSqlite3(servicesStmt, 1);
|
|
|
|
|
std::string ServiceVersion = XNSim::getStringFromSqlite3(servicesStmt, 2);
|
|
|
|
|
std::string ServiceName = XNSim::getStringFromSqlite3(servicesStmt, 3);
|
|
|
|
|
|
|
|
|
|
ClassName = XNSim::getFileNameWithoutExt(ClassName);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
std::string dynamicLibName = servicePath + "/lib" + ClassName + ".so." + ServiceVersion;
|
2025-05-27 15:16:11 +08:00
|
|
|
|
// 加载动态库
|
|
|
|
|
GetFramework()->GetServiceManager()->LoadService(dynamicLibName, ClassName, ServiceVersion,
|
|
|
|
|
1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查询LoadModelGroups表读取模型组信息
|
|
|
|
|
std::string modelGroupsSql = "SELECT * FROM LoadModelGroups WHERE ConfID = ?";
|
|
|
|
|
sqlite3_stmt *modelGroupsStmt;
|
|
|
|
|
if (sqlite3_prepare_v2(db, modelGroupsSql.c_str(), -1, &modelGroupsStmt, nullptr)
|
|
|
|
|
!= SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1020 准备LoadModelGroups查询语句失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绑定参数
|
|
|
|
|
if (sqlite3_bind_int(modelGroupsStmt, 1, configIdInt) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1021 绑定LoadModelGroups参数失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(modelGroupsStmt);
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行查询并处理结果
|
|
|
|
|
while (sqlite3_step(modelGroupsStmt) == SQLITE_ROW) {
|
|
|
|
|
// 获取模型组信息
|
|
|
|
|
std::string GroupID = XNSim::getStringFromSqlite3(modelGroupsStmt, 1);
|
|
|
|
|
std::string GroupName = XNSim::getStringFromSqlite3(modelGroupsStmt, 2);
|
|
|
|
|
double GroupFreq = std::stod(XNSim::getStringFromSqlite3(modelGroupsStmt, 3));
|
|
|
|
|
uint32_t GroupPriority = XNSim::safe_stoi(XNSim::getStringFromSqlite3(modelGroupsStmt, 4));
|
|
|
|
|
std::string GroupCPUAff = XNSim::getStringFromSqlite3(modelGroupsStmt, 5);
|
|
|
|
|
std::vector<std::string> GroupCPUAffList = XNSim::split(GroupCPUAff, ",");
|
|
|
|
|
|
|
|
|
|
// 验证CPU亲和性
|
|
|
|
|
for (const auto &cpu : GroupCPUAffList) {
|
|
|
|
|
if (std::find(cpuAffList.begin(), cpuAffList.end(), cpu) == cpuAffList.end()) {
|
|
|
|
|
LOG_ERROR("0x2100 模型分组CPU亲和性设置错误,CPU亲和性值:%s,进程CPU亲和性值:%s",
|
|
|
|
|
cpu.c_str(), cpuAff.c_str());
|
|
|
|
|
sqlite3_finalize(modelGroupsStmt);
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ThreadCpuAffinity = 0;
|
|
|
|
|
for (const auto &cpu : GroupCPUAffList) {
|
|
|
|
|
auto it = std::find(cpuAffList.begin(), cpuAffList.end(), cpu);
|
|
|
|
|
if (it != cpuAffList.end()) {
|
|
|
|
|
ThreadCpuAffinity |= 1 << std::distance(cpuAffList.begin(), it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LOG_INFO("0x1021 添加线程池: %1", GroupName);
|
|
|
|
|
// 添加线程池
|
|
|
|
|
uint32_t threadID = GetFramework()->GetThreadManager()->AddThreadPool(
|
|
|
|
|
GroupName, GroupFreq, GroupPriority, ThreadCpuAffinity);
|
|
|
|
|
|
|
|
|
|
// 准备查询LoadModels表的SQL语句
|
|
|
|
|
std::string modelsSql = "SELECT * FROM LoadModels WHERE GroupID = ?";
|
|
|
|
|
sqlite3_stmt *modelsStmt = nullptr;
|
|
|
|
|
if (sqlite3_prepare_v2(db, modelsSql.c_str(), -1, &modelsStmt, nullptr) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1022 准备LoadModels查询语句失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(modelGroupsStmt);
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绑定参数
|
|
|
|
|
if (sqlite3_bind_int(modelsStmt, 1, XNSim::safe_stoi(GroupID)) != SQLITE_OK) {
|
|
|
|
|
LOG_ERROR("0x1023 绑定LoadModels参数失败: %1", sqlite3_errmsg(db));
|
|
|
|
|
sqlite3_finalize(modelsStmt);
|
|
|
|
|
sqlite3_finalize(modelGroupsStmt);
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 执行查询并处理结果
|
|
|
|
|
while (sqlite3_step(modelsStmt) == SQLITE_ROW) {
|
|
|
|
|
// 获取模型信息
|
|
|
|
|
std::string ClassName = XNSim::getStringFromSqlite3(modelsStmt, 1);
|
|
|
|
|
std::string ModelVersion = XNSim::getStringFromSqlite3(modelsStmt, 2);
|
|
|
|
|
std::string ModelName = XNSim::getStringFromSqlite3(modelsStmt, 3);
|
|
|
|
|
|
|
|
|
|
ClassName = XNSim::getFileNameWithoutExt(ClassName);
|
2025-06-04 14:00:46 +08:00
|
|
|
|
std::string dynamicLibName = modelPath + "/lib" + ClassName + ".so." + ModelVersion;
|
2025-05-27 15:16:11 +08:00
|
|
|
|
// 加载动态库
|
|
|
|
|
LOG_INFO("0x1021 加载模型: %1", dynamicLibName);
|
|
|
|
|
GetFramework()->GetModelManager()->LoadModel(dynamicLibName, ClassName, ModelVersion,
|
|
|
|
|
planeName, 1, threadID);
|
|
|
|
|
}
|
|
|
|
|
// 清理资源
|
|
|
|
|
sqlite3_finalize(modelsStmt);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 清理资源
|
|
|
|
|
sqlite3_finalize(modelGroupsStmt);
|
|
|
|
|
sqlite3_finalize(servicesStmt);
|
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
|
sqlite3_close(db);
|
|
|
|
|
return true;
|
|
|
|
|
}
|