/** * @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