XNSim/XNCore/XNModelManager.cpp

169 lines
4.3 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"
#include <QLibrary>
#include <QMetaObject>
#include <QPointer>
// 构造函数
XNModelManager::XNModelManager(QObject *parent)
: XNBaseFrameObject(*new XNModelManagerPrivate(this), parent)
{
setUniqueId(6);
setObjectName("XNModelManager");
Q_D(XNModelManager);
d->ModelIDAssigned.resize(10000, false);
}
// 析构函数
XNModelManager::~XNModelManager()
{
}
XNModelManager::XNModelManager(XNModelManagerPrivate &dd, QObject *parent)
: XNBaseFrameObject(dd, parent)
{
Q_D(XNModelManager);
d->ModelIDAssigned.resize(10000, false);
}
// 运行前最后准备
void XNModelManager::OnPrepareForExecute()
{
Q_D(XNModelManager);
emit PrepareForExecute();
d->_status = XNFrameObjectStatus::Ready;
LOG_INFO("XNModelManager is prepared!");
emit PrepareForExecuteSuccess();
}
void XNModelManager::OnInitialize()
{
Q_D(XNModelManager);
LOG_INFO("XNModelManager Initialize Success!");
d->_status = XNFrameObjectStatus::Initialized;
emit InitializeSuccess();
}
void XNModelManager::OnLoadModel(const QString &modelPath, const QString &className)
{
Q_D(XNModelManager);
QLibrary lib(modelPath);
if (lib.load()) {
typedef void (*InitialModelFunc)();
QString initialModelName = "Initial" + className;
InitialModelFunc initialModel =
(InitialModelFunc)lib.resolve(initialModelName.toUtf8().constData());
if (initialModel) {
initialModel();
QMetaType metaType = QMetaType::fromName(className.toUtf8().constData());
if (metaType.isValid()) {
QObject *obj = static_cast<QObject *>(metaType.create());
if (obj) {
XNModelObject *model = qobject_cast<XNModelObject *>(obj);
if (model) {
quint32 modelID = RegisterModel();
if (modelID == 0) {
LOG_WARNING("0x2174 Assign Model ID Failed, Model ID is used up!");
delete obj;
return;
}
model->setParent(this);
model->setObjectName(className);
model->setUniqueId(modelID);
model->SetBaseFreq(d->dBaseFreq);
QString configFilePath =
QFileInfo(modelPath).absolutePath() + "/" + className + ".mcfg";
model->SetXmlPath(configFilePath);
connect(model, &XNModelObject::RegisterFunction, this,
&XNModelManager::OnRegisterFunction);
connect(this, &XNModelManager::PrepareForExecute, model,
&XNModelObject::OnPrepareForExecute);
model->OnInitialize();
} else {
LOG_WARNING("0x2175 Model %1 Instantiation Failed, Not a subclass of "
"XNModelObject!",
className);
delete obj;
return;
}
} else {
LOG_WARNING("0x2176 Model %1 Instantiation Failed, Not a subclass of QObject!",
className);
delete obj;
return;
}
} else {
LOG_WARNING("0x2173 Model %1 Not found in dynamic link library %2!", className,
modelPath);
}
} else {
LOG_WARNING("0x2177 InitialModel function not found in dynamic link library %2!",
modelPath);
}
} else {
LOG_WARNING("0x2172 Model %1 Dynamic link library loading failed! Error: %2", className,
lib.errorString());
}
}
void XNModelManager::OnSetBaseFreq(const double &dBaseFreq)
{
Q_D(XNModelManager);
d->dBaseFreq = dBaseFreq;
}
// 模型注册
quint32 XNModelManager::RegisterModel()
{
Q_D(XNModelManager);
// 从1000019999的编号中分配ID
for (int i = 0; i < 10000; i++) {
if (d->ModelIDAssigned[i])
continue;
else {
d->ModelIDAssigned[i] = true;
return i + 10000;
}
}
return 0;
}
// 获取模型指针
XNModelObject *XNModelManager::GetModel(quint32 modelID)
{
Q_D(XNModelManager);
if (d->ModelIDAssigned[modelID - 10000]) {
QList<XNModelObject *> modelList = findChildren<XNModelObject *>();
for (auto &model : modelList) {
if (model->getUniqueId() == modelID)
return model;
}
return nullptr;
} else
return nullptr;
}
void XNModelManager::OnRegisterFunction(quint32 id, XNCallBack fun, quint32 freqGroup,
quint32 RunPos, quint32 RunPriorty)
{
Q_D(XNModelManager);
if (d->ModelIDAssigned[id - 10000]) {
emit RegisterFunction(id, fun, freqGroup, RunPos, RunPriorty);
} else {
LOG_WARNING(
"0x2177 Submission of periodic function was rejected, model ID %1 is not registered!",
id);
}
}