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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 运行前最后准备
|
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();
|
2025-05-21 12:17:50 +08:00
|
|
|
|
for (auto &model : d->ModelMap) {
|
|
|
|
|
model.second->PrepareForExecute();
|
|
|
|
|
}
|
2025-04-28 12:25:20 +08:00
|
|
|
|
d->_status = XNFrameObjectStatus::Ready;
|
|
|
|
|
LOG_INFO("XNModelManager is prepared!");
|
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
|
|
|
|
bool XNModelManager::Initialize()
|
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
|
|
|
|
LOG_INFO("XNModelManager Initialize Success!");
|
|
|
|
|
d->_status = XNFrameObjectStatus::Initialized;
|
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,
|
|
|
|
|
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("0x2174 Assign Model ID Failed, Model ID is used up!");
|
|
|
|
|
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());
|
2025-05-21 12:17:50 +08:00
|
|
|
|
model->SetInitializeType(initialType);
|
|
|
|
|
model->SetThreadID(threadID);
|
2025-05-20 15:39:40 +08:00
|
|
|
|
// 使用std::filesystem处理路径
|
|
|
|
|
std::filesystem::path configPath =
|
|
|
|
|
std::filesystem::path(modelPath).parent_path() / (className + ".mcfg");
|
|
|
|
|
model->SetXmlPath(configPath.string());
|
|
|
|
|
|
|
|
|
|
// 注册模型到管理器
|
|
|
|
|
d->ModelMap[modelID] = model;
|
|
|
|
|
|
|
|
|
|
// 初始化模型
|
2025-05-21 12:17:50 +08:00
|
|
|
|
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,
|
2025-05-21 12:17:50 +08:00
|
|
|
|
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 {
|
2025-05-20 15:39:40 +08:00
|
|
|
|
LOG_WARNING("0x2173 Model %s Not found in dynamic link library %s!",
|
|
|
|
|
className.c_str(), modelPath.c_str());
|
|
|
|
|
dlclose(handle);
|
|
|
|
|
return;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2025-05-20 15:39:40 +08:00
|
|
|
|
LOG_WARNING("0x2177 InitialModel function not found in dynamic link library %s!",
|
|
|
|
|
modelPath.c_str());
|
|
|
|
|
dlclose(handle);
|
|
|
|
|
return;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2025-05-20 15:39:40 +08:00
|
|
|
|
LOG_WARNING("0x2172 Model %s Dynamic link library loading failed! Error: %s",
|
|
|
|
|
className.c_str(), 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
|
|
|
|
// 从10000~19999的编号中分配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();
|
2025-04-28 12:25:20 +08:00
|
|
|
|
if (d->ModelIDAssigned[modelID - 10000]) {
|
2025-05-20 15:39:40 +08:00
|
|
|
|
auto model = d->ModelMap.find(modelID);
|
|
|
|
|
if (model != d->ModelMap.end()) {
|
|
|
|
|
return model->second;
|
2025-04-28 12:25:20 +08:00
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
} else
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
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();
|
2025-04-28 12:25:20 +08:00
|
|
|
|
if (d->ModelIDAssigned[id - 10000]) {
|
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(
|
|
|
|
|
"0x2177 Submission of periodic function was rejected, model ID %1 is not registered!",
|
|
|
|
|
id);
|
|
|
|
|
}
|
2025-05-20 15:39:40 +08:00
|
|
|
|
}
|