#include "Pou.h" #include "WindowAppItemInterface.h" #include "WindowAppBlockStandard.h" #include "WindowAppBlockStandardBase.h" #include "WindowAppBlockGoto.h" #include "WindowAppVariableTable.h" #include "GvlManager.h" #include "TaskManager.h" #include "../Common/CameraBaseClass/IBaseCamCommon.h" #include "../Common/CameraBaseClass/IBaseCamera.h" #include "WindowAppTaskView.h" POU::POU() { m_nExecuteIndex = 0; // 并行工具线程池支持的最大并行工具数量 m_ParallelThreadPool.setMaxThreadCount(MAX_PARALLEL_TOOL_COUNT); } /// /// 2022-2-16,在Pou析构的时候需要释放掉内部变量 /// POU::~POU() { g_pGvlManager->removeVariable(m_strPouName, INTERNALVAR_NAME_EXECTIME); g_pGvlManager->removeVariable(m_strPouName, INTERNALVAR_NAME_EXECCOUNT); g_pGvlManager->removeVariable(m_strPouName, INTERNALVAR_NAME_ERRORCOUNT); } /// /// 重置本Pou中所有的数据结构 /// void POU::reset() { // 遍历所有的工具 QHash::iterator iter = m_itemToTools.begin(); while (iter != m_itemToTools.end()) { // 回收资源 if (iter.value()->pDllPtr != nullptr) { delete iter.value()->pDllPtr; iter.value()->pDllPtr = nullptr; } // 从界面中移除此功能块 QString str = iter.value()->strInstanceName; WindowAppBlockBase* pItem = m_instNameToToolItems[str]; if (pItem != nullptr) { pItem->scene()->removeItem(pItem); } iter++; } m_instNameToTools.clear(); m_fullNameToInterfaces.clear(); m_itemToTools.clear(); m_itemToInterfaces.clear(); m_instNameToToolItems.clear(); m_fullNameToInterfaceItems.clear(); m_AutoToolRenameIndex.clear(); m_Links.clear(); } /// /// 添加一个运行的Tool功能块到当前Pou中 /// /// void POU::registerTool(WindowAppBlockBase* pBlockItem, TOOL* pRunningTool) { // 保存功能块和工具的对应信息 m_itemToTools.insert(pBlockItem, pRunningTool); m_instNameToTools.insert(pRunningTool->strInstanceName, pRunningTool); m_instNameToToolItems.insert(pRunningTool->strInstanceName, pBlockItem); // 重命名计数 + 1 AddRenameRefCount(pRunningTool->strName); // 2021-8-14 如果是StandardTool,则刷新StandardTools列表 // 2022-3-28 更新 (NOTICE:此处是包含了标准工具和Goto工具一起的) // 2022-4-28 加入了Parallel工具 // 2022-8-25 加入了ForLoop工具 if (pRunningTool->isIndexedTool() ) { m_StandardTools.push_back(pRunningTool); // 2022-3-31更新,此处要保证严格有序,否则反序列化或者其他时候可能会有各种隐患 std::sort(m_StandardTools.begin(), m_StandardTools.end(), TOOL::sort_by_index); // 2021-8-14 Pou中添加工具后,如果当前Pou被Task选中,则需要向Task同步新增加的Tool信息 if (m_pParentTask != nullptr) { g_pTaskManager->addToolToTaskView(m_pParentTask->strName, this, pRunningTool); } } #ifdef QT_NO_DEBUG #else // 输出调试信息 // debugAllTools(); #endif } /// /// 添加一个运行的接口到当前Pou中 /// /// /// void POU::registerInterface(WindowAppItemInterface* pInfItem, _INTERFACE* pSelInf) { if (pInfItem == nullptr || pSelInf == nullptr) { qDebug() << "[Error] POU::registerInterface - but pInfItem or pSelInf is nullptr."; return; } QString strInfName = QString(pInfItem->m_infInfo->strFullName); m_itemToInterfaces.insert(pInfItem, pSelInf); m_fullNameToInterfaces.insert(strInfName, pSelInf); m_fullNameToInterfaceItems.insert(strInfName, pInfItem); // 输出接口信息 // debugAllInterface(); } /// /// 移除一个运行的Tool功能块 /// /// void POU::removeTool(QGraphicsItem* pBlockItem) { Q_UNUSED(pBlockItem); //for (QVector::iterator it = m_SelTools.begin();it != m_SelTools.end();) //{ // if (it->item == pRunningBlock) // { // it = m_SelTools.erase(it); // } // else // { // it++; // } //} #ifdef QT_NO_DEBUG #else // 输出调试信息 // debugAllTools(); #endif } /// /// 显示当前工具对话框 /// /// void POU::ShowToolDialog(WindowAppBlockStandardBase* pBlockItem) { m_itemToTools.value(pBlockItem)->pDllPtr->ShowDialog(); } DebugData POU::GetToolDebugData(WindowAppBlockStandardBase* pBlockItem) { if (m_itemToTools.value(pBlockItem) != nullptr && m_itemToTools.value(pBlockItem)->pDllPtr) { return m_itemToTools.value(pBlockItem)->pDllPtr->GetDebugData(); } DebugData data; return data; } /// /// 序号+1 /// /// void POU::ToolMoveDown(WindowAppBlockStandardBase* pBlockItem) { TOOL* pMovTool = m_itemToTools.value(pBlockItem); int nCurIndex = pMovTool->nIndex; // 如果只剩1个工具或者本身就是最后一个工具的话,则忽略这个操作 if (m_itemToTools.size() <= 1 || nCurIndex >= m_itemToTools.size() - 1) { return; } int nAjustIndex = nCurIndex + 1; // 交换一下邻接的工具序号 QHash::iterator iter = m_itemToTools.begin(); while (iter != m_itemToTools.end()) { if (iter.value()->nIndex == nAjustIndex) { iter.value()->nIndex--; break; } iter++; } // 修正自身序号 m_itemToTools.value(pBlockItem)->nIndex++; // 移动StandardToolList m_StandardTools.removeOne(pMovTool); m_StandardTools.insert(nAjustIndex, pMovTool); // 2022-3-6,检测功能块的变动是否需要向Task同步 this->syncToolMoveToTaskView(); } /// /// 序号-1 /// /// void POU::ToolMoveUp(WindowAppBlockStandardBase* pBlockItem) { TOOL* pMovTool = m_itemToTools.value(pBlockItem); int nCurIndex = pMovTool->nIndex; // 如果只剩1个工具或者本身就是第一个工具的话,则忽略这个操作 if (m_itemToTools.size() <= 1 || nCurIndex == 0) { return; } int nAjustIndex = nCurIndex - 1; // 交换一下邻接的工具序号 QHash::iterator iter = m_itemToTools.begin(); while (iter != m_itemToTools.end()) { if (iter.value()->nIndex == nAjustIndex) { iter.value()->nIndex++; break; } iter++; } // 修正自身序号 m_itemToTools.value(pBlockItem)->nIndex--; // 移动StandardToolList m_StandardTools.removeOne(pMovTool); m_StandardTools.insert(nAjustIndex, pMovTool); // 2022-3-6,检测功能块的变动是否需要向Task同步 this->syncToolMoveToTaskView(); } /// /// 执行顺序移动到最前端 /// /// void POU::ToolMoveFirst(WindowAppBlockStandardBase* pBlockItem) { TOOL* pMovTool = m_itemToTools.value(pBlockItem); int& nCurIndex = pMovTool->nIndex; // 所有工具序号后移 QHash::iterator iter = m_itemToTools.begin(); while (iter != m_itemToTools.end()) { if (iter.value()->nIndex < nCurIndex) { iter.value()->nIndex++; } iter++; } // 修正自身序号 nCurIndex = 0; // 移动StandardToolList m_StandardTools.removeOne(pMovTool); m_StandardTools.push_front(pMovTool); // 2022-3-6,检测功能块的变动是否需要向Task同步 this->syncToolMoveToTaskView(); } /// /// 执行顺序移动到最后端 /// /// void POU::ToolMoveLast(WindowAppBlockStandardBase* pBlockItem) { TOOL* pMovTool = m_itemToTools.value(pBlockItem); int nLastIndex = m_itemToTools.size() - 1; int& nCurIndex = pMovTool->nIndex; // 所有工具序号前移 QHash::iterator iter = m_itemToTools.begin(); while (iter != m_itemToTools.end()) { if (iter.value()->nIndex > nCurIndex) { iter.value()->nIndex--; } iter++; } // 修正自身序号 nCurIndex = nLastIndex; // 移动StandardTools m_StandardTools.removeOne(pMovTool); m_StandardTools.push_back(pMovTool); // 2022-3-6,检测功能块的变动是否需要向Task同步 this->syncToolMoveToTaskView(); } /// /// 复制功能块本身 /// /// void POU::ToolCopyBlock(WindowAppBlockStandardBase* pBlockItem) { TOOL* pActiveTool = m_itemToTools.value(pBlockItem); if (pActiveTool) { } } /// /// 复制功能块的数据 /// /// void POU::ToolCopyData(WindowAppBlockStandardBase* pBlockItem) { TOOL* pActiveTool = m_itemToTools.value(pBlockItem); if (pActiveTool) { m_BufferTemp.open(QIODevice::WriteOnly); QDataStream ar(&m_BufferTemp); ar << pActiveTool->strName; pActiveTool->pDllPtr->SerializedToDoc(ar); } } /// /// 粘贴数据 /// /// void POU::ToolPaste(WindowAppBlockStandardBase* pBlockItem) { TOOL* pActiveTool = m_itemToTools.value(pBlockItem); if (pActiveTool) { m_BufferTemp.open(QIODevice::ReadOnly); QDataStream ar(&m_BufferTemp); QString strName; ar >> strName; if (strName == pActiveTool->strName) { pActiveTool->pDllPtr->SerializedFromDoc(ar); } else { qWarning() << "Paste Error Data Source is" << strName; } m_BufferTemp.close(); } } /// /// 删除指定工具 /// /// void POU::ToolDelete(WindowAppBlockBase* pBlockItem) { //// 跳过注释工具 //if (pBlockItem->m_toolInfo->isCommentTool()) //{ // return; //} vDebug() << "Delete tool[" << pBlockItem->m_toolInfo->strInstanceName << "]."; // 如果是带序号的工具,需要先调整一下序号 if (pBlockItem->m_toolInfo->isIndexedTool()) { // 调整其他功能块的序号 int nCurIndex = m_itemToTools.value(pBlockItem)->nIndex; // 2021-8-14 移除StandardTools列表中的信息 m_StandardTools.removeOne(m_itemToTools.value(pBlockItem)); // 遍历所有的工具 QHash::iterator iter = m_itemToTools.begin(); while (iter != m_itemToTools.end()) { // 后面的序号前移 if (iter.value()->nIndex > nCurIndex) { iter.value()->nIndex--; } iter++; } // 回收工具的Dll资源(仅标准工具才有) if (m_itemToTools.value(pBlockItem)->pDllPtr != nullptr) { delete m_itemToTools.value(pBlockItem)->pDllPtr; m_itemToTools.value(pBlockItem)->pDllPtr = nullptr; } } // 先移除工具中的Interface信息 QVectorIterator<_INTERFACE*> it(m_itemToTools.value(pBlockItem)->Interfaces); while (it.hasNext()) { _INTERFACE* pInf = it.next(); m_itemToInterfaces.remove(m_fullNameToInterfaceItems.value(pInf->strFullName)); m_fullNameToInterfaces.remove(pInf->strFullName); m_fullNameToInterfaceItems.remove(pInf->strFullName); } // 如果删除的是硬件组态里的工具,需要清理绑定信息 if (pBlockItem->m_toolInfo->isHardwareTool()) { g_pGvlManager->unbindHdwToolAndDB(pBlockItem->m_toolInfo, pBlockItem->m_toolInfo->strHdwInstName); } // 移除此工具 m_itemToTools.remove(pBlockItem); m_instNameToTools.remove(pBlockItem->m_toolInfo->strInstanceName); m_instNameToToolItems.remove(pBlockItem->m_toolInfo->strInstanceName); // 工具的重命名计数减一 m_AutoToolRenameIndex[pBlockItem->m_toolInfo->strName] --; // 2022-9-4 加入,由于有Wait工具的存在,所以需要到TaskManager中反注册一下 if (pBlockItem->m_toolInfo->isWaitTool()) { g_pTaskManager->unregisterTool(pBlockItem->m_toolInfo); } //#ifdef QT_NO_DEBUG //#else // // 输出调试信息 // debugAllTools(); // debugAllInterface(); //#endif } /// /// 保存Link信息 /// /// /// void POU::makeLink( WindowAppItemInterface* srcInfItem, WindowAppItemInterface* dstInfItem, WindowAppItemLink* linkItem, LINK_MODE linkMode ) { // 起始接口 _INTERFACE* srcInf = m_itemToInterfaces.value(srcInfItem); if (srcInf == nullptr) { qDebug() << "[POU][LINK] Make link Error: startInf is nullptr."; return; } // 终止接口 _INTERFACE* dstInf = m_itemToInterfaces.value(dstInfItem); if (dstInf == nullptr) { qDebug() << "[POU][LINK] Make link Error: endInf is nullptr."; return; } // 建立Link dstInf->pUpLinkInterface = srcInf; srcInf->pDownLinkInterfaces.push_back(dstInf); // 引用计数 + 1 srcInf->nRefCount++; dstInf->nRefCount++; // 2022-8-28去掉,改为运行时实时判定 //// 2022-5-4增加,如果是Parallel模式连接,则还需要把被连接的Tool设置为并行模式 //if (linkMode == LINK_MODE::LINK_PARALLEL) //{ // dstInf->parent()->bParallelized = true; //} // 2022-6-12增加,保存本Link信息用于统一管理 this->registerLink(srcInfItem, dstInfItem, linkItem, linkMode); //// 2022-9-5增加,此处需要在链接的时候直接启动并行子工具线程(并行工具的新启动机制) //this->addParallelSubTool(dstInfItem->m_infInfo->parent()); qDebug() << "[POU][LINK] Make link: " << srcInf->parent()->strInstanceName << "-" << srcInf->strName << " --> " << dstInf->parent()->strInstanceName << "-" << dstInf->strName; } /// /// 清除Link信息 /// /// void POU::removeLink(WindowAppItemInterface* endInfItem) { // 从上联接口中移除其下联接口信息 QVector<_INTERFACE*>& pDownInterfaces = m_itemToInterfaces.value(endInfItem)->pUpLinkInterface->pDownLinkInterfaces; for (QVector<_INTERFACE*>::iterator it = pDownInterfaces.begin(); it != pDownInterfaces.end();) { if (*it == m_itemToInterfaces.value(endInfItem)) { //// 2022-5-6,移除被连接Tool的并行模式标志(删除并行link等于移出了并行组) //if ((*it)->parent()->bParallelized) //{ // (*it)->parent()->bParallelized = false; //} it = pDownInterfaces.erase(it); } else { it++; } } // 移除对应接口的上行连接信息 m_itemToInterfaces.value(endInfItem)->pUpLinkInterface = nullptr; // 2022-6-13 增加,移除Link的注册信息 this->unregisterLink(endInfItem); } /// /// 注册新的Link信息 /// /// /// /// void POU::registerLink( WindowAppItemInterface* startInfItem, WindowAppItemInterface* endInfItem, WindowAppItemLink* linkItem, LINK_MODE linkMode ) { LINK newLink; newLink.linkMode = linkMode; newLink.pSrcItem = startInfItem; newLink.pDstItem = endInfItem; newLink.pLinkItem = linkItem; m_Links.push_back(newLink); qDebug() << "POU::registerLink - Inf[" << endInfItem->m_infInfo->strFullName << "]"; } /// /// 反注册Link信息 /// /// /// void POU::unregisterLink(WindowAppItemInterface* endInfItem) { for (auto it = m_Links.begin(); it != m_Links.end();) { if (it->pDstItem == endInfItem) { it = m_Links.erase(it); qDebug() << "POU::unregisterLink - Inf[" << endInfItem->m_infInfo->strFullName << "]"; break; } else { ++it; } } } /// /// 将指定接口绑定到指定Port中 /// /// /// void POU::bindPortAndInterface(WindowAppBlockBase* pPortItem, _INTERFACE* pBindInf, const QString& strInfName) { // 2021-6-6 增加,被绑定接口的引用计数需要 + 1 pBindInf->nRefCount++; _INTERFACE* pPortInf = m_itemToTools.value(pPortItem)->Interfaces[0]; // 将绑定接口的信息复制过来 pPortInf->strName = strInfName; // TODO:此处这个全名是有问题的,接口名字必须全局唯一,但是这里重复了,strFullName暂时不改了 // pPortInf->strFullName = pBindInf->strFullName; pPortInf->strComment = pBindInf->strComment; pPortInf->bSerialized = pBindInf->bSerialized; // 2021-5-24 修正,由于GVl变量是双向的,此处需要强制设置为和Port方向一致 // pPortInf->InfDirection = pBindInf->InfDirection; pPortInf->Type = pBindInf->Type; // 指针直接复制,这样值就可以双方同步了 pPortInf->value = pBindInf->value; pPortInf->nIndex = pBindInf->nIndex; pPortInf->strNameWithType= pBindInf->strNameWithType; //// 2021-6-12 修正port绑定接口的时候造成的崩溃bug //// 修改连父工具指针一起复制过去 //pPortInf->pParentTool = pBindInf->pParentTool; // 这三个属性是否需要复制待定 //pPortInf->bShow = pBindInf->bShow; //pPortInf->bWatch = pBindInf->bWatch; // 2021-6-5增加,直接复制link信息,并且整理旧接口相关的link关系 // For test //pPortInf->setValue(50); //g_pVariablesManager->debugVariable(pPortInf); //g_pVariablesManager->debugVariable(m_ItemPorts[pPortItem]->Interface); //g_pVariablesManager->debugAllVariables(); qDebug() << "[POU][PORT]: bind " << pPortInf->strName << " to port."; } /// /// 获取指定Item的绝对坐标 /// /// /// QPointF POU::GetToolItemPos(QString strKey) { return m_instNameToToolItems.value(strKey)->scenePos(); } /// /// 2022-3-12,删除指定的接口相关数据结构 /// /// /// void POU::DelInterface(const QString& strFullName, WindowAppItemInterface* pItem, _INTERFACE* pInf) { Q_UNUSED(pInf); m_fullNameToInterfaces.remove(strFullName); m_itemToInterfaces.remove(pItem); m_fullNameToInterfaceItems.remove(strFullName); } /// /// 根据接口中对应的Dll数值获取接口指针(UIManager中使用) /// /// /// _INTERFACE* POU::GetInterfaceByValuePtr(void* pValue) { QMapIterator iter(m_fullNameToInterfaces); while (iter.hasNext()) { _INTERFACE* pInf = iter.next().value(); // 2022-5-18 增加,由于每个Tool多了一个ToolStart接口,所以这里要把ToolStart接口过滤掉,否则会崩溃 if(pInf->nIndex<0) { continue; } void** pValuePtr = pInf->getValuePtr(); if (pValuePtr == pValue) { return pInf; } } return nullptr; } /// /// 重命名计数 + 1 /// /// void POU::AddRenameRefCount(const QString& strName) { m_AutoToolRenameIndex[strName]++; } /// /// 获取所有的Event类型接口(如果有) /// /// QMap POU::getAllEvents() { QMap m_Events; QMapIterator iter(m_fullNameToInterfaces); while (iter.hasNext()) { if (iter.next().value()->Type==INF_TYPE::INF_TYPE_EVENT //&& iter.value()->eventTrigger !=nullptr ) { m_Events.insert(iter.key(), iter.value()); } } return m_Events; } /// /// 生成工具新的实例名字 /// /// /// QString POU::genToolInstanceName(const QString& strToolName) { // 根据引用计数生成工具的实例名字 int nRefCount = m_AutoToolRenameIndex.value(strToolName) + 1; return QString(strToolName + " " + QString::number(nRefCount)); } /// /// 设置工具的启用禁用 /// /// /// void POU::setToolEnable(const TOOL* pToolInfo, bool bEnable) { m_instNameToTools.value(pToolInfo->strInstanceName)->bEnable = bEnable; } /// /// 设置接口的启用禁用 /// /// /// bool POU::setInterfaceEnable(const _INTERFACE* pInfInfo, bool bEnable) { // 需要参考引用计数,如果计数错误则不允许切换 if (pInfInfo->nRefCount > 0) { return false; } m_fullNameToInterfaces.value(pInfInfo->strFullName)->bEnable = bEnable; return true; } /// /// 设置接口的启用禁用(根据接口序号设置) /// /// /// /// bool POU::setInterfaceEnable(const TOOL* pToolInfo, int nInfIndex, bool bEnable) { _INTERFACE* pInf = m_instNameToTools.value(pToolInfo->strInstanceName)->Interfaces[nInfIndex]; // 需要参考引用计数,如果计数错误则不允许切换 if (pInf->nRefCount > 0) { return false; } pInf->bEnable = bEnable; return true; } /// /// 更新工具的Info /// /// /// void POU::setToolInfo(const TOOL* pToolInfo, const QString& strInfo) { m_instNameToTools.value(pToolInfo->strInstanceName)->strInfo = strInfo; } /// /// 设置工具的延时参数 /// /// /// void POU::setToolDelay(const TOOL* pToolInfo, const int inDelay, const int outDelay) { m_instNameToTools.value(pToolInfo->strInstanceName)->execParams.nPreDelay = inDelay; m_instNameToTools.value(pToolInfo->strInstanceName)->execParams.nPostDelay = outDelay; } /// /// 设置工具的实例名称 /// /// void POU::setInstanceName(const TOOL* pToolInfo, const QString& strNewInsName, const QString& strOldInsName) { Q_UNUSED(pToolInfo); // 保留一下旧数据 TOOL* tool = m_instNameToTools.value(strOldInsName); WindowAppBlockBase* pItem = m_instNameToToolItems[strOldInsName]; // 更名,设置别名 m_instNameToTools.value(strOldInsName)->strAliasName = strOldInsName; m_instNameToTools.value(strOldInsName)->strInstanceName = strNewInsName; // 删掉旧的数据 m_instNameToTools.remove(strOldInsName); m_instNameToToolItems.remove(strOldInsName); // 添加新的数据,保持key一致 m_instNameToTools.insert(strNewInsName, tool); m_instNameToToolItems.insert(strNewInsName, pItem); // 设置新的实例化名称到工具 if (tool->pDllPtr) { tool->pDllPtr->ModToolInstanceName(strNewInsName); } } /// /// 检查工具的实例名称是否重复(用于在Dialog对话框中判断用户是否可以重命名工具) /// /// /// bool POU::isInstanceNameDuplicated(const QString& strInsName) { QMap::iterator it = m_instNameToTools.find(strInsName); if (it != m_instNameToTools.end()) { return true; } return false; } /// /// 查询可执行SmartLink的接口(找离本接口最近的同类型输出端口,序号小于自己的,当然不一定能够找到) /// /// /// WindowAppItemInterface* POU::getSmartLinkInterface(const WindowAppItemInterface* pInf) { // 查询序号小于本接口的工具 TOOL* pTool = pInf->m_infInfo->parent(); QHash::const_iterator it; int nCount = m_itemToTools.size(); for (int i = 0; i < nCount; i++) { int nTargetIndex = pTool->nIndex - i - 1; if (nTargetIndex < 0) { return nullptr; } it = m_itemToTools.constBegin(); // 遍历所有工具 for (; it != m_itemToTools.constEnd(); ++it) { // qDebug() << i.key() << ":" << i.value(); // 找到对应的序号 if (it.value()->nIndex == nTargetIndex) { // 查找是否有符合的工具 TOOL* pLinkTool = it.value(); for (int m = 0; m < pLinkTool->Interfaces.size(); m++) { _INTERFACE* pLinkInf = pLinkTool->Interfaces[m]; // 方向为输出并且类型相同的接口,并且接口处于可用状态 if (pLinkInf->Direction == INF_DIRECTION::INF_DIR_OUT && pLinkInf->isSameTypeTo(pInf->m_infInfo) && pLinkInf->bEnable) { // return pLinkTool->Interfaces[m]; return m_fullNameToInterfaceItems.value(pLinkInf->strFullName); } } // 如果没有找到,则跳出循环,继续查找下一个序号 break; } } } return nullptr; } /// /// 完成Pou的初始化动作 /// /// void POU::init(const QString& strName, WindowAppPouScene* pScene) { this->m_strPouName = strName; this->m_parentScene = pScene; // 初始化本Pou内部变量 this->initPouInternalVariables(); // 绑定本Pou的内部变量 this->bindPouInternalVariables(); } /// /// 是否被Task选中 /// /// bool POU::isSelByTask() { return (this->m_pParentTask != nullptr); } /// /// 是否在Task中运行 /// /// bool POU::isRunningInTask() { return (this->m_pParentTask != nullptr && m_pParentTask->isRunning()); } /// /// 2021-9-15 增加,查找本Pou中指定类型的接口(用于设计界面中的数据链接用) /// /// /// bool POU::containInterface(VALUE_TYPE type, INF_DIRECTION dir) { // 遍历本Pou中所有Tool的所有Interface,查找是否有对应的类型 QMapIterator it(m_fullNameToInterfaces); while (it.hasNext()) { if (it.next().value()->value.type == type && it.value()->Direction == dir ) { return true; } } return false; } /// /// 2022-6-21 增加,获取两个Block之间的所有LinkItem(用于进行批量移动) /// /// /// /// QList POU::getLinkItemsBetweenBlocks(WindowAppBlockBase* srcBlock, WindowAppBlockBase* dstBlock) { QList linkItemList; // 遍历终点功能块的所有输入接口 for (const auto& infItem : dstBlock->m_itemInterfaces) { // 输入接口 if (infItem->m_infInfo->isDirInput()) { // 首先找到这个输入接口对应的LinkItem的序号 int nLinkIndex = this->getLinkIndexByDstInfItem(infItem); // 如果没有则说明这个接口没有Link,继续查找下一个 if (nLinkIndex < 0) { continue; } // 如果找到了Link,那么判断这个Link是否是属于srcBlock的 WindowAppItemInterface* srcInfItem = m_Links[nLinkIndex].pSrcItem; bool bInBlock = srcBlock->isInBlock(srcInfItem); // 如果这个Item是属于这个Block,则将此两个接口间的LinkItem保存下来 if (bInBlock) { linkItemList.push_back(m_Links[nLinkIndex].pLinkItem); } } } return linkItemList; } /// /// 2022-6-21 获取指定接口Item的LinkItem序号 /// /// /// int POU::getLinkIndexByDstInfItem(WindowAppItemInterface* dstItem) { for (int i = 0; i < m_Links.size(); i++) { if (m_Links[i].pDstItem == dstItem) { return i; } } return -1; } /// /// 2022-2-15 增加Pou内部变量(仅用于统计,不显示、不序列化) /// NOTICE:由于不参与序列化,所以每次反序列化完毕之后都需要手工重新创建一下内部变量 /// void POU::initPouInternalVariables() { int nIndex = g_pGvlManager->getVariablesCountByGroup(m_strPouName); // 执行总时长(ms) VARIABLE* pNewVariable = new VARIABLE( m_strPouName, false, INTERNALVAR_NAME_EXECTIME, "int", "0", INTERNALVAR_CHNAME_EXECTIME, nIndex, false // 内部变量标识 ); // 数据结构中添加本变量信息 g_pGvlManager->addNewVariable( m_strPouName, pNewVariable ); // 执行次数 pNewVariable = new VARIABLE( m_strPouName, false, INTERNALVAR_NAME_EXECCOUNT, "int", "0", INTERNALVAR_CHNAME_EXECCOUNT, nIndex + 1, false ); // 数据结构中添加本变量信息 g_pGvlManager->addNewVariable( m_strPouName, pNewVariable ); // 错误次数 pNewVariable = new VARIABLE( m_strPouName, false, INTERNALVAR_NAME_ERRORCOUNT, "int", "0", INTERNALVAR_CHNAME_ERRORCOUNT, nIndex + 2, false ); // 数据结构中添加本变量信息 g_pGvlManager->addNewVariable( m_strPouName, pNewVariable ); } /// W /// 2022-2-16 绑定Pou内部变量和EXEC_PARAMS数据结构 /// 为了防止大幅度改动数据结构,将内部变量与EXEC_PARAMS做绑定 /// void POU::bindPouInternalVariables() { VARIABLE* pVar = g_pGvlManager->getVariableByName(m_strPouName, INTERNALVAR_NAME_EXECTIME); pVar->value.setValueByAddress((void**)&this->execParams.nExecTime); pVar = g_pGvlManager->getVariableByName(m_strPouName, INTERNALVAR_NAME_EXECCOUNT); pVar->value.setValueByAddress((void**)&this->execParams.nExecCount); pVar = g_pGvlManager->getVariableByName(m_strPouName, INTERNALVAR_NAME_ERRORCOUNT); pVar->value.setValueByAddress((void**)&this->execParams.nErrorCount); } /// /// 2022-3-6,检测功能块的变动是否需要向Task同步 /// void POU::syncToolMoveToTaskView() { if (this->isSelByTask()) { WindowAppTaskView* pTaskView = g_pTaskManager->getTaskViewByName(this->m_pParentTask->strName); pTaskView->onMovePouTool(this); } } /// /// 输出所有工具相关的数据结构 /// void POU::debugAllTools() { qDebug() << "QMap m_AllTools - size : " << m_instNameToTools.size(); QMapIterator it1(m_instNameToTools); while (it1.hasNext()) { it1.next(); qDebug() << it1.key() << " - with " << it1.value()->Interfaces.size() << " interfaces"; } qDebug() << "QHash m_ItemTools - size : " << m_itemToTools.size(); QHashIterator it2(m_itemToTools); while (it2.hasNext()) { it2.next(); qDebug() << it2.key()->m_toolInfo->strInstanceName << " - " << it2.value(); } qDebug() << "QHash m_ToolItems - size : " << m_instNameToToolItems.size(); QMapIterator it3(m_instNameToToolItems); while (it3.hasNext()) { it3.next(); qDebug() << it3.key(); } } /// /// 输出所有接口相关的数据结构 /// void POU::debugAllInterface() { qDebug() << "QString, _INTERFACE* - size : " << m_fullNameToInterfaces.size(); QMapIterator it1(m_fullNameToInterfaces); while (it1.hasNext()) { it1.next(); qDebug() << it1.key() << " - " << it1.value(); } qDebug() << "QHash m_ItemInterfaces - size : " << m_itemToInterfaces.size(); QHashIterator it2(m_itemToInterfaces); while (it2.hasNext()) { it2.next(); qDebug() << it2.key()->m_infInfo->strFullName << " - " << it2.value(); } qDebug() << "QHash m_InterfaceItems - size : " << m_fullNameToInterfaceItems.size(); QMapIterator it3(m_fullNameToInterfaceItems); while (it3.hasNext()) { qDebug() << it3.next().key(); } } ///// ///// 输出所有引用计数的相关数据结构 ///// //void PouManager::debugAllRefCounter() //{ // QHashIterator i(m_ItemReferenceCounter); // while (i.hasNext()) // { // qDebug() << i.next().key() << ":" << i.value(); // } // // //QHash::const_iterator i; // //for (i = m_ItemReferenceCounter.constBegin(); i != m_ItemReferenceCounter.constEnd(); ++i) // //{ // // qDebug() << i.key() << ":" << i.value(); // //} //}