XNSim/XNCore_Win/XNModelManager/XNModelManager.cpp

174 lines
5.4 KiB
C++
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 "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();
// 从1000019999的编号中分配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