Pou.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. #pragma once
  2. #include "Common.h"
  3. #include "CommonDraw.h"
  4. class WindowAppItemLink;
  5. class WindowAppPouScene;
  6. class WindowAppItemInterface;
  7. class WindowAppBlockPort;
  8. class WindowAppBlockStandard;
  9. class WindowAppBlockStandardBase;
  10. class WindowAppBlockComment;
  11. class WindowAppBlockBase;
  12. class Document;
  13. class TASK;
  14. /// <summary>
  15. /// Parallel Tool 的执行线程体
  16. /// </summary>
  17. class _ParallelThread : public QRunnable
  18. {
  19. public:
  20. _ParallelThread(POU* pPou, TOOL* pRunningTool)
  21. {
  22. this->m_pPou = pPou;
  23. this->m_pParallelSubTool = pRunningTool;
  24. };
  25. ~_ParallelThread() {};
  26. protected:
  27. // 线程函数
  28. virtual void run();
  29. //signals:
  30. //
  31. // // 传递线程参数(暂未使用)
  32. // void sigThreadParams();
  33. private:
  34. // 所在的Pou指针
  35. POU* m_pPou;
  36. // 并行子工具的指针
  37. TOOL* m_pParallelSubTool;
  38. // 互斥量,用于模拟线程的休眠
  39. QMutex m_mutex;
  40. };
  41. /// <summary>
  42. /// 用于存储Link信息的类
  43. /// </summary>
  44. typedef struct _tagLink
  45. {
  46. // 运行使用
  47. WindowAppItemInterface* pSrcItem; // Link中起始接口的Item
  48. WindowAppItemInterface* pDstItem; // Link中目的接口的Item
  49. WindowAppItemLink* pLinkItem; // 本Link对应的LinkItem
  50. LINK_MODE linkMode; // 连接模式
  51. _tagLink()
  52. {
  53. linkMode = LINK_MODE::LINK_NORMAL;
  54. pLinkItem = nullptr;
  55. pSrcItem = nullptr;
  56. pDstItem = nullptr;
  57. }
  58. } LINK;
  59. /// <summary>
  60. /// 核心类,管理Pou界面中的Tool数据结构
  61. /// </summary>
  62. class POU
  63. {
  64. public:
  65. POU();
  66. ~POU();
  67. // 完成Pou的初始化动作
  68. void init(const QString& strName, WindowAppPouScene* pScene);
  69. // 重置本Pou中所有的数据结构
  70. void reset();
  71. // 注册一个运行的功能块信息到当前Pou中
  72. void registerTool(WindowAppBlockBase* pBlockItem, TOOL* pSelTool);
  73. // 注册一个运行的接口信息到当前Pou中
  74. void registerInterface(WindowAppItemInterface* pInfItem, _INTERFACE* pSelInf);
  75. // 移除一个运行的Tool功能块
  76. void removeTool(QGraphicsItem* pBlockItem);
  77. // 显示当前工具对话框
  78. void ShowToolDialog(WindowAppBlockStandardBase* pBlockItem);
  79. // 获取当前DebugData
  80. DebugData GetToolDebugData(WindowAppBlockStandardBase* pBlockItem);
  81. // 执行当前工具
  82. VPEnum::RETURN_VALUE ToolExecuteStandard(TOOL* pActiveTool);
  83. //// 执行当前工具
  84. //VPEnum::RETURN_VALUE ToolExecuteStandard(WindowAppBlockStandardBase* pBlockItem);
  85. // 从当前位置执行
  86. void ToolExecuteSub(WindowAppBlockStandardBase* pBlockItem);
  87. // 全部按顺序执行
  88. void ToolExecuteAll(const int startIndex = 0);
  89. // 单步执行
  90. void ToolExecuteSingleStep();
  91. // Execute前更新上连接口
  92. VPEnum::RETURN_VALUE ToolPreExecute(TOOL* pActiveTool);
  93. // Execute后更新下连接口
  94. VPEnum::RETURN_VALUE ToolPostExecute(TOOL* pActiveTool);
  95. void ToolBreakPoint(WindowAppBlockStandardBase* pBlockItem);
  96. // 调整工具的序号
  97. void ToolMoveDown(WindowAppBlockStandardBase* pBlockItem);
  98. void ToolMoveUp(WindowAppBlockStandardBase* pBlockItem);
  99. void ToolMoveFirst(WindowAppBlockStandardBase* pBlockItem);
  100. void ToolMoveLast(WindowAppBlockStandardBase* pBlockItem);
  101. // 功能块复制粘贴
  102. void ToolCopyBlock(WindowAppBlockStandardBase* pBlockItem);
  103. void ToolCopyData(WindowAppBlockStandardBase* pBlockItem);
  104. void ToolPaste(WindowAppBlockStandardBase* pBlockItem);
  105. // 删除工具
  106. void ToolDelete(WindowAppBlockBase* pBlockItem);
  107. // 建立Link
  108. void makeLink(
  109. WindowAppItemInterface* srcInfItem,
  110. WindowAppItemInterface* dstInfItem,
  111. WindowAppItemLink* linkItem,
  112. LINK_MODE linkMode = LINK_MODE::LINK_NORMAL
  113. );
  114. // 清除Link信息
  115. void removeLink(WindowAppItemInterface* endInfItem);
  116. // 获取全部的Link信息
  117. const QVector<LINK>& getAllLinks()
  118. {
  119. return m_Links;
  120. }
  121. // 注册新的Link信息
  122. void registerLink(
  123. WindowAppItemInterface* startInfItem,
  124. WindowAppItemInterface* endInfItem,
  125. WindowAppItemLink* linkItem,
  126. LINK_MODE linkMode);
  127. // 反注册Link信息
  128. void unregisterLink(WindowAppItemInterface* endInfItem);
  129. // 重置所有工具执行状态
  130. void ResetToolExecCode();
  131. // 将指定接口绑定到指定Port中
  132. void bindPortAndInterface(WindowAppBlockBase* pPortItem, _INTERFACE* pBindInf, const QString& strInfName);
  133. // 根据对应的Item指针获取对应的Tool
  134. TOOL* GetToolByName(WindowAppBlockBase* pItem)
  135. {
  136. return m_itemToTools.value(pItem);
  137. }
  138. // 根据对应的InstanceName获取对应的Tool
  139. TOOL* GetToolByName(QString strInstName)
  140. {
  141. return m_instNameToTools.value(strInstName);
  142. }
  143. // 根据对应的InstanceName获取对应的Tool Item
  144. WindowAppBlockBase* GetToolItem(QString strInstName)
  145. {
  146. return m_instNameToToolItems.value(strInstName);
  147. }
  148. // 获取指定Item的绝对坐标
  149. QPointF GetToolItemPos(QString strKey);
  150. // 根据对应的Tool信息找到对应的Tool Item
  151. WindowAppBlockBase* GetToolItem(const TOOL* pTool)
  152. {
  153. return m_instNameToToolItems.value(pTool->strInstanceName);
  154. }
  155. // 根据对应的Item指针获取对应的Interface
  156. _INTERFACE* GetInterface(WindowAppItemInterface* pItem)
  157. {
  158. return m_itemToInterfaces.value(pItem);
  159. }
  160. // 根据对应的名字获取对应的Interface(toolinstancename.infname的形式)
  161. _INTERFACE* GetInterface(const QString& strFullName)
  162. {
  163. return m_fullNameToInterfaces.value(strFullName);
  164. }
  165. // 2022-3-12,删除指定的接口相关数据结构
  166. void DelInterface(const QString& strFullName, WindowAppItemInterface* pItem, _INTERFACE* pInf);
  167. // 根据接口中对应的Dll数值获取接口指针(UIManager中使用)
  168. _INTERFACE* GetInterfaceByValuePtr(void* pValue);
  169. // 根据对应的名字获取对应的Interface Item(toolinstancename.infname的形式)
  170. WindowAppItemInterface* GetInterfaceItemByName(QString strFullName) const
  171. {
  172. return m_fullNameToInterfaceItems.value(strFullName);
  173. }
  174. // 获取当前运行的所有工具数量
  175. int GetAllToolsCount()
  176. {
  177. return m_itemToTools.size();
  178. }
  179. // 获取当前标准工具的数量(包括了Parallel、Goto、ForLoop以及StandardTools)
  180. int GetStandardToolsCount()
  181. {
  182. return this->m_StandardTools.size();
  183. }
  184. // 获取当前索引序号的工具的数量(目前等同于GetStandardToolsCount(),但是后面会分开)
  185. int GetIndexedToolsCount()
  186. {
  187. return this->m_StandardTools.size();
  188. }
  189. // 获取当前在运行的所有工具
  190. const QMap<QString, TOOL*> GetAllTools() const
  191. {
  192. return m_instNameToTools;
  193. }
  194. // 获取当前运行的所有标准工具
  195. const QVector<TOOL*>& GetAllStandardTools() const
  196. {
  197. return m_StandardTools;
  198. }
  199. //// 2022-3-29,按执行顺序获取当前所有工具
  200. //const QList<TOOL*> GetOrderedStandardTools() const;
  201. //// 2022-3-
  202. // 获取当前在运行的所有接口
  203. const QMap<QString, _INTERFACE*> GetAllInterfaces() const
  204. {
  205. return m_fullNameToInterfaces;
  206. }
  207. // 获取所有的Event类型接口(如果有)
  208. QMap<QString, EVENT*> getAllEvents();
  209. // 生成工具新的实例名字
  210. QString genToolInstanceName(const QString& strToolName);
  211. // 更新工具的各个参数信息
  212. // 设置工具的启用禁用
  213. void setToolEnable(const TOOL* pToolInfo, bool bEnable);
  214. // 设置接口的启用禁用
  215. bool setInterfaceEnable(const _INTERFACE* pInfInfo, bool bEnable);
  216. bool setInterfaceEnable(const TOOL* pToolInfo, int nInfIndex, bool bEnable);
  217. // 更新工具的Info
  218. void setToolInfo(const TOOL* pToolInfo, const QString& strInfo);
  219. // 设置工具的延时参数
  220. void setToolDelay(const TOOL* pToolInfo, const int inDelay, const int outDelay);
  221. // 设置工具的实例名称
  222. void setInstanceName(const TOOL* pToolInfo, const QString& strNewInsName, const QString& strOldInsName);
  223. // 检查工具的实例名称是否重复(用于在Dialog对话框中判断用户是否可以重命名工具)
  224. bool isInstanceNameDuplicated(const QString& strInsName);
  225. // 查询可执行SmartLink的接口
  226. WindowAppItemInterface* getSmartLinkInterface(const WindowAppItemInterface* pInf);
  227. // 获取本Pou的名字
  228. const QString pouName() const
  229. {
  230. return m_strPouName;
  231. }
  232. // 获取本Pou所在的Scene指针
  233. WindowAppPouScene* parentScene()
  234. {
  235. return m_parentScene;
  236. }
  237. //// 是否处于执行状态(被Task选中,并加载执行)
  238. //bool isRunning();
  239. // 是否被Task选中
  240. bool isSelByTask();
  241. // 是否在Task中运行
  242. bool isRunningInTask();
  243. // 2021-9-15 增加,查找本Pou中指定类型的接口(用于设计界面中的数据链接用)
  244. bool containInterface(VALUE_TYPE type, INF_DIRECTION dir = INF_DIRECTION::INF_DIR_OUT);
  245. // 更新接口的值(根据不同的模式,返回更新值的字符串形式)
  246. QString updateInterfaceValue(_INTERFACE* pInf, UPDATE_VALUE_MODE mode);
  247. // 2022-6-21 增加,获取两个Block之间的所有LinkItem(用于进行批量移动)
  248. QList<WindowAppItemLink*> getLinkItemsBetweenBlocks(WindowAppBlockBase* srcBlock, WindowAppBlockBase* dstBlock);
  249. // 2022-6-21 获取指定接口Item的LinkItem序号
  250. int getLinkIndexByDstInfItem(WindowAppItemInterface* dstItem);
  251. //// 是否可以从Task列表中删除(Task尚未处于运行状态)
  252. //bool couldBeDeletedFromTask();
  253. //// 2022-3-29 执行内部工具
  254. //VPEnum::RETURN_VALUE ExecuteInternal(TOOL* pActiveTool);
  255. // 2022-3-29 执行Goto工具(TODO:应该为内部工具专门设计一套数据结构,暂时先放在这里)
  256. VPEnum::RETURN_VALUE ToolExecuteGoto(TOOL* pTool, int& index);
  257. // 2022-4-30 执行Parallel工具
  258. VPEnum::RETURN_VALUE ToolExecuteParallel(TOOL* pTool);
  259. // 2022-8-25 执行ForLoop工具
  260. VPEnum::RETURN_VALUE ToolExecuteForloop(TOOL* pTool);
  261. // 2022-9-3 执行Wait工具
  262. VPEnum::RETURN_VALUE ToolExecuteWait(TOOL* pTool, TOOL_RUN_MODE runMode);
  263. // 2022-5-1 工具的执行总调度
  264. VPEnum::RETURN_VALUE ToolExecutionDispatcher(TOOL*& pTool, TOOL_RUN_MODE runMode);
  265. // 2022-5-1 工具的执行总调度(Task中使用,关联执行序号)
  266. VPEnum::RETURN_VALUE ToolExecutionDispatcher(TOOL*& pTool, int& index, TOOL_RUN_MODE runMode);
  267. // 2022-9-6,执行前预检查
  268. VPEnum::RETURN_VALUE ToolExecutionDispatcherPreCheck(TOOL*& pTool, TOOL_RUN_MODE runMode);
  269. // 2022-9-25,查询WaitTool的等待Value(用于在TaskManager触发WaitTool执行的时候进行判断)
  270. VALUE* getWaitToolValue(TOOL* pTool);
  271. public:
  272. friend Document;
  273. // 本Pou运行时的参数和状态
  274. EXEC_PARAMS execParams;
  275. // 本Pou执行时所在的Task
  276. const TASK* m_pParentTask = nullptr;
  277. protected:
  278. // 从Dll获取接口的值
  279. template<typename T>
  280. T& GetDllInfValue(_INTERFACE* pInf);
  281. // 设置Dll中接口的值
  282. template<typename T>
  283. void SetDllInfValue(T& tValue, _INTERFACE* pInf);
  284. // 重命名计数 + 1
  285. void AddRenameRefCount(const QString& strName);
  286. //// 刷新StandardTools列表
  287. //void updateStandardToolsList(TOOL* pNewTool);
  288. // MoveValue
  289. template<typename T>
  290. void MoveValue(T& tValue, _INTERFACE* pInf, UPDATE_VALUE_MODE mode);
  291. // 2021-8-24 将基础数据类型转换后,再执行操作
  292. template<typename T>
  293. void MoveValueByConverter(T& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
  294. // 根据其他需要特殊的类型做模板的特化(为了实现自动接口数值类型转换)
  295. void MoveValueByConverter(QString& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
  296. void MoveValueByConverter(int& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
  297. void MoveValueByConverter(float& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
  298. void MoveValueByConverter(double& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
  299. void MoveValueByConverter(bool& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
  300. // 2021-11-9 向UI同步接口数值
  301. void syncValuesToUi(QList<_INTERFACE*> pInfs);
  302. // 2021-11-14 向变量表界面同步数值
  303. void syncValuesToTableUI(QList<VARIABLE*> pInfs);
  304. // 2021-12-15 向Runtime推送索引数值的变动
  305. void syncComplexIndexesToRuntime(QList<VARIABLE*> pIndexes);
  306. // 用于调试的函数
  307. // 输出所有工具相关的数据结构
  308. void debugAllTools();
  309. // 输出所有接口相关的数据结构
  310. void debugAllInterface();
  311. //// 输出所有引用计数的相关数据结构
  312. //void debugAllRefCounter();
  313. // 2022-2-15 增加Pou内部变量(仅用于统计,不显示、不序列化)
  314. void initPouInternalVariables();
  315. // 2022-2-16 绑定Pou内部变量和EXEC_PARAMS数据结构
  316. void bindPouInternalVariables();
  317. // 2022-3-6,检测功能块的变动是否需要向Task同步
  318. void syncToolMoveToTaskView();
  319. // 排序(用于在Pou中保持执行队列按index有序)
  320. static bool sort_by_index(const TOOL* t1, const TOOL* t2)
  321. {
  322. return t1->nIndex < t2->nIndex;
  323. }
  324. private:
  325. // 本Pou的名称
  326. QString m_strPouName;
  327. // 界面中正在运行的工具信息(Name Map对,自动排序)`
  328. QMap<QString, TOOL*> m_instNameToTools;
  329. // 界面中正在运行的所有接口信息(FullName Map对,自动排序)
  330. QMap<QString, _INTERFACE*> m_fullNameToInterfaces;
  331. // 界面中正在运行的工具信息(QGraphicsItem Hash对)
  332. QHash<WindowAppBlockBase*, TOOL*> m_itemToTools;
  333. // 界面中正在运行的所有接口信息(QGraphicsItem Hash对)
  334. QHash<WindowAppItemInterface*, _INTERFACE*> m_itemToInterfaces;
  335. // 界面中正在运行的工具信息(Name - Item Hash对)
  336. QMap<QString, WindowAppBlockBase*> m_instNameToToolItems;
  337. // 界面中正在运行的所有接口信息(FullName - Item Hash对)
  338. QMap<QString, WindowAppItemInterface*> m_fullNameToInterfaceItems;
  339. //// 每种运行工具的引用计数
  340. //QHash<const QGraphicsItem*, int> m_ItemReferenceCounter;
  341. // 每种工具的重命名Index
  342. QMap<QString, int> m_AutoToolRenameIndex;
  343. // 2021-8-14增加,为了提高TaskManager中的Tool执行效率,专门建立此数据结构
  344. // 用于按执行顺序存储该Pou所有的标准工具
  345. QVector<TOOL*> m_StandardTools;
  346. //用于临时数据的buffer
  347. QBuffer m_BufferTemp;
  348. // 单步执行的序号
  349. int m_nExecuteIndex;
  350. // 2022-4-30, 用于执行并行任务的线程池
  351. QThreadPool m_ParallelThreadPool;
  352. // 2022-6-12,用于存储本Pou中所有的Link信息,此后Link信息由Pou类统一管理(主要用于Link信息的序列化与反序列化)
  353. QVector<LINK> m_Links;
  354. // 所属的Scene指针
  355. WindowAppPouScene* m_parentScene;
  356. };