/** * @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" #include "XNDDSManager.h" #include "XNThreadManager.h" #include "XNModelManager.h" #include "XNServiceManager.h" #include #include #include #include // 默认构造函数 XNScenarioManager::XNScenarioManager() : XNBaseFrameObject(new XNScenarioManagerPrivate()) { SetUniqueId(5); SetObjectName("XNScenarioManager"); } XNScenarioManager::~XNScenarioManager() { } XNScenarioManager::XNScenarioManager(PrivateType *p) : XNBaseFrameObject(p) { } // 获取运行环境名称 const std::string &XNScenarioManager::GetSimName() { T_D(); return d->_ScenarioName; } // 设置运行环境名称 void XNScenarioManager::SetSimName(const std::string &simName) { T_D(); d->_ScenarioName = simName; } // 初始化 bool XNScenarioManager::Initialize() { T_D(); LOG_INFO("XNScenarioManager Initialize Success!"); d->_status = XNFrameObjectStatus::Initialized; return true; } bool XNScenarioManager::PrepareForExecute() { T_D(); d->_status = XNFrameObjectStatus::Ready; LOG_INFO("XNScenarioManager is prepared!"); return true; } // 辅助函数:分割字符串 std::vector split(const std::string &str, const std::string &delim) { std::vector tokens; size_t prev = 0, pos = 0; do { pos = str.find(delim, prev); if (pos == std::string::npos) pos = str.length(); std::string token = str.substr(prev, pos - prev); if (!token.empty()) tokens.push_back(token); prev = pos + delim.length(); } while (pos < str.length() && prev < str.length()); return tokens; } // 辅助函数:获取文件名(不含扩展名) std::string getFileNameWithoutExt(const std::string &path) { size_t lastDot = path.find_last_of('.'); if (lastDot != std::string::npos) { return path.substr(0, lastDot); } return path; } // 运行环境配置文件解析 bool XNScenarioManager::AnalysisScenarioXml(const std::string &XmlPath, uint32_t initialType) { T_D(); std::ifstream file(XmlPath); if (!file.is_open()) { LOG_ERROR("0x2100 打开运行环境描述文件: %1出错,错误信息: %2", XmlPath, strerror(errno)); return false; } tinyxml2::XMLDocument doc; if (doc.LoadFile(XmlPath.c_str()) != tinyxml2::XML_SUCCESS) { LOG_ERROR("0x2100 解析XML文件: %1 失败", XmlPath); file.close(); return false; } tinyxml2::XMLElement *root = doc.FirstChildElement("Scenario"); // 读取环境信息 tinyxml2::XMLElement *envInfo = root->FirstChildElement("Environment"); std::string OSName = envInfo->Attribute("OSName"); std::string version = envInfo->Attribute("Version"); std::string kernel = envInfo->Attribute("RTXVersion"); // 设置工作目录 std::string rootPath = envInfo->Attribute("WorkPath"); GetFramework()->SetWorkPath(rootPath); // 设置模型库目录 std::string modelPath = rootPath + envInfo->Attribute("ModelsPath"); GetFramework()->SetModelPath(modelPath); // 设置服务库目录 std::string servicePath = rootPath + envInfo->Attribute("ServicesPath"); GetFramework()->SetServicePath(servicePath); // 设置域ID uint32_t domainID = std::stoul(envInfo->Attribute("DomainID")); GetFramework()->GetDDSManager()->SetDomainID(domainID); // 读取CPU亲和性 std::string cpuAff = envInfo->Attribute("CPUAffinity"); std::vector cpuAffList = split(cpuAff, ","); //读取服务列表 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"); } } // 读取模型分组 tinyxml2::XMLElement *modelGroup = root->FirstChildElement("ModelGroup"); while (modelGroup) { // 读取模型分组名称 std::string modelGroupName = modelGroup->Attribute("Name"); // 读取模型分组频率 double modelGroupFreq = std::stod(modelGroup->Attribute("Freq")); // 读取模型分组优先级 int modelGroupPriority = std::stoi(modelGroup->Attribute("Priority")); if (modelGroupPriority > 99 || modelGroupPriority < 0) { LOG_ERROR("0x2100 模型分组优先级设置错误,优先级值:%d", modelGroupPriority); return false; } // 读取模型分组CPU亲和性 std::string modelGroupCPUAff = modelGroup->Attribute("CPUAff"); std::vector 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; } } int ThreadCpuAffinity = 0; 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); } } // 添加线程池 uint32_t threadID = GetFramework()->GetThreadManager()->AddThreadPool( modelGroupName, modelGroupFreq, modelGroupPriority, ThreadCpuAffinity); // 读取模型列表 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"; // 加载动态库 GetFramework()->GetModelManager()->LoadModel(dynamicLibName, libName, 0, threadID); model = model->NextSiblingElement("Model"); } modelGroup = modelGroup->NextSiblingElement("ModelGroup"); } return true; }