174 lines
5.4 KiB
C++
174 lines
5.4 KiB
C++
/**
|
||
* @file XNModelManager.cpp
|
||
* @author jinchao
|
||
* @brief 模型管理器类源文件
|
||
* @version 1.0
|
||
* @date 2024-11-06
|
||
*
|
||
* @copyright Copyright (c) 2024 XN
|
||
*
|
||
*/
|
||
#include "XNModelManager.h"
|
||
#include "XNFramework/XNFramework.h"
|
||
#include "XNModelManager_p.h"
|
||
#include "XNModelObject/XNModelObject.h"
|
||
#include "XNThreadManager/XNThreadManager.h"
|
||
|
||
|
||
namespace XNSim {
|
||
// 构造函数
|
||
XNModelManager::XNModelManager()
|
||
: XNBaseFrameObject(new XNModelManagerPrivate()) {
|
||
SetUniqueId(enumValue(XNCoreObjectID::ModelManager));
|
||
SetObjectName("XNModelManager");
|
||
T_D();
|
||
d->ModelIDAssigned.resize(XN_MODEL_ID_SIZE, false);
|
||
}
|
||
|
||
// 析构函数
|
||
XNModelManager::~XNModelManager() {}
|
||
|
||
XNModelManager::XNModelManager(PrivateType *p) : XNBaseFrameObject(p) {}
|
||
|
||
// 运行前最后准备
|
||
XN_BOOL XNModelManager::PrepareForExecute() {
|
||
T_D();
|
||
for (auto &model : d->ModelMap) {
|
||
model.second->PrepareForExecute();
|
||
}
|
||
d->_status = XNFrameObjectStatus::Ready;
|
||
LOG_INFO("XNModelManager is prepared!");
|
||
return true;
|
||
}
|
||
|
||
XN_BOOL XNModelManager::Initialize() {
|
||
T_D();
|
||
LOG_INFO("XNModelManager Initialize Success!");
|
||
d->_status = XNFrameObjectStatus::Initialized;
|
||
return true;
|
||
}
|
||
|
||
void XNModelManager::LoadModel(const XN_STRING &modelPath,
|
||
const XN_STRING &className,
|
||
const XN_STRING &modelVersion,
|
||
const XN_STRING &planeName,
|
||
XN_UINT32 initialType, XN_UINT32 threadID) {
|
||
T_D();
|
||
XN_HANDLE handle = loadLibrary(modelPath);
|
||
if (handle) {
|
||
typedef XNModelObjectPtr (*InitialModelFunc)();
|
||
XN_STRING initialModelName = "Initial" + className;
|
||
InitialModelFunc initialModel =
|
||
(InitialModelFunc)getSymbol(handle, initialModelName.c_str());
|
||
if (initialModel) {
|
||
XNModelObjectPtr model = initialModel();
|
||
if (model) {
|
||
XN_UINT32 modelID = RegisterModel();
|
||
if (modelID == 0) {
|
||
LOG_WARNING("0x2174 Assign Model ID Failed, Model ID is used up!");
|
||
closeLibrary(handle);
|
||
return;
|
||
}
|
||
model->SetUniqueId(modelID);
|
||
model->SetObjectName(className);
|
||
model->SetFramework(GetFramework());
|
||
model->SetInitializeType(initialType);
|
||
model->SetThreadID(threadID);
|
||
XN_STRING workPath = GetFramework()->GetWorkPath() + "/Packages/";
|
||
model->SetLibPath(workPath);
|
||
if (initialType == 0) {
|
||
// 使用std::filesystem处理路径
|
||
XN_PATH configPath = XN_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()); 设置模型设置频率
|
||
XN_DOUBLE threadFreq =
|
||
framework->GetThreadManager()->GetThreadFreqByID(threadID);
|
||
XN_DOUBLE modelSetFreq =
|
||
threadFreq / (double)(1 << model->GetRunFreq());
|
||
model->SetSetFreq(modelSetFreq);
|
||
}
|
||
}
|
||
} else {
|
||
LOG_WARNING("0x2173 Model %s Not found in dynamic link library %s!",
|
||
className.c_str(), modelPath.c_str());
|
||
closeLibrary(handle);
|
||
return;
|
||
}
|
||
} else {
|
||
LOG_WARNING(
|
||
"0x2177 InitialModel function not found in dynamic link library %s!",
|
||
modelPath);
|
||
closeLibrary(handle);
|
||
return;
|
||
}
|
||
} else {
|
||
LOG_WARNING(
|
||
"0x2172 Model %s Dynamic link library loading failed! Error: %s",
|
||
className, LoadError());
|
||
}
|
||
}
|
||
|
||
// 模型注册
|
||
XN_UINT32 XNModelManager::RegisterModel() {
|
||
T_D();
|
||
// 从10000~19999的编号中分配ID
|
||
for (XN_UINT32 i = 0; i < XN_MODEL_ID_SIZE; i++) {
|
||
if (d->ModelIDAssigned[i])
|
||
continue;
|
||
else {
|
||
d->ModelIDAssigned[i] = true;
|
||
return i + XN_MODEL_ID_START;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 获取模型指针
|
||
XNModelObjectPtr XNModelManager::GetModel(XN_UINT32 modelID) {
|
||
T_D();
|
||
if (d->ModelIDAssigned[modelID - XN_MODEL_ID_START]) {
|
||
auto model = d->ModelMap.find(modelID);
|
||
if (model != d->ModelMap.end()) {
|
||
return model->second;
|
||
}
|
||
return nullptr;
|
||
} else
|
||
return nullptr;
|
||
}
|
||
|
||
void XNModelManager::RegisterFunction(XN_UINT32 id, XNCallBack fun,
|
||
XN_UINT32 threadID, XN_UINT32 freqGroup,
|
||
XN_UINT32 RunPos, XN_UINT32 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);
|
||
}
|
||
}
|
||
} // namespace XNSim
|