XNSim/XNCore/XNModelManager.cpp

159 lines
3.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::PrepareForExecute()
{
T_D();
d->_status = XNFrameObjectStatus::Ready;
LOG_INFO("XNModelManager is prepared!");
return true;
}
bool XNModelManager::Initialize()
{
T_D();
LOG_INFO("XNModelManager Initialize Success!");
d->_status = XNFrameObjectStatus::Initialized;
return true;
}
void XNModelManager::LoadModel(const std::string &modelPath, const std::string &className,
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("0x2174 Assign Model ID Failed, Model ID is used up!");
dlclose(handle);
return;
}
model->SetUniqueId(modelID);
model->SetObjectName(className);
model->SetFramework(GetFramework());
// 使用std::filesystem处理路径
std::filesystem::path configPath =
std::filesystem::path(modelPath).parent_path() / (className + ".mcfg");
model->SetXmlPath(configPath.string());
// 注册模型到管理器
d->ModelMap[modelID] = model;
// 初始化模型
model->Initialize(initialType, threadID);
// 注册到线程管理器
if (threadID != 0) {
auto framework = GetFramework();
if (framework) {
framework->GetThreadManager()->RegisterFunction(
modelID, std::bind(&XNModelObject::StepUpdate, model.get()), threadID,
0, 0, 0);
}
}
} else {
LOG_WARNING("0x2173 Model %s Not found in dynamic link library %s!",
className.c_str(), modelPath.c_str());
dlclose(handle);
return;
}
} else {
LOG_WARNING("0x2177 InitialModel function not found in dynamic link library %s!",
modelPath.c_str());
dlclose(handle);
return;
}
} else {
LOG_WARNING("0x2172 Model %s Dynamic link library loading failed! Error: %s",
className.c_str(), 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 (d->ModelIDAssigned[modelID - 10000]) {
auto model = d->ModelMap.find(modelID);
if (model != d->ModelMap.end()) {
return model->second;
}
return nullptr;
} else
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 (d->ModelIDAssigned[id - 10000]) {
auto framework = GetFramework();
if (framework) {
framework->GetThreadManager()->RegisterFunction(id, fun, threadID, freqGroup, RunPos,
RunPriorty);
}
} else {
LOG_WARNING(
"0x2177 Submission of periodic function was rejected, model ID %1 is not registered!",
id);
}
}