XNSim/XNCore/XNScenarioManager.cpp

203 lines
6.2 KiB
C++
Raw Permalink Normal View History

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-20 15:39:40 +08:00
// 辅助函数:分割字符串
std::vector<std::string> split(const std::string &str, const std::string &delim)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
std::vector<std::string> tokens;
size_t prev = 0, pos = 0;
do {
pos = str.find(delim, prev);
if (pos == std::string::npos)
pos = str.length();
std::string token = str.substr(prev, pos - prev);
if (!token.empty())
tokens.push_back(token);
prev = pos + delim.length();
} while (pos < str.length() && prev < str.length());
return tokens;
2025-04-28 12:25:20 +08:00
}
2025-05-20 15:39:40 +08:00
// 辅助函数:获取文件名(不含扩展名)
std::string getFileNameWithoutExt(const std::string &path)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
size_t lastDot = path.find_last_of('.');
if (lastDot != std::string::npos) {
return path.substr(0, lastDot);
}
return path;
2025-04-28 12:25:20 +08:00
}
// 运行环境配置文件解析
2025-05-20 15:45:00 +08:00
bool XNScenarioManager::AnalysisScenarioXml(const std::string &XmlPath, uint32_t initialType)
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-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");
std::vector<std::string> cpuAffList = 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");
libName = getFileNameWithoutExt(libName);
std::string dynamicLibName = servicePath + "lib" + libName + ".so";
// 加载动态库
GetFramework()->GetServiceManager()->LoadService(dynamicLibName, libName, 0);
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-20 15:39:40 +08:00
int modelGroupPriority = std::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");
std::vector<std::string> modelGroupCPUAffList = split(modelGroupCPUAff, ",");
// 验证CPU亲和性
for (const auto &cpu : modelGroupCPUAffList) {
if (std::find(cpuAffList.begin(), cpuAffList.end(), cpu) == cpuAffList.end()) {
LOG_ERROR("0x2100 模型分组CPU亲和性设置错误CPU亲和性值%s,进程CPU亲和性值%s",
cpu.c_str(), cpuAff.c_str());
return false;
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");
libName = getFileNameWithoutExt(libName);
std::string dynamicLibName = modelPath + "lib" + libName + ".so";
2025-04-28 12:25:20 +08:00
// 加载动态库
2025-05-20 15:39:40 +08:00
GetFramework()->GetModelManager()->LoadModel(dynamicLibName, libName, 0, threadID);
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
}