#include "GvlManager.h" #include "VPGlobal.h" #include "WindowAppVariableTable.h" #include "Preferences.h" // 单例模式 GvlManager* GvlManager::m_pGvlManager = nullptr; GvlManager::GvlManager() { // 创建默认的全局变量分组 this->initSystemGvl(); // 创建默认值变量分组(目前用于存储DataLink默认变量) this->initDefaultValues(); } /// /// 添加新的变量组 /// /// /// /// GVL* GvlManager::addNewGroup(const QString& strGroup, TOOL_TYPE varType, GVL_MODE gvlMode) { // 检查是否冲突 if (m_Gvls.contains(strGroup)) { qDebug() << "[Error] GvlManager::addNewGroup - but [" << strGroup << "] is exist."; return m_Gvls[strGroup]; } // 添加新的空变量组 GVL* newGroup = new GVL(strGroup, varType, gvlMode); this->m_Gvls.insert(strGroup, newGroup); return newGroup; } /// /// 添加新的变量 /// /// /// /// bool GvlManager::addNewVariable(const QString& strGroup, VARIABLE* pNewVar) { // 获取所属变量组 GVLS::iterator it = this->m_Gvls.find(strGroup); if (it != this->m_Gvls.end()) { // 设置变量归属的父指针 pNewVar->setParent(it.value()); // pNewVar->pOriginalTool = it.value(); it.value()->Variables.push_back(pNewVar); return true; } else { qWarning() << "[Error] GvlManager::addNewVariable - but [" << strGroup << "] is not exist."; return false; } } /// /// 2022-3-8添加新的默认变量(和正常变量分开存储) /// /// /// bool GvlManager::addNewDefaultVariable(VARIABLE* pNewVar) { pNewVar->setParent(m_defaultValueGvl); // pNewVar->pOriginalTool = m_defaultValueGvl; m_defaultValueGvl->Variables.push_back(pNewVar); return true; } /// /// 绑定UI和变量 /// /// /// void GvlManager::bindUIAndVariable(QTableWidget* pTable, QString& strVarFullName) { this->m_GvlTables.insert(strVarFullName, pTable); } /// /// 删除一个变量 /// /// /// void GvlManager::delVariable(const QString& strGroup, const int& nIndex) { VARIABLES& vars = m_Gvls[strGroup]->Variables; // 清理此变量的内存 delete vars[nIndex]->value.Ptr; *vars[nIndex]->value.Ptr = nullptr; vars[nIndex]->value.Ptr = nullptr; delete vars[nIndex]; vars[nIndex] = nullptr; // 清理数组中的对应元素 vars.erase(vars.begin() + nIndex); ////// 删除此group下的nIndex变量 ////for (QVector::iterator it = vars.begin(); it != vars.end();) ////{ //// if (it->item == pRunningBlock) //// { //// it = vars.erase(it); //// } //// else //// { //// it++; //// } ////} debugAllVariables(); } /// /// 移除一个变量(无需释放内存) /// /// /// void GvlManager::removeVariable(const QString& strGroup, const int& nIndex) { VARIABLES& vars = m_Gvls[strGroup]->Variables; vars.erase(vars.begin() + nIndex); // TODO:此处可能没有释放DB触发变量的Event,对应的Task端应该需要同时删除此Event的绑定 } /// /// 移除一个变量(无需释放内存) /// /// /// void GvlManager::removeVariable(const QString& strGroup, const QString& strName) { if (!m_Gvls.contains(strGroup)) { return; } VARIABLES& vars = m_Gvls[strGroup]->Variables; for (VARIABLES::iterator iter = vars.begin(); iter != vars.end();) { if ((* iter)->strName == strName)//进行路径匹配 { vars.erase(iter);//删除该行 } else { iter++; } } // TODO:此处可能没有释放DB触发变量的Event,对应的Task端应该需要同时删除此Event的绑定 } /// /// 变量交换顺序 /// /// /// /// void GvlManager::exchangeVariable(const QString& strGroup, const int& nIndex1, const int& nIndex2) { VARIABLE* varTmp = m_Gvls[strGroup]->Variables[nIndex1]; m_Gvls[strGroup]->Variables[nIndex1] = m_Gvls[strGroup]->Variables[nIndex2]; m_Gvls[strGroup]->Variables[nIndex2] = varTmp; debugAllVariables(); } /// /// /2022-3-2 绑定硬件组态指针和DB数据表 /// /// /// void GvlManager::bindHdwToolAndDB(TOOL* pTool, const QString& strDBGroup) { if ((pTool == nullptr) || (pTool->pDllPtr == nullptr)) { return; } DllTool* pHdwTool = pTool->pDllPtr; GVL* pDB = this->getGvl(strDBGroup); if (pDB == nullptr) { qWarning() << "Failed to find Gvl :" << strDBGroup; return; } pHdwTool->setBindDB(pDB); pTool->strHdwInstName = strDBGroup; pDB->strHdwInstName = pHdwTool->getInstanceName(); // 保存对应关系 m_DBToTool.insert(strDBGroup, pTool); } /// /// 2022-3-8 解绑硬件组态和指针 /// (此处只是添加了函数,但是尚未调用,需要额外加一下,在删除硬件工具和删除DB数据表的时候都需要调用) /// /// /// void GvlManager::unbindHdwToolAndDB(TOOL* pTool, const QString& strDBGroup) { if ((pTool == nullptr) || (pTool->pDllPtr == nullptr)) { return; } DllTool* pHdwTool = pTool->pDllPtr; // DB端解绑 if (m_Gvls.contains(strDBGroup)) { GVL* pDB = this->getGvl(strDBGroup); if (pDB != nullptr) { pDB->strHdwInstName.clear(); } } // Dll端解绑 pHdwTool->unbindDB(); pTool->strHdwInstName.clear(); // 移除绑定信息 m_DBToTool.remove(strDBGroup); } /// /// 检查是否与本组变量重名 /// /// /// /// bool GvlManager::isDuplicated(const QString& strGroup, const QString& newName) { if (m_Gvls.find(strGroup) ==m_Gvls.end()) { return false; } VARIABLES& vars = m_Gvls[strGroup]->Variables; QVectorIterator it(vars); while (it.hasNext()) { const VARIABLE* var = it.next(); if (var->strName == newName) { return true; } } return false; } /// /// 检查用户输入的变量类型和数值是否匹配 /// /// /// /// /// bool GvlManager::isValueValid(const QString& newType, const QString& newValue) { // 如果是字符串,那么所有的都合法 if (newType == Utility::getTypeString(VALUE_TYPE::Type_String)) { return true; } // 如果是bool类型,只有true false 和 1 0 合法 else if (newType == Utility::getTypeString(VALUE_TYPE::Type_Bool)) { if (newValue == "true" || newValue == "false" || newValue == "1" || newValue == "0") { return true; } else { return false; } } // 如果是int类型 else if (newType == Utility::getTypeString(VALUE_TYPE::Type_Int)) { return Utility::isIntString(newValue); } // 如果是float类型 else if (newType == Utility::getTypeString(VALUE_TYPE::Type_Float)) { return Utility::isFloatString(newValue); } return true; } /// /// 检查用户输入的变量类型和数值是否匹配 /// /// /// /// bool GvlManager::isValueValid(const VALUE_TYPE newType, const QString& newValue) { // 如果是字符串,那么所有的都合法 if (newType == VALUE_TYPE::Type_String) { return true; } // 如果是bool类型,只有true false 和 1 0 合法 else if (newType == VALUE_TYPE::Type_Bool) { if (newValue == "true" || newValue == "false" || newValue == "1" || newValue == "0") { return true; } else { return false; } } // 如果是int类型 else if (newType == VALUE_TYPE::Type_Int) { return Utility::isIntString(newValue); } // 如果是float类型 else if (newType == VALUE_TYPE::Type_Float) { return Utility::isFloatString(newValue); } return true; } /// /// 本分组是否是全局变量 /// /// /// bool GvlManager::isGlobalGvl(const QString& strGroup) { if (m_Gvls.contains(strGroup)) { if (m_Gvls[strGroup]->Type == TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE) { return true; } } return false; } /// /// 本分组是否是硬件变量 /// /// /// bool GvlManager::isHardwareGvl(const QString& strGroup) { return (strGroup== CATEGORY_TOOL_HARDWARE); } /// /// 本分组是否是Pou局部变量 /// /// /// bool GvlManager::isLocalGvl(const QString& strGroup) { if (m_Gvls.contains(strGroup)) { if (m_Gvls[strGroup]->Type == TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE) { return true; } } return false; } /// /// 更新持久化状态 /// /// /// /// void GvlManager::updatePersit(const QString& strGroup, const int& nIndex, bool newValue) { // 有效性检查 VARIABLES& vars = m_Gvls[strGroup]->Variables; if (nIndex >= vars.size()) { return; } VARIABLE* var = m_Gvls[strGroup]->Variables[nIndex]; // 检查值是否有变动,没有变动就不更新了 if (var->bSerialized == newValue) { qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " persistent, but is the same. "; return; } var->bSerialized = newValue; qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " bPersit to " << newValue; debugVariable(var); } /// /// 更新Value /// /// /// /// bool GvlManager::updateValue(const QString& strGroup, const int& nIndex, const QString& newValue) { // 需要跳过不显示的变量 int nVarIndex = nIndex; { VARIABLES& vars = m_Gvls[strGroup]->Variables; for (int i = 0; i< vars.size(); i++) { VARIABLE* var = m_Gvls[strGroup]->Variables[i]; if (!var->bShow) { nVarIndex++; } } } // 参数有效性检查 VARIABLES& vars = m_Gvls[strGroup]->Variables; if (nVarIndex >= vars.size()) { return false; } VARIABLE* var = m_Gvls[strGroup]->Variables[nVarIndex]; // 检查值是否和类型匹配 if (!this->isValueValid(var->value.type, newValue)) { qDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " value, but is invalid. "; //// 也要更新值,但是这个值是一个无效值,无法使用 //var->value.strValueString = newValue; //var->bValid = false; // debugVariable(var); return false; } // 可以更新值了 //var->value.strValueString = newValue; var->setValue(newValue); //// 置为有效值 //var->bValid = true; vDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " value to " << newValue; // 2022-9-1,由于DB变量增加了触发Task执行的特性,如果是DB变量更新,并且带有触发特性,还需要向TaskManager发送触发信号 if (m_Gvls[strGroup]->gvlMode == GVL_MODE::GVL_DB) { if (var->eventTrigger != nullptr) { // 2022-9-25,由于WaitTool需要支持等待某一个值触发,所以ToolEvent中保存每次DB变量的最新值 var->eventTrigger->m_triggerValue = var->value; // 发送到TaskManager触发Task执行 // NOTICE:此处注意不能用postEvent,否则会自动释放掉这个事件指针造成程序崩溃 QCoreApplication::sendEvent((QObject*)g_pTaskManager, var->eventTrigger); vDebug() << "[GVL] Post " << var->strFullName << " event trigger to task."; } } // debugVariable(var); return true; } /// /// 更新Comment /// /// /// /// bool GvlManager::updateComment(const QString& strGroup, const int& nIndex, const QString& newComment) { // 需要跳过不显示的变量 int nVarIndex = nIndex; { VARIABLES& vars = m_Gvls[strGroup]->Variables; for (int i = 0; i < vars.size(); i++) { VARIABLE* var = m_Gvls[strGroup]->Variables[i]; if (!var->bShow) { nVarIndex++; } } } // 参数有效性检查 VARIABLES& vars = m_Gvls[strGroup]->Variables; if (nVarIndex >= vars.size()) { return false; } VARIABLE* var = m_Gvls[strGroup]->Variables[nVarIndex]; // 检查值是否有变动,没有变动就不更新了 if (var->strComment == newComment) { qDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " value, but is the same. "; return true; } var->strComment = newComment; qDebug() << "[GVL] Change " << strGroup << "-Index: " << nVarIndex << " Comment to " << newComment; debugVariable(var); return true; } /// /// 更新通讯地址(仅DB模式) /// /// /// /// /// bool GvlManager::updateDbCommAddress(const QString& strGroup, const int& nIndex, const QString& newAddress) { // 参数有效性检查 VARIABLES& vars = m_Gvls[strGroup]->Variables; if (nIndex >= vars.size()) { return false; } VARIABLE* var = m_Gvls[strGroup]->Variables[nIndex]; // 检查值是否有变动,没有变动就不更新了 if (var->strCommAddress == newAddress) { qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " value, but is the same. "; return true; } var->strCommAddress = newAddress; qDebug() << "[GVL] Change " << strGroup << "-Index: " << nIndex << " Comment to " << newAddress; debugVariable(var); return true; } /// /// 输出一个全局变量的详细信息(For Debug) /// /// void GvlManager::debugVariable(const VARIABLE* var) { qDebug() << "[" << var->parent()->strName << "] - " << var->strName <<"(Persis: " << var->bSerialized << ")" << "\n\t[Type] - " << Utility::getTypeString(var->value.type) << "\n\t[Value] - " << var->getValueString() // << "\n\t[ValueString] - " << var->value.strValueString << "\n\t[Comment] - " << var->strComment; } /// /// 输出目前所有的全局变量信息 /// void GvlManager::debugAllVariables() { QMapIterator it(m_Gvls); qDebug() << "================ All Variables ========================="; while (it.hasNext()) { qDebug() << "Group: " << it.next().key(); const GVL* gvl = it.value(); QVectorIterator it2(gvl->Variables); while (it2.hasNext()) { const VARIABLE* var = it2.next(); qDebug() << "\t" << var->strName << " - " << var->bSerialized << " " << Utility::getTypeString(var->value.type) << " " << var->getValueString() << " " << var->strComment; } } qDebug() << "=============================================================\n"; } /// /// 根据名字获取指定变量 /// /// /// /// VARIABLE* GvlManager::getVariableByName(const QString& strGroupName, const QString& strVarName) { if (m_Gvls.contains(strGroupName)) { const VARIABLES& vars = m_Gvls[strGroupName]->Variables; for (auto var : vars) { if (var->strName == strVarName) { return var; } } } return nullptr; } /// /// 根据名字获取指定的默认值 /// /// /// const VARIABLE* GvlManager::getDefaultValueByName(const QString& strValueName) const { return m_defaultValueGvl->getInterfaceByName(strValueName); } /// /// 获取本分组的变量数 /// /// /// int GvlManager::getVariablesCountByGroup(const QString& strGroupName) { if (m_Gvls.contains(strGroupName)) { return m_Gvls[strGroupName]->Variables.size(); } else { return 0; } } /// /// 2022-9-1 获取全部带有Event触发特性的变量 /// /// QHash GvlManager::getAllEventVariables() { QHash eventVars; QMapIterator it(m_Gvls); while (it.hasNext()) { // 取出每一个变量组 const GVL* pGvl = it.next().value(); // 取出本变量组中的变量 const VARIABLES& vars = pGvl->Variables; // 遍历所有变量,找到具有触发机制的变量,添加到界面中 for (VARIABLE* var : vars) { if (var->eventTrigger != nullptr) { eventVars.insert(var->strFullName, var); } } } return eventVars; } /// /// 获取需要序列化的分组(跳过系统内置变量) /// /// QList GvlManager::getAllSerializedGvls() { QList gvls; QMapIterator it(m_Gvls); while (it.hasNext()) { // 需要跳过系统内置变量和硬件变量 if (it.next().key() != GROUP_NAME_SYSTEM && it.key() != GROUP_NAME_HARDWARE && it.key() != GROUP_NAME_DEFAULVALUE ) { gvls.push_back(it.value()); } } return gvls; } /// /// 删除指定Pou分组 /// /// void GvlManager::removeGvl(const QString& strGroupName) { // 2022-2-22 ,此处如果是SYSTEM分组的话,需要跳过(这种情况应该不会出现才对) if (strGroupName == GROUP_NAME_SYSTEM) { qWarning() << "[Warning] VariablesManager::removeVariablesGroup - name: System Group"; return; } // 删除变量组 m_Gvls.remove(strGroupName); // 删除变量表格 m_GvlTables.remove(strGroupName); // TODO: 是否需要清空相关内存? } /// /// 2021-11-13 接收表格中的变量刷新显示Event /// /// void GvlManager::customEvent(QEvent* event) { // 只处理数值同步消息 if (event->type() == VALUE_EVENT_TYPEID) { qDebug() << "UiManager::event - VALUE_EVENT"; SyncValueEvent* pValueEvent = dynamic_cast (event); // 取出参数 QList syncValues = pValueEvent->getSyncValues(); for (VARIABLE* syncVal : syncValues) { // 2022-3-23处理,如果是Port类型的话,这里的strFullName是错误的 // this->syncValueToTable(syncVal->strFullName, syncVal->getValueString()); if (syncVal->isBinded()) { this->syncValueToTable(syncVal->pBindInterface->strFullName, syncVal->getValueString()); } else { this->syncValueToTable(syncVal->strFullName, syncVal->getValueString()); } } } } /// /// 将变量同步更新到Table中 /// /// void GvlManager::syncValueToTable(const QString& strFullName, const QString& strValueString) { WindowAppVariableTable* pTableUI = qobject_cast(this->m_GvlTables.value( strFullName)); if (pTableUI != nullptr) { // pTableUI->updateTableValue(pDownLinks[i]->strFullName, pDownLinks[i]->getValueString()); pTableUI->updateTableValue(strFullName, strValueString); } else { // 2022-2-17 qDebug() << "[DEBUG] VariablesManager::syncValueToTable - updateTableValue failed, reason: pTableUI is nullptr."; } } /// /// 数据结构重置 /// void GvlManager::reset() { // m_Variables.clear(); // 2022-2-22修改,重置时需要跳过SYSTEM分组和硬件组态分组 for (GVLS::iterator it = m_Gvls.begin(); it != m_Gvls.end();) { if (it.key() != GROUP_NAME_SYSTEM && it.key() != GROUP_NAME_HARDWARE && it.key() != GROUP_NAME_DEFAULVALUE ) { // 删除分组之前,需要清理DB 组的绑定状态 if (it.value()->gvlMode == GVL_MODE::GVL_DB) { QString strGvlName = it.value()->strName; TOOL* pTool = getHdwToolByDbName(strGvlName); g_pGvlManager->unbindHdwToolAndDB(pTool, strGvlName); } it = m_Gvls.erase(it); } else { it++; } } // TODO: 因为没有SYSTEM分组的变量表格显示,所以可以全部清除,如果后面有了SYSTEM变量表格也就需要细分一下了 m_GvlTables.clear(); // 重置SYSTEM分组变量的值 thePrefs.m_nRunningCount = 0; thePrefs.m_strProjectPath = DEFAULT_PROJECT_PATH; thePrefs.m_strProjectName = DEFAULT_PROJECT_NAME; } /// /// 2022-2-15 创建内置的全局变量组(System) /// void GvlManager::initSystemGvl() { // int nIndex = getVariablesCountByGroup(GROUP_NAME_SYSTEM); // 2022-3-2, 首先创建对应的系统变量组 this->addNewGroup(GROUP_NAME_SYSTEM, TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE, GVL_MODE::GVL_BASIC); int nIndex = 0; // 系统运行计数 VARIABLE* pNewVariable = new VARIABLE( GROUP_NAME_SYSTEM, false, SYSTEMVAR_NAME_EXECCOUNT, "int", "0", SYSTEMVAR_CHNAME_EXECCOUNT, nIndex, true ); this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable); // 系统项目名称 pNewVariable = new VARIABLE( GROUP_NAME_SYSTEM, false, SYSTEMVAR_NAME_PROJECTNAME, "QString", "", SYSTEMVAR_CHNAME_PROJECTNAME, nIndex ++, true ); this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable); // 系统项目路径 pNewVariable = new VARIABLE( GROUP_NAME_SYSTEM, false, SYSTEMVAR_NAME_PROJECTPATH, "QString", "", SYSTEMVAR_CHNAME_PROJECTPATH, nIndex ++, true ); this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable); // 系统时间 pNewVariable = new VARIABLE( GROUP_NAME_SYSTEM, false, SYSTEMVAR_NAME_TIME, "QString", "00:00:00", SYSTEMVAR_CHNAME_TIME, nIndex ++, true ); this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable); // 开机时长 pNewVariable = new VARIABLE( GROUP_NAME_SYSTEM, false, SYSTEMVAR_NAME_RUNTIME, "QString", "00:00:00", SYSTEMVAR_CHNAME_RUNTIME, nIndex ++, true ); this->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable); // 2022-2-20,将必要的变量绑定至全局变量SYSTEM组中 this->bindSystemGvl(); } /// /// 2022-2-20 绑定SYSTEM全局变量和类中的关键变量 /// void GvlManager::bindSystemGvl() { VARIABLE* pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_EXECCOUNT); pVar->value.setValueByAddress((void**)&thePrefs.m_nRunningCount); pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_PROJECTNAME); pVar->value.setValueByAddress((void**)&thePrefs.m_strProjectName); pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_PROJECTPATH); pVar->value.setValueByAddress((void**)& thePrefs.m_strProjectPath); pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_TIME); pVar->value.setValueByAddress((void**)&thePrefs.m_strSystemTime); pVar = getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_RUNTIME); pVar->value.setValueByAddress((void**)&thePrefs.m_strLiveTime); } /// /// 2022-3-7 创建默认值的变量组,例如 0,"" 等等(DefaultValue) /// (目前只有复杂控件的DataLink在使用,本组变量是只读的,不允许修改) /// void GvlManager::initDefaultValues() { // 2022-3-2, 首先创建对应的默认值变量组 m_defaultValueGvl = new GVL(GROUP_NAME_DEFAULVALUE, TOOL_TYPE::TOOL_TYPE_GLOBAL_VARIABLE, GVL_MODE::GVL_STANDARD); int nIndex = 0; // int型的默认值 VARIABLE* pNewVariable = new VARIABLE( GROUP_NAME_DEFAULVALUE, false, DEFAULT_VALUE_0, "int", "0", "", nIndex, false ); this->addNewDefaultVariable(pNewVariable); // QString的默认值 pNewVariable = new VARIABLE( GROUP_NAME_DEFAULVALUE, false, DEFAULT_VALUE_NULLSTRING, "QString", "", "", nIndex++, false ); this->addNewDefaultVariable(pNewVariable); } ///// ///// 数据结构序列化 ///// ///// ///// ///// //QDataStream& operator<<(QDataStream& out, const GvlManager& w) //{ // Q_UNUSED(w); // // return out; //} ///// ///// 数据结构反序列化 ///// ///// ///// ///// //QDataStream& operator>>(QDataStream& in, GvlManager& w) //{ // Q_UNUSED(w); // // return in; //}