#pragma once #include "Common.h" #include "CommonDraw.h" class WindowAppItemLink; class WindowAppPouScene; class WindowAppItemInterface; class WindowAppBlockPort; class WindowAppBlockStandard; class WindowAppBlockStandardBase; class WindowAppBlockComment; class WindowAppBlockBase; class Document; class TASK; /// /// Parallel Tool 的执行线程体 /// class _ParallelThread : public QRunnable { public: _ParallelThread(POU* pPou, TOOL* pRunningTool) { this->m_pPou = pPou; this->m_pParallelSubTool = pRunningTool; }; ~_ParallelThread() {}; protected: // 线程函数 virtual void run(); //signals: // // // 传递线程参数(暂未使用) // void sigThreadParams(); private: // 所在的Pou指针 POU* m_pPou; // 并行子工具的指针 TOOL* m_pParallelSubTool; // 互斥量,用于模拟线程的休眠 QMutex m_mutex; }; /// /// 用于存储Link信息的类 /// typedef struct _tagLink { // 运行使用 WindowAppItemInterface* pSrcItem; // Link中起始接口的Item WindowAppItemInterface* pDstItem; // Link中目的接口的Item WindowAppItemLink* pLinkItem; // 本Link对应的LinkItem LINK_MODE linkMode; // 连接模式 _tagLink() { linkMode = LINK_MODE::LINK_NORMAL; pLinkItem = nullptr; pSrcItem = nullptr; pDstItem = nullptr; } } LINK; /// /// 核心类,管理Pou界面中的Tool数据结构 /// class POU { public: POU(); ~POU(); // 完成Pou的初始化动作 void init(const QString& strName, WindowAppPouScene* pScene); // 重置本Pou中所有的数据结构 void reset(); // 注册一个运行的功能块信息到当前Pou中 void registerTool(WindowAppBlockBase* pBlockItem, TOOL* pSelTool); // 注册一个运行的接口信息到当前Pou中 void registerInterface(WindowAppItemInterface* pInfItem, _INTERFACE* pSelInf); // 移除一个运行的Tool功能块 void removeTool(QGraphicsItem* pBlockItem); // 显示当前工具对话框 void ShowToolDialog(WindowAppBlockStandardBase* pBlockItem); // 获取当前DebugData DebugData GetToolDebugData(WindowAppBlockStandardBase* pBlockItem); // 执行当前工具 VPEnum::RETURN_VALUE ToolExecuteStandard(TOOL* pActiveTool); //// 执行当前工具 //VPEnum::RETURN_VALUE ToolExecuteStandard(WindowAppBlockStandardBase* pBlockItem); // 从当前位置执行 void ToolExecuteSub(WindowAppBlockStandardBase* pBlockItem); // 全部按顺序执行 void ToolExecuteAll(const int startIndex = 0); // 单步执行 void ToolExecuteSingleStep(); // Execute前更新上连接口 VPEnum::RETURN_VALUE ToolPreExecute(TOOL* pActiveTool); // Execute后更新下连接口 VPEnum::RETURN_VALUE ToolPostExecute(TOOL* pActiveTool); void ToolBreakPoint(WindowAppBlockStandardBase* pBlockItem); // 调整工具的序号 void ToolMoveDown(WindowAppBlockStandardBase* pBlockItem); void ToolMoveUp(WindowAppBlockStandardBase* pBlockItem); void ToolMoveFirst(WindowAppBlockStandardBase* pBlockItem); void ToolMoveLast(WindowAppBlockStandardBase* pBlockItem); // 功能块复制粘贴 void ToolCopyBlock(WindowAppBlockStandardBase* pBlockItem); void ToolCopyData(WindowAppBlockStandardBase* pBlockItem); void ToolPaste(WindowAppBlockStandardBase* pBlockItem); // 删除工具 void ToolDelete(WindowAppBlockBase* pBlockItem); // 建立Link void makeLink( WindowAppItemInterface* srcInfItem, WindowAppItemInterface* dstInfItem, WindowAppItemLink* linkItem, LINK_MODE linkMode = LINK_MODE::LINK_NORMAL ); // 清除Link信息 void removeLink(WindowAppItemInterface* endInfItem); // 获取全部的Link信息 const QVector& getAllLinks() { return m_Links; } // 注册新的Link信息 void registerLink( WindowAppItemInterface* startInfItem, WindowAppItemInterface* endInfItem, WindowAppItemLink* linkItem, LINK_MODE linkMode); // 反注册Link信息 void unregisterLink(WindowAppItemInterface* endInfItem); // 重置所有工具执行状态 void ResetToolExecCode(); // 将指定接口绑定到指定Port中 void bindPortAndInterface(WindowAppBlockBase* pPortItem, _INTERFACE* pBindInf, const QString& strInfName); // 根据对应的Item指针获取对应的Tool TOOL* GetToolByName(WindowAppBlockBase* pItem) { return m_itemToTools.value(pItem); } // 根据对应的InstanceName获取对应的Tool TOOL* GetToolByName(QString strInstName) { return m_instNameToTools.value(strInstName); } // 根据对应的InstanceName获取对应的Tool Item WindowAppBlockBase* GetToolItem(QString strInstName) { return m_instNameToToolItems.value(strInstName); } // 获取指定Item的绝对坐标 QPointF GetToolItemPos(QString strKey); // 根据对应的Tool信息找到对应的Tool Item WindowAppBlockBase* GetToolItem(const TOOL* pTool) { return m_instNameToToolItems.value(pTool->strInstanceName); } // 根据对应的Item指针获取对应的Interface _INTERFACE* GetInterface(WindowAppItemInterface* pItem) { return m_itemToInterfaces.value(pItem); } // 根据对应的名字获取对应的Interface(toolinstancename.infname的形式) _INTERFACE* GetInterface(const QString& strFullName) { return m_fullNameToInterfaces.value(strFullName); } // 2022-3-12,删除指定的接口相关数据结构 void DelInterface(const QString& strFullName, WindowAppItemInterface* pItem, _INTERFACE* pInf); // 根据接口中对应的Dll数值获取接口指针(UIManager中使用) _INTERFACE* GetInterfaceByValuePtr(void* pValue); // 根据对应的名字获取对应的Interface Item(toolinstancename.infname的形式) WindowAppItemInterface* GetInterfaceItemByName(QString strFullName) const { return m_fullNameToInterfaceItems.value(strFullName); } // 获取当前运行的所有工具数量 int GetAllToolsCount() { return m_itemToTools.size(); } // 获取当前标准工具的数量(包括了Parallel、Goto、ForLoop以及StandardTools) int GetStandardToolsCount() { return this->m_StandardTools.size(); } // 获取当前索引序号的工具的数量(目前等同于GetStandardToolsCount(),但是后面会分开) int GetIndexedToolsCount() { return this->m_StandardTools.size(); } // 获取当前在运行的所有工具 const QMap GetAllTools() const { return m_instNameToTools; } // 获取当前运行的所有标准工具 const QVector& GetAllStandardTools() const { return m_StandardTools; } //// 2022-3-29,按执行顺序获取当前所有工具 //const QList GetOrderedStandardTools() const; //// 2022-3- // 获取当前在运行的所有接口 const QMap GetAllInterfaces() const { return m_fullNameToInterfaces; } // 获取所有的Event类型接口(如果有) QMap getAllEvents(); // 生成工具新的实例名字 QString genToolInstanceName(const QString& strToolName); // 更新工具的各个参数信息 // 设置工具的启用禁用 void setToolEnable(const TOOL* pToolInfo, bool bEnable); // 设置接口的启用禁用 bool setInterfaceEnable(const _INTERFACE* pInfInfo, bool bEnable); bool setInterfaceEnable(const TOOL* pToolInfo, int nInfIndex, bool bEnable); // 更新工具的Info void setToolInfo(const TOOL* pToolInfo, const QString& strInfo); // 设置工具的延时参数 void setToolDelay(const TOOL* pToolInfo, const int inDelay, const int outDelay); // 设置工具的实例名称 void setInstanceName(const TOOL* pToolInfo, const QString& strNewInsName, const QString& strOldInsName); // 检查工具的实例名称是否重复(用于在Dialog对话框中判断用户是否可以重命名工具) bool isInstanceNameDuplicated(const QString& strInsName); // 查询可执行SmartLink的接口 WindowAppItemInterface* getSmartLinkInterface(const WindowAppItemInterface* pInf); // 获取本Pou的名字 const QString pouName() const { return m_strPouName; } // 获取本Pou所在的Scene指针 WindowAppPouScene* parentScene() { return m_parentScene; } //// 是否处于执行状态(被Task选中,并加载执行) //bool isRunning(); // 是否被Task选中 bool isSelByTask(); // 是否在Task中运行 bool isRunningInTask(); // 2021-9-15 增加,查找本Pou中指定类型的接口(用于设计界面中的数据链接用) bool containInterface(VALUE_TYPE type, INF_DIRECTION dir = INF_DIRECTION::INF_DIR_OUT); // 更新接口的值(根据不同的模式,返回更新值的字符串形式) QString updateInterfaceValue(_INTERFACE* pInf, UPDATE_VALUE_MODE mode); // 2022-6-21 增加,获取两个Block之间的所有LinkItem(用于进行批量移动) QList getLinkItemsBetweenBlocks(WindowAppBlockBase* srcBlock, WindowAppBlockBase* dstBlock); // 2022-6-21 获取指定接口Item的LinkItem序号 int getLinkIndexByDstInfItem(WindowAppItemInterface* dstItem); //// 是否可以从Task列表中删除(Task尚未处于运行状态) //bool couldBeDeletedFromTask(); //// 2022-3-29 执行内部工具 //VPEnum::RETURN_VALUE ExecuteInternal(TOOL* pActiveTool); // 2022-3-29 执行Goto工具(TODO:应该为内部工具专门设计一套数据结构,暂时先放在这里) VPEnum::RETURN_VALUE ToolExecuteGoto(TOOL* pTool, int& index); // 2022-4-30 执行Parallel工具 VPEnum::RETURN_VALUE ToolExecuteParallel(TOOL* pTool); // 2022-8-25 执行ForLoop工具 VPEnum::RETURN_VALUE ToolExecuteForloop(TOOL* pTool); // 2022-9-3 执行Wait工具 VPEnum::RETURN_VALUE ToolExecuteWait(TOOL* pTool, TOOL_RUN_MODE runMode); // 2022-5-1 工具的执行总调度 VPEnum::RETURN_VALUE ToolExecutionDispatcher(TOOL*& pTool, TOOL_RUN_MODE runMode); // 2022-5-1 工具的执行总调度(Task中使用,关联执行序号) VPEnum::RETURN_VALUE ToolExecutionDispatcher(TOOL*& pTool, int& index, TOOL_RUN_MODE runMode); // 2022-9-6,执行前预检查 VPEnum::RETURN_VALUE ToolExecutionDispatcherPreCheck(TOOL*& pTool, TOOL_RUN_MODE runMode); // 2022-9-25,查询WaitTool的等待Value(用于在TaskManager触发WaitTool执行的时候进行判断) VALUE* getWaitToolValue(TOOL* pTool); public: friend Document; // 本Pou运行时的参数和状态 EXEC_PARAMS execParams; // 本Pou执行时所在的Task const TASK* m_pParentTask = nullptr; protected: // 从Dll获取接口的值 template T& GetDllInfValue(_INTERFACE* pInf); // 设置Dll中接口的值 template void SetDllInfValue(T& tValue, _INTERFACE* pInf); // 重命名计数 + 1 void AddRenameRefCount(const QString& strName); //// 刷新StandardTools列表 //void updateStandardToolsList(TOOL* pNewTool); // MoveValue template void MoveValue(T& tValue, _INTERFACE* pInf, UPDATE_VALUE_MODE mode); // 2021-8-24 将基础数据类型转换后,再执行操作 template void MoveValueByConverter(T& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf); // 根据其他需要特殊的类型做模板的特化(为了实现自动接口数值类型转换) void MoveValueByConverter(QString& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf); void MoveValueByConverter(int& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf); void MoveValueByConverter(float& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf); void MoveValueByConverter(double& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf); void MoveValueByConverter(bool& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf); // 2021-11-9 向UI同步接口数值 void syncValuesToUi(QList<_INTERFACE*> pInfs); // 2021-11-14 向变量表界面同步数值 void syncValuesToTableUI(QList pInfs); // 2021-12-15 向Runtime推送索引数值的变动 void syncComplexIndexesToRuntime(QList pIndexes); // 用于调试的函数 // 输出所有工具相关的数据结构 void debugAllTools(); // 输出所有接口相关的数据结构 void debugAllInterface(); //// 输出所有引用计数的相关数据结构 //void debugAllRefCounter(); // 2022-2-15 增加Pou内部变量(仅用于统计,不显示、不序列化) void initPouInternalVariables(); // 2022-2-16 绑定Pou内部变量和EXEC_PARAMS数据结构 void bindPouInternalVariables(); // 2022-3-6,检测功能块的变动是否需要向Task同步 void syncToolMoveToTaskView(); // 排序(用于在Pou中保持执行队列按index有序) static bool sort_by_index(const TOOL* t1, const TOOL* t2) { return t1->nIndex < t2->nIndex; } private: // 本Pou的名称 QString m_strPouName; // 界面中正在运行的工具信息(Name Map对,自动排序)` QMap m_instNameToTools; // 界面中正在运行的所有接口信息(FullName Map对,自动排序) QMap m_fullNameToInterfaces; // 界面中正在运行的工具信息(QGraphicsItem Hash对) QHash m_itemToTools; // 界面中正在运行的所有接口信息(QGraphicsItem Hash对) QHash m_itemToInterfaces; // 界面中正在运行的工具信息(Name - Item Hash对) QMap m_instNameToToolItems; // 界面中正在运行的所有接口信息(FullName - Item Hash对) QMap m_fullNameToInterfaceItems; //// 每种运行工具的引用计数 //QHash m_ItemReferenceCounter; // 每种工具的重命名Index QMap m_AutoToolRenameIndex; // 2021-8-14增加,为了提高TaskManager中的Tool执行效率,专门建立此数据结构 // 用于按执行顺序存储该Pou所有的标准工具 QVector m_StandardTools; //用于临时数据的buffer QBuffer m_BufferTemp; // 单步执行的序号 int m_nExecuteIndex; // 2022-4-30, 用于执行并行任务的线程池 QThreadPool m_ParallelThreadPool; // 2022-6-12,用于存储本Pou中所有的Link信息,此后Link信息由Pou类统一管理(主要用于Link信息的序列化与反序列化) QVector m_Links; // 所属的Scene指针 WindowAppPouScene* m_parentScene; };