XNSim/XNCore/XNModelManager.cpp

179 lines
4.9 KiB
C++
Raw Normal View History

2025-04-28 12:25:20 +08:00
/**
* @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"
2025-05-20 15:39:40 +08:00
#include "XNFramework.h"
#include "XNThreadManager.h"
2025-04-28 12:25:20 +08:00
// 构造函数
2025-05-20 15:39:40 +08:00
XNModelManager::XNModelManager() : XNBaseFrameObject(new XNModelManagerPrivate())
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
SetUniqueId(6);
SetObjectName("XNModelManager");
T_D();
2025-04-28 12:25:20 +08:00
d->ModelIDAssigned.resize(10000, false);
}
// 析构函数
XNModelManager::~XNModelManager()
{
}
2025-05-20 15:39:40 +08:00
XNModelManager::XNModelManager(PrivateType *p) : XNBaseFrameObject(p)
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->ModelIDAssigned.resize(10000, false);
}
bool XNModelManager::Initialize()
{
T_D();
LOG_INFO("D01114001:模型管理器初始化成功!");
d->_status = XNFrameObjectStatus::Initialized;
return true;
}
2025-04-28 12:25:20 +08:00
// 运行前最后准备
2025-05-20 15:39:40 +08:00
bool XNModelManager::PrepareForExecute()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
for (auto &model : d->ModelMap) {
model.second->PrepareForExecute();
}
2025-04-28 12:25:20 +08:00
d->_status = XNFrameObjectStatus::Ready;
LOG_INFO("D01114002:模型管理器准备就绪!");
2025-05-20 15:39:40 +08:00
return true;
2025-04-28 12:25:20 +08:00
}
2025-05-20 15:39:40 +08:00
void XNModelManager::LoadModel(const std::string &modelPath, const std::string &className,
const std::string &modelVersion, const std::string &planeName,
2025-05-20 15:39:40 +08:00
uint32_t initialType, uint32_t threadID)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
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());
2025-04-28 12:25:20 +08:00
if (initialModel) {
2025-05-20 15:39:40 +08:00
XNModelObjectPtr model = initialModel();
if (model) {
uint32_t modelID = RegisterModel();
if (modelID == 0) {
LOG_WARNING("B01113003:分配模型ID失败, 模型ID已用完, 模型无法注册!");
2025-05-20 15:39:40 +08:00
dlclose(handle);
2025-04-28 12:25:20 +08:00
return;
}
2025-05-20 15:39:40 +08:00
model->SetUniqueId(modelID);
model->SetObjectName(className);
model->SetFramework(GetFramework());
model->SetInitializeType(initialType);
model->SetThreadID(threadID);
2025-06-04 15:26:50 +08:00
std::string workPath = GetFramework()->GetWorkPath() + "/Packages/";
model->SetLibPath(workPath);
if (initialType == 0) {
// 使用std::filesystem处理路径
std::filesystem::path configPath =
2025-06-04 15:26:50 +08:00
std::filesystem::path(modelPath).parent_path()
/ (className + "_V" + modelVersion + ".mcfg");
model->SetXmlPath(configPath.string());
} else if (initialType == 1) {
model->SetXmlPath(planeName + "," + className + "," + modelVersion);
}
2025-05-20 15:39:40 +08:00
// 注册模型到管理器
d->ModelMap[modelID] = model;
// 初始化模型
model->Initialize();
2025-05-20 15:39:40 +08:00
// 注册到线程管理器
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);
2025-05-20 15:39:40 +08:00
}
}
2025-04-28 12:25:20 +08:00
} else {
LOG_WARNING("B01113004:动态链接库 %1 中未找到模型 %2!", modelPath, className);
2025-05-20 15:39:40 +08:00
dlclose(handle);
return;
2025-04-28 12:25:20 +08:00
}
} else {
LOG_WARNING("B01113005:动态链接库 %1 中未找到 %2 函数!", modelPath, initialModelName);
2025-05-20 15:39:40 +08:00
dlclose(handle);
return;
2025-04-28 12:25:20 +08:00
}
} else {
LOG_WARNING("C01113006:动态链接库 %1 加载失败! 错误: %2", modelPath, dlerror());
2025-04-28 12:25:20 +08:00
}
}
// 模型注册
2025-05-20 15:39:40 +08:00
uint32_t XNModelManager::RegisterModel()
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
// 从1000019999的编号中分配ID
for (int i = 0; i < 10000; i++) {
if (d->ModelIDAssigned[i])
continue;
else {
d->ModelIDAssigned[i] = true;
return i + 10000;
}
}
return 0;
}
// 获取模型指针
2025-05-20 15:39:40 +08:00
XNModelObjectPtr XNModelManager::GetModel(uint32_t modelID)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
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;
2025-04-28 12:25:20 +08:00
}
LOG_WARNING("B01113008:模型ID %1 未注册!", modelID);
2025-04-28 12:25:20 +08:00
return nullptr;
} else {
LOG_WARNING("B01113009:模型ID %1 不合法!", modelID);
2025-04-28 12:25:20 +08:00
return nullptr;
}
2025-04-28 12:25:20 +08:00
}
2025-05-20 15:39:40 +08:00
void XNModelManager::RegisterFunction(uint32_t id, XNCallBack fun, uint32_t threadID,
uint32_t freqGroup, uint32_t RunPos, uint32_t RunPriorty)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
if (GetModel(id) != nullptr) {
2025-05-20 15:39:40 +08:00
auto framework = GetFramework();
if (framework) {
framework->GetThreadManager()->RegisterFunction(id, fun, threadID, freqGroup, RunPos,
RunPriorty);
}
2025-04-28 12:25:20 +08:00
} else {
LOG_WARNING("B01113010:模型ID %1 注册周期性函数失败, 模型不存在!", id);
2025-04-28 12:25:20 +08:00
}
2025-05-20 15:39:40 +08:00
}