XNSim/XNCore/XNModelManager.cpp

179 lines
4.9 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file XNModelManager.cpp
* @author jinchao
* @brief 模型管理器类源文件
* @version 1.0
* @date 2024-11-06
*
* @copyright Copyright (c) 2024 XN
*
*/
#include "XNModelManager.h"
#include "XNModelManager_p.h"
#include "XNModelObject.h"
#include "XNFramework.h"
#include "XNThreadManager.h"
// 构造函数
XNModelManager::XNModelManager() : XNBaseFrameObject(new XNModelManagerPrivate())
{
SetUniqueId(6);
SetObjectName("XNModelManager");
T_D();
d->ModelIDAssigned.resize(10000, false);
}
// 析构函数
XNModelManager::~XNModelManager()
{
}
XNModelManager::XNModelManager(PrivateType *p) : XNBaseFrameObject(p)
{
T_D();
d->ModelIDAssigned.resize(10000, false);
}
bool XNModelManager::Initialize()
{
T_D();
LOG_INFO("D01114001:模型管理器初始化成功!");
d->_status = XNFrameObjectStatus::Initialized;
return true;
}
// 运行前最后准备
bool XNModelManager::PrepareForExecute()
{
T_D();
for (auto &model : d->ModelMap) {
model.second->PrepareForExecute();
}
d->_status = XNFrameObjectStatus::Ready;
LOG_INFO("D01114002:模型管理器准备就绪!");
return true;
}
void XNModelManager::LoadModel(const std::string &modelPath, const std::string &className,
const std::string &modelVersion, const std::string &planeName,
uint32_t initialType, uint32_t threadID)
{
T_D();
void *handle = dlopen(modelPath.c_str(), RTLD_LAZY);
if (handle) {
typedef XNModelObjectPtr (*InitialModelFunc)();
std::string initialModelName = "Initial" + className;
InitialModelFunc initialModel = (InitialModelFunc)dlsym(handle, initialModelName.c_str());
if (initialModel) {
XNModelObjectPtr model = initialModel();
if (model) {
uint32_t modelID = RegisterModel();
if (modelID == 0) {
LOG_WARNING("B01113003:分配模型ID失败, 模型ID已用完, 模型无法注册!");
dlclose(handle);
return;
}
model->SetUniqueId(modelID);
model->SetObjectName(className);
model->SetFramework(GetFramework());
model->SetInitializeType(initialType);
model->SetThreadID(threadID);
std::string workPath = GetFramework()->GetWorkPath() + "/Packages/";
model->SetLibPath(workPath);
if (initialType == 0) {
// 使用std::filesystem处理路径
std::filesystem::path configPath =
std::filesystem::path(modelPath).parent_path()
/ (className + "_V" + modelVersion + ".mcfg");
model->SetXmlPath(configPath.string());
} else if (initialType == 1) {
model->SetXmlPath(planeName + "," + className + "," + modelVersion);
}
// 注册模型到管理器
d->ModelMap[modelID] = model;
// 初始化模型
model->Initialize();
// 注册到线程管理器
if (threadID != 0) {
auto framework = GetFramework();
if (framework) {
// 注册到线程管理器 (重复注册了,暂删除)
// framework->GetThreadManager()->RegisterFunction(
// modelID, std::bind(&XNModelObject::StepUpdate, model.get()), threadID,
// model->GetRunFreq(), model->GetRunNode(), model->GetRunPriority());
// 设置模型设置频率
double threadFreq =
framework->GetThreadManager()->GetThreadFreqByID(threadID);
double modelSetFreq = threadFreq / (double)(1 << model->GetRunFreq());
model->SetSetFreq(modelSetFreq);
}
}
} else {
LOG_WARNING("B01113004:动态链接库 %1 中未找到模型 %2!", modelPath, className);
dlclose(handle);
return;
}
} else {
LOG_WARNING("B01113005:动态链接库 %1 中未找到 %2 函数!", modelPath, initialModelName);
dlclose(handle);
return;
}
} else {
LOG_WARNING("C01113006:动态链接库 %1 加载失败! 错误: %2", modelPath, dlerror());
}
}
// 模型注册
uint32_t XNModelManager::RegisterModel()
{
T_D();
// 从1000019999的编号中分配ID
for (int i = 0; i < 10000; i++) {
if (d->ModelIDAssigned[i])
continue;
else {
d->ModelIDAssigned[i] = true;
return i + 10000;
}
}
return 0;
}
// 获取模型指针
XNModelObjectPtr XNModelManager::GetModel(uint32_t modelID)
{
T_D();
if (modelID >= 10000 && modelID < 20000) {
if (d->ModelIDAssigned[modelID - 10000]) {
auto model = d->ModelMap.find(modelID);
if (model != d->ModelMap.end()) {
return model->second;
}
LOG_WARNING("B01113007:模型ID %1 对应的模型不存在!", modelID);
return nullptr;
}
LOG_WARNING("B01113008:模型ID %1 未注册!", modelID);
return nullptr;
} else {
LOG_WARNING("B01113009:模型ID %1 不合法!", modelID);
return nullptr;
}
}
void XNModelManager::RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID,
uint32_t freqGroup, uint32_t RunPos, uint32_t RunPriorty)
{
T_D();
if (GetModel(id) != nullptr) {
auto framework = GetFramework();
if (framework) {
framework->GetThreadManager()->RegisterFunction(id, fun, threadID, freqGroup, RunPos,
RunPriorty);
}
} else {
LOG_WARNING("B01113010:模型ID %1 注册周期性函数失败, 模型不存在!", id);
}
}