TaskManager.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. #include "TaskManager.h"
  2. #include "WindowAppTaskView.h"
  3. #include "Pou.h"
  4. #include "Preferences.h"
  5. #include "PouManager.h"
  6. #include "GvlManager.h"
  7. TaskManager* TaskManager::m_pTaskManager = nullptr;
  8. // 同时支持的Task最大线程数
  9. #define MAX_TASK_THREAD 20
  10. TaskManager::TaskManager()
  11. {
  12. // 支持线程池最大并行线程
  13. m_TaskThreadPool.setMaxThreadCount(MAX_TASK_THREAD);
  14. // 注册自定义线程参数
  15. // (切记需要注册,如果不注册的话线程参数不会正常传递到线程中执行)
  16. // qRegisterMetaType<TASK*>("TASK*");
  17. qRegisterMetaType<QVector<int>>("QVector<int>");
  18. // 生成系统内置事件
  19. this->initSysEvents();
  20. // 初始化系统定时器
  21. m_eventTimer.setInterval(SYS_TIMER);
  22. connect(&m_eventTimer, SIGNAL(timeout()), this, SLOT(onEventTimer()));
  23. }
  24. /// <summary>
  25. /// 接收来自各个View的Task注册信息
  26. /// </summary>
  27. /// <param name="pTask"></param>
  28. /// <param name="pView"></param>
  29. void TaskManager::registerTask(TASK* pTask, WindowAppTaskView* pView)
  30. {
  31. m_Tasks.insert(pTask->strName, pTask);
  32. m_TaskViews.insert(pTask->strName, pView);
  33. // 有了新的Task,更新一下Task和event的对应关系
  34. if (pTask->pEvent != nullptr)
  35. {
  36. m_EventTasks.insertMulti(pTask->pEvent->type(), pTask);
  37. }
  38. }
  39. ///// <summary>
  40. ///// 添加单独的Task
  41. ///// </summary>
  42. ///// <param name="newTask"></param>
  43. //void TaskManager::addTask(TASK* pNewTask)
  44. //{
  45. // pNewTask->nIndex = m_Tasks.size();
  46. // m_Tasks.insert(pNewTask->strName, pNewTask);
  47. //}
  48. ///// <summary>
  49. ///// 新建一个Task
  50. ///// </summary>
  51. ///// <param name="strTaskName"></param>
  52. //void TaskManager::addTask(const QString& strTaskName)
  53. //{
  54. // TASK newTask;
  55. //
  56. // newTask.nIndex = m_Tasks.size();
  57. // newTask.strName = strTaskName;
  58. //
  59. // m_Tasks.insert(strTaskName, newTask);
  60. //}
  61. /// <summary>
  62. /// 为指定的Task添加Pou
  63. /// </summary>
  64. /// <param name="strTaskName"></param>
  65. /// <param name="pous"></param>
  66. void TaskManager::addTaskPous(const QString& strTaskName, const QVector<POU*>& pous)
  67. {
  68. if (m_Tasks.find(strTaskName) != m_Tasks.end())
  69. {
  70. m_Tasks.value(strTaskName)->pous.append(pous);
  71. }
  72. else
  73. {
  74. qWarning() << "[Error] addTaskPous, but can't find the task, name :" << strTaskName;
  75. }
  76. }
  77. /// <summary>
  78. /// 删除整个Task
  79. /// </summary>
  80. /// <param name="strTaskName"></param>
  81. void TaskManager::delTask(const QString& strTaskName)
  82. {
  83. // 枚举Task中的每一个Task,并清理标记位
  84. QVectorIterator<POU*> it(m_Tasks.value(strTaskName)->pous);
  85. while (it.hasNext())
  86. {
  87. POU* pPou = it.next();
  88. pPou->m_pParentTask = nullptr;
  89. }
  90. m_Tasks.remove(strTaskName);
  91. m_TaskViews.remove(strTaskName);
  92. // TODO:需要删除event
  93. QHashIterator<EVENT_ID, TASK*> i(m_EventTasks);
  94. while (i.hasNext())
  95. {
  96. QList<TASK*> pTasks = m_EventTasks.values(i.next().key());
  97. for (TASK* pTask : pTasks)
  98. {
  99. if (pTask->strName == strTaskName)
  100. {
  101. m_EventTasks.remove(i.key(), pTask);
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. /// <summary>
  108. /// 删除指定Task中的一个Pou
  109. /// </summary>
  110. /// <param name="strTaskName"></param>
  111. /// <param name="nPouIndex"></param>
  112. void TaskManager::delTaskPou(const QString& strTaskName, const int& nPouIndex)
  113. {
  114. m_Tasks.value(strTaskName)->pous.remove(nPouIndex);
  115. }
  116. /// <summary>
  117. /// 数据结构重置
  118. /// </summary>
  119. void TaskManager::reset()
  120. {
  121. m_Tasks.clear();
  122. m_TaskViews.clear();
  123. m_EventTasks.clear();
  124. m_EventTools.clear();
  125. m_ToolEvents.clear();
  126. }
  127. /// <summary>
  128. /// Pou信息交换顺序
  129. /// </summary>
  130. /// <param name="strGroup"></param>
  131. /// <param name="nIndex1"></param>
  132. /// <param name="nIndex2"></param>
  133. void TaskManager::swapTaskPou(const QString& strTaskName, const int& nIndex1, const int& nIndex2)
  134. {
  135. qSwap(m_Tasks.value(strTaskName)->pous[nIndex1], m_Tasks.value(strTaskName)->pous[nIndex2]);
  136. //PouManager* pTmp = m_Tasks.value(strTaskName).pous[nIndex2];
  137. //m_Tasks.value(strTaskName).pous[nIndex1] = m_Tasks.value(strTaskName).pous[nIndex2];
  138. //m_Tasks.value(strTaskName).pous[nIndex2] = pTmp;
  139. }
  140. //============================================================
  141. //
  142. // Task执行相关
  143. //
  144. //============================================================
  145. /// <summary>
  146. /// 执行所有任务
  147. /// </summary>
  148. /// <param name="bOnce">是否只执行一轮</param>
  149. bool TaskManager::executeAllTasks(bool bOnce)
  150. {
  151. Q_UNUSED(bOnce);
  152. // 检查是否有Task处于Busy状态
  153. if (isTaskBusy())
  154. {
  155. return false;
  156. }
  157. // 设定系统内置事件定时器
  158. if (!m_eventTimer.isActive())
  159. {
  160. // 启动定时器
  161. m_eventTimer.start();
  162. }
  163. // 重置时间计数器
  164. m_nTimerCounter = 0;
  165. // 循环所有任务启动执行
  166. QMap<QString, TASK*>::iterator iter = m_Tasks.begin();
  167. while (iter != m_Tasks.end())
  168. {
  169. this->executeTask(iter.key(), bOnce);
  170. iter++;
  171. }
  172. return true;
  173. }
  174. /// <summary>
  175. /// 执行Task
  176. /// </summary>
  177. /// <param name="strTaskName">待执行任务的名字</param>
  178. /// <param name="bOnce">是否是单次执行</param>
  179. void TaskManager::executeTask(const QString& strTaskName, bool bOnce /*= true*/)
  180. {
  181. // 确保任务的名字正确
  182. if (m_Tasks.find(strTaskName) == m_Tasks.end())
  183. {
  184. qWarning() << "[Error] executeTask, but can't find the task, name :" << strTaskName;
  185. return;
  186. }
  187. // 检查任务的状态是否为busy
  188. if (isTaskBusy(strTaskName))
  189. {
  190. return;
  191. }
  192. // 启动线程开始执行对应的Task
  193. if (bOnce)
  194. {
  195. m_Tasks.value(strTaskName)->execParams.runMode = TASK_RUN_MODE::RUN_ONCE;
  196. }
  197. else
  198. {
  199. m_Tasks.value(strTaskName)->execParams.runMode = TASK_RUN_MODE::RUN_LOOP;
  200. }
  201. // 设置线程参数
  202. qDebug() << "[TASK] Run task[" << strTaskName << "] thread pool....";
  203. // 启动线程(带Task线程优先级)
  204. m_TaskThreadPool.start(
  205. new _TaskThread(m_Tasks.value(strTaskName)),
  206. (int)m_Tasks.value(strTaskName)->execParams.nPriority
  207. );
  208. }
  209. /// <summary>
  210. /// 执行Task(供线程调用)
  211. /// </summary>
  212. /// <param name="strTaskName"></param>
  213. /// <param name="bOnce"></param>
  214. void TaskManager::_executeTask(TASK* pTask)
  215. {
  216. thePrefs.m_bSystemIsRunning = true;
  217. qDebug() << "[TASK] Run thread task[" << pTask->strName << "] _executeTask in mode:" << (short)pTask->execParams.runMode;
  218. WindowAppTaskView* pView = m_TaskViews.value(pTask->strName);
  219. // 重置一下Task的Timer
  220. pTask->execParams.nExecTime = 0;
  221. // 开始统计Task 执行时间
  222. QElapsedTimer taskTimer;
  223. // 循环执行
  224. forever
  225. {
  226. // 等到事件前,开始计时
  227. taskTimer.start();
  228. // 将Task置为Wait状态
  229. pTask->execParams.nStatus = VPEnum::EXEC_STATUS::Wait;
  230. emit pView->sigUpdateTaskStatus();
  231. // vDebug() << "Task[" << pTask->strName << "] waiting...";
  232. // 如果是事件任务,则等待Task事件触发后才执行
  233. bool bWaitDone = this->waitForEvents(pTask);
  234. // Q_UNUSED(bWaitDone);
  235. // vDebug() << "Task[" << pTask->strName << "] waiting finished.";
  236. // 等到事件后,开始计时
  237. taskTimer.start();
  238. // 2021-9-29 此处的判断还是需要打开,防止waitForEvents返回false时,task依然继续执行的问题
  239. if (!bWaitDone)
  240. {
  241. // 检查一下线程是否退出
  242. if (pTask->execParams.runMode == TASK_RUN_MODE::RUN_STOP)
  243. {
  244. this->setTaskStandBy(pTask, pView);
  245. break;
  246. }
  247. else
  248. {
  249. continue;
  250. }
  251. }
  252. qDebug() << "----- [TASK] Task[" << pTask->strName << "] activate.";
  253. // 将Task置为Busy状态
  254. pTask->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
  255. emit pView->sigUpdateTaskStatus();
  256. // 枚举Task中的每一个Pou,顺序执行
  257. QVectorIterator<POU*> it(pTask->pous);
  258. while (it.hasNext())
  259. {
  260. POU* pPou = it.next();
  261. this->_executePou(pTask, pPou, pView);
  262. }
  263. // 如果Task任务退出则退出循环
  264. if (pTask->execParams.runMode == TASK_RUN_MODE::RUN_STOP)
  265. {
  266. this->setTaskStandBy(pTask, pView);
  267. break;
  268. }
  269. //只执行一次的话,退出循环
  270. else if (pTask->execParams.runMode == TASK_RUN_MODE::RUN_ONCE)
  271. {
  272. this->setTaskDone(pTask, taskTimer, pView);
  273. break;
  274. }
  275. // 执行Task后延时
  276. Utility::qSleep(pTask->execParams.nPostDelay);
  277. // Task Done
  278. this->setTaskDone(pTask, taskTimer, pView);
  279. qDebug() << "----- [TASK] Task[" << pTask->strName << "] finished.";
  280. }
  281. thePrefs.m_bSystemIsRunning = false;
  282. // Task Done 吗,
  283. //this->setTaskDone(pTask, pView);
  284. qDebug() << "[TASK][Thread] Task[" << pTask->strName << "] _executeTask exit.";
  285. }
  286. /// <summary>
  287. /// 执行Pou(线程执行)
  288. /// </summary>
  289. /// <param name="pPou"></param>
  290. /// <param name="pView"></param>
  291. void TaskManager::_executePou(TASK* pTask, POU* pPou, WindowAppTaskView* pView)
  292. {
  293. // 开始统计 pou 执行时间
  294. QElapsedTimer pouTimer;
  295. pouTimer.start();
  296. //// For Test
  297. //Utility::qSleep(200);
  298. // 将Pou置为busy状态
  299. this->setPouBusy(pPou, pView);
  300. // 以Tool为单位执行
  301. const QVector<TOOL*>& allTools = pPou->GetAllStandardTools();
  302. for (int index = 0; index < allTools.size(); )
  303. {
  304. TOOL* pTool = allTools[index];
  305. // Tool Busy
  306. this->setToolBusy(pPou, pTool, pView);
  307. // 开始统计Tool执行时间
  308. QElapsedTimer toolTimer;
  309. toolTimer.start();
  310. VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
  311. // 交给Pou的Tool执行调度器执行
  312. ret = pPou->ToolExecutionDispatcher(pTool, index, TOOL_RUN_MODE::SEQUENTIAL);
  313. // 如果出现了错误,则Task的错误值需要 + 1 (Success和Goto混在一起判断了)
  314. if (ret != VPEnum::RETURN_VALUE::Success && ret != VPEnum::RETURN_VALUE::Goto)
  315. {
  316. pTask->execParams.nErrorCount++;
  317. }
  318. // 工具完成,执行更新
  319. this->setToolDone(pPou, pTool, toolTimer, pView);
  320. qDebug() << "[TASK:" << pTask->strName << "][POU:" << pPou->pouName() << "][Tool:" << pTool->strInstanceName << "][Index:"
  321. << pTool->nIndex << "] executed finished.";
  322. }
  323. // Pou完成,执行更新
  324. this->setPouDone(pPou, pouTimer, pView);
  325. }
  326. /// <summary>
  327. /// 停止所有任务
  328. /// </summary>
  329. /// <param name="bForce">是否强制停止</param>
  330. void TaskManager::stopAllTask(bool bForce /*= false*/)
  331. {
  332. Q_UNUSED(bForce);
  333. //// 检查是否有Task处于Busy状态
  334. //if (! isTaskBusy ())
  335. //{
  336. // return;
  337. //}
  338. // 设定系统内置事件定时器
  339. if (m_eventTimer.isActive())
  340. {
  341. // 启动定时器
  342. m_eventTimer.stop();
  343. }
  344. // 重置时间计数器
  345. m_nTimerCounter = 0;
  346. // 2022-9-4 循环所有Tool的activator,发送退出信号
  347. QMutableHashIterator<EVENT_ID, TOOL*> iter(m_EventTools);
  348. while (iter.hasNext())
  349. {
  350. QList<TOOL*> tools = m_EventTools.values(iter.next().key());
  351. foreach(TOOL* tool, tools)
  352. {
  353. tool->activator.wakeAll();
  354. }
  355. }
  356. // 循环所有Task,发送任务退出信号
  357. QMap<QString, TASK*>::iterator iter2 = m_Tasks.begin();
  358. while (iter2 != m_Tasks.end())
  359. {
  360. TASK* pTask = iter2.value();
  361. pTask->execParams.runMode = TASK_RUN_MODE::RUN_STOP;
  362. pTask->activator.wakeAll();
  363. iter2++;
  364. }
  365. }
  366. /// <summary>
  367. /// 检查Task状态是否Busy
  368. /// </summary>
  369. /// <param name="strTaskName"></param>
  370. /// <returns></returns>
  371. bool TaskManager::isTaskBusy(const QString& strTaskName /*= ""*/)
  372. {
  373. // 如果名字是空,则是检查所有任务的
  374. if (strTaskName.isEmpty())
  375. {
  376. QMap<QString, TASK*>::iterator iter = m_Tasks.begin();
  377. while (iter != m_Tasks.end())
  378. {
  379. if (iter.value()->execParams.nStatus == VPEnum::EXEC_STATUS::Busy)
  380. {
  381. //Utility::VPCriticalMessageBox("Task [" + iter.value()->strName + "] is busy!");
  382. return true;
  383. }
  384. iter++;
  385. }
  386. }
  387. else
  388. {
  389. if (m_Tasks.value(strTaskName)->execParams.nStatus == VPEnum::EXEC_STATUS::Busy)
  390. {
  391. //Utility::VPCriticalMessageBox("Task [" + strTaskName + "] is busy!");
  392. return true;
  393. }
  394. }
  395. return thePrefs.m_bSystemIsRunning;
  396. }
  397. /// <summary>
  398. /// 为TaskView添加一个新的Tool(用于Pou中动态增加Tool同步更新信息)
  399. /// </summary>
  400. /// <param name="strTaskName"></param>
  401. /// <param name="pPou"></param>
  402. /// <param name="pTool"></param>
  403. void TaskManager::addToolToTaskView(const QString& strTaskName, const POU* pPou, const TOOL* pTool)
  404. {
  405. // 首先找到对应的TaskView
  406. WindowAppTaskView* pView = m_TaskViews.value(strTaskName);
  407. pView->addTaskPouTool(pPou, pTool);
  408. }
  409. /// <summary>
  410. /// 执行Task的Event等待任务
  411. /// </summary>
  412. /// <param name="pTask"></param>
  413. bool TaskManager::waitForEvents(TASK* pTask)
  414. {
  415. // Loop执行或者是只执行一次,是不需要等待事件的
  416. if (pTask->strModeName == TASK_MODE_LOOP
  417. || pTask->execParams.runMode == TASK_RUN_MODE::RUN_ONCE)
  418. {
  419. //Utility::qSleep(50);
  420. return true;
  421. }
  422. //qDebug() << "[TASK] " << pTask->strName << " Wait for event[" << pTask->strMode << "]";
  423. // 否则开始等待任务事件触发
  424. pTask->mutex.lock();
  425. if (pTask->activator.wait(&pTask->mutex, pTask->timeOut) == false)
  426. {
  427. pTask->mutex.unlock();
  428. return false;
  429. }
  430. pTask->mutex.unlock();
  431. return true;
  432. }
  433. /// <summary>
  434. /// 2021-8-21 更新,Task设置更新后,要及时更新 m_TaskEvents 中的Event和Task的对应关系
  435. /// </summary>
  436. /// <param name="pTask"></param>
  437. void TaskManager::updateTaskEvent(QEvent::Type oldType, TASK* pTask)
  438. {
  439. // 删除旧的event-task绑定关系
  440. m_EventTasks.remove(oldType, pTask);
  441. // 有了新的Task,更新一下Task和event的对应关系
  442. if (pTask->pEvent != nullptr)
  443. {
  444. m_EventTasks.insertMulti(pTask->pEvent->type(), pTask);
  445. }
  446. }
  447. /// <summary>
  448. /// 2022-9-4 为了实现事件触发Tool等待执行而增加的系列函数
  449. /// </summary>
  450. /// <param name=""></param>
  451. /// <param name=""></param>
  452. void TaskManager::registerToolEvent(ToolEvent* event, TOOL* tool)
  453. {
  454. m_EventTools.insertMulti(event->type(), tool);
  455. m_ToolEvents.insert(tool, event);
  456. }
  457. /// <summary>
  458. /// 查询本工具是否绑定了触发事件
  459. /// </summary>
  460. /// <param name="pTool"></param>
  461. bool TaskManager::isToolTriggerable(TOOL* pTool)
  462. {
  463. QMutableHashIterator<EVENT_ID, TOOL*> iter(m_EventTools);
  464. while (iter.hasNext())
  465. {
  466. QList<TOOL*> tools = m_EventTools.values(iter.next().key());
  467. foreach(TOOL * tool, tools)
  468. {
  469. if (pTool == tool)
  470. {
  471. return true;
  472. }
  473. }
  474. }
  475. return false;
  476. }
  477. /// <summary>
  478. /// // 删除了一个工具的时候,需要到这里来反注册一下
  479. /// </summary>
  480. /// <param name=""></param>
  481. void TaskManager::unregisterTool(TOOL* pTool)
  482. {
  483. QMutableHashIterator<EVENT_ID, TOOL*> iter(m_EventTools);
  484. while (iter.hasNext())
  485. {
  486. QList<TOOL*> tools = m_EventTools.values(iter.next().key());
  487. foreach(TOOL * tool, tools)
  488. {
  489. if (pTool == tool)
  490. {
  491. m_EventTools.remove(iter.key(), pTool);
  492. return;
  493. }
  494. }
  495. }
  496. m_ToolEvents.remove(pTool);
  497. }
  498. /// <summary>
  499. /// 通过Tool查询ToolEvents信息(目前用于序列化中)
  500. /// </summary>
  501. /// <param name="pTool"></param>
  502. /// <returns></returns>
  503. ToolEvent* TaskManager::getEventByTool(TOOL* pTool)
  504. {
  505. return m_ToolEvents.value(pTool);
  506. }
  507. //============================================================
  508. //
  509. // Task界面设置 相关
  510. //
  511. //============================================================
  512. /// <summary>
  513. /// 设置tool为Busy状态
  514. /// </summary>
  515. /// <param name="pTool"></param>
  516. /// <param name="pView"></param>
  517. void TaskManager::setToolBusy(const POU* pPou, TOOL* pTool, WindowAppTaskView* pView)
  518. {
  519. pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
  520. emit pView->sigUpdateToolStatus(pPou, pTool);
  521. }
  522. /// <summary>
  523. /// 设置tool为完成状态
  524. /// </summary>
  525. /// <param name="pTool"></param>
  526. void TaskManager::setToolDone(
  527. POU* pPou,
  528. TOOL* pTool,
  529. QElapsedTimer& toolTimer,
  530. WindowAppTaskView* pView
  531. )
  532. {
  533. int nTimer = toolTimer.elapsed();
  534. // 统计Tool执行时间
  535. pTool->execParams.nExecTime = nTimer;
  536. // Tool Done
  537. pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
  538. // 2022-8-29 由于执行次数各个工具内部的情况都不一样,干脆还是直接改回工具内部处理了
  539. //// 正常情况下,Tool 执行次数+1(需要排除掉Goto和ForLoop特殊处理)
  540. //if ((!pTool->isGotoTool()) && (!pTool->isForloopTool()))
  541. //{
  542. // pTool->execParams.nExecCount++;
  543. //}
  544. //// 2022-4-6增加,Goto工具只有在执行了Goto动作后执行次数才会 +1
  545. //else if (pTool->isGotoTool()
  546. // && pTool->execParams.nRetValue == VPEnum::RETURN_VALUE::Goto)
  547. //{
  548. // pTool->execParams.nExecCount++;
  549. //}
  550. //// 2022-8-28 增加,ForLoop工具的执行计数需要按照其循环执行的次数来+,所以只能在ForLoop工具内部处理
  551. //else if (pTool->isForloopTool())
  552. //{
  553. //}
  554. // 刷新所有表格
  555. emit pView->sigUpdateAllTables(pPou, pTool);
  556. }
  557. /// <summary>
  558. /// 设置Pou为Busy状态
  559. /// </summary>
  560. /// <param name="pPou"></param>
  561. /// <param name="pView"></param>
  562. void TaskManager::setPouBusy(POU* pPou, WindowAppTaskView* pView)
  563. {
  564. // 将Pou置为busy状态
  565. pPou->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
  566. emit pView->sigUpdatePouStatus(pPou);
  567. // 重置一下Pou的Timer
  568. pPou->execParams.nExecTime = 0;
  569. }
  570. /// <summary>
  571. /// 设置Pou为完成状态
  572. /// </summary>
  573. /// <param name="pPou"></param>
  574. void TaskManager::setPouDone(POU* pPou, QElapsedTimer& pouTimer, WindowAppTaskView* pView)
  575. {
  576. // 将Pou置为完成状态
  577. pPou->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
  578. // Pou 执行次数+1
  579. pPou->execParams.nExecCount++;
  580. // 结束统计Pou执行时间
  581. pPou->execParams.nExecTime = pouTimer.elapsed();
  582. VARIABLE* pVar = g_pGvlManager->getVariableByName(pPou->pouName(), INTERNALVAR_NAME_EXECTIME);
  583. QString strValue = pVar->getValueString();
  584. // 更新一下Pou表格和Task表格
  585. emit pView->sigUpdatePouTable(pPou);
  586. // 2022-3-21,检查Pou内部变量是否绑定了复杂控件的索引(或刷新)并执行更新
  587. this->syncComplexIndexToRuntime(pPou->pouName());
  588. // 2022-9-10,发送Pou同步消息
  589. this->syncPouParamsToUi(pPou);
  590. }
  591. /// <summary>
  592. /// 设置Task为完成状态
  593. /// </summary>
  594. /// <param name="pTask"></param>
  595. void TaskManager::setTaskDone(TASK* pTask, QElapsedTimer& taskTimer, WindowAppTaskView* pView)
  596. {
  597. // 全部Pou执行完毕后,将Task置为Done状态
  598. pTask->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
  599. // Task执行次数 + 1
  600. pTask->execParams.nExecCount++;
  601. // 系统中的总执行次数 +1
  602. thePrefs.m_nRunningCount++;
  603. // 统计Task执行时间
  604. pTask->execParams.nExecTime = taskTimer.elapsed();
  605. // 刷新Task表格
  606. emit pView->sigUpdateTaskTable();
  607. // 2022-9-10,发送Task同步消息(向UI)
  608. this->syncTaskAndSystemParamsToUi(pTask);
  609. // 2022-9-12,检查全局变量是否绑定了复杂控件的索引并执行更新(向Runtime)
  610. this->syncComplexIndexToRuntime(GROUP_NAME_SYSTEM);
  611. }
  612. /// <summary>
  613. /// 设置Task为就绪状态
  614. /// </summary>
  615. /// <param name="pTask"></param>
  616. void TaskManager::setTaskStandBy(TASK* pTask, WindowAppTaskView* pView)
  617. {
  618. // 全部Pou执行完毕后,将Task置为Done状态
  619. pTask->execParams.nStatus = VPEnum::EXEC_STATUS::StandBy;
  620. // 刷新Task表格
  621. emit pView->sigUpdateTaskTable();
  622. }
  623. /// <summary>
  624. /// 2022-9-10,增加了Task完成时的数值触发动作,用于提供给外部进行绑定同步
  625. /// </summary>
  626. void TaskManager::syncTaskAndSystemParamsToUi(TASK* pTask)
  627. {
  628. SyncValueEvent* valueEvent = new SyncValueEvent();
  629. // Task执行次数
  630. VARIABLE* pVar = g_pGvlManager->getVariableByName(GROUP_NAME_SYSTEM, pTask->strName + EXEC_COUNT_POSTFIX);
  631. valueEvent->addSyncValue(pVar);
  632. // System执行总次数
  633. pVar = g_pGvlManager->getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_EXECCOUNT);
  634. valueEvent->addSyncValue(pVar);
  635. // TODO:其他参数由于没有变动,为了提高效率这里就没有触发,也就是说如果绑定其他参数的话,变动的时候应该不会得到同步
  636. // 更合理的方式应该是在其他变量变动的时候再同步即可,放在这里效率有点低了
  637. // post数值同步消息,post内部会自动释放event的指针,无需手工释放
  638. QCoreApplication::postEvent((QObject*)g_pUiManager, valueEvent);
  639. }
  640. /// <summary>
  641. /// 2022-9-10,增加了Pou完成时的数值触发动作,用于提供给外部进行绑定同步
  642. /// </summary>
  643. void TaskManager::syncPouParamsToUi(POU* pPou)
  644. {
  645. SyncValueEvent* valueEvent = new SyncValueEvent();
  646. // Pou的执行次数
  647. VARIABLE* pVar = g_pGvlManager->getVariableByName(pPou->pouName(), INTERNALVAR_NAME_EXECCOUNT);
  648. valueEvent->addSyncValue(pVar);
  649. // Pou执行时间
  650. pVar = g_pGvlManager->getVariableByName(pPou->pouName(), INTERNALVAR_NAME_EXECTIME);
  651. valueEvent->addSyncValue(pVar);
  652. // post数值同步消息,post内部会自动释放event的指针,无需手工释放
  653. QCoreApplication::postEvent((QObject*)g_pUiManager, valueEvent);
  654. }
  655. //============================================================
  656. //
  657. // Event 相关
  658. //
  659. //============================================================
  660. /// <summary>
  661. /// 初始化系统事件
  662. /// </summary>
  663. void TaskManager::initSysEvents()
  664. {
  665. // 为了统一事件触发机制,把系统内置变量的Event机制进行了重写
  666. _INTERFACE* newEventInf = new _INTERFACE(nullptr);
  667. // Task_loop(为了统一也作为一个事件,但是指针为nullptr)
  668. newEventInf->strName = (TASK_MODE_LOOP);
  669. newEventInf->strFullName = (TASK_MODE_LOOP);
  670. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  671. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  672. newEventInf->eventTrigger = nullptr;
  673. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  674. // Task Run
  675. newEventInf = new _INTERFACE(nullptr);
  676. newEventInf->strName = (TASK_MODE_EVENT_RUN);
  677. newEventInf->strFullName = (TASK_MODE_EVENT_RUN);
  678. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  679. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  680. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  681. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  682. // Task Stop
  683. newEventInf = new _INTERFACE(nullptr);
  684. newEventInf->strName = (TASK_MODE_EVENT_STOP);
  685. newEventInf->strFullName = (TASK_MODE_EVENT_STOP);
  686. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  687. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  688. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  689. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  690. // Sys Exit
  691. newEventInf = new _INTERFACE(nullptr);
  692. newEventInf->strName = (TASK_MODE_EVENT_EXIT);
  693. newEventInf->strFullName = (TASK_MODE_EVENT_EXIT);
  694. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  695. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  696. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  697. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  698. // Load Doc
  699. newEventInf = new _INTERFACE(nullptr);
  700. newEventInf->strName = (TASK_MODE_EVENT_DOCLOADED);
  701. newEventInf->strFullName = (TASK_MODE_EVENT_DOCLOADED);
  702. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  703. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  704. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  705. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  706. // 100ms
  707. newEventInf = new _INTERFACE(nullptr);
  708. newEventInf->strName = (TASK_MODE_EVENT_TIME_100MS);
  709. newEventInf->strFullName = (TASK_MODE_EVENT_TIME_100MS);
  710. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  711. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  712. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  713. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  714. // 500ms
  715. newEventInf = new _INTERFACE(nullptr);
  716. newEventInf->strName = (TASK_MODE_EVENT_TIME_500MS);
  717. newEventInf->strFullName = (TASK_MODE_EVENT_TIME_500MS);
  718. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  719. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  720. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  721. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  722. // 1s
  723. newEventInf = new _INTERFACE(nullptr);
  724. newEventInf->strName = (TASK_MODE_EVENT_TIME_1S);
  725. newEventInf->strFullName = (TASK_MODE_EVENT_TIME_1S);
  726. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  727. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  728. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  729. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  730. // 5s
  731. newEventInf = new _INTERFACE(nullptr);
  732. newEventInf->strName = (TASK_MODE_EVENT_TIME_5S);
  733. newEventInf->strFullName = (TASK_MODE_EVENT_TIME_5S);
  734. newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  735. newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
  736. newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
  737. m_sysEvents.insert(newEventInf->strFullName, newEventInf);
  738. // Old
  739. //// 构造Event类型的接口,为了和Tool中的Event接口统一
  740. //_INTERFACE* newEventInf = new _INTERFACE(nullptr);
  741. //// Task_loop(为了统一也作为一个事件,但是指针为nullptr)
  742. //newEventInf->strName = (TASK_MODE_LOOP);
  743. //newEventInf->strFullName = (TASK_MODE_LOOP);
  744. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  745. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  746. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  747. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  748. //newEventInf->value.Ptr = nullptr;
  749. //m_sysModes.insert(newEventInf->strName, newEventInf);
  750. //// Task Run
  751. //newEventInf = new _INTERFACE(nullptr);
  752. //newEventInf->strName = (TASK_MODE_EVENT_RUN);
  753. //newEventInf->strFullName = (TASK_MODE_EVENT_RUN);
  754. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  755. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  756. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  757. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  758. //newEventInf->value.Ptr = (void**)(
  759. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  760. // );
  761. //m_sysModes.insert(newEventInf->strName, newEventInf);
  762. //// Task Stop
  763. //newEventInf = new _INTERFACE(nullptr);
  764. //newEventInf->strName = (TASK_MODE_EVENT_STOP);
  765. //newEventInf->strFullName = (TASK_MODE_EVENT_STOP);
  766. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  767. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  768. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  769. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  770. //newEventInf->value.Ptr = (void**)(
  771. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  772. // );
  773. //m_sysModes.insert(newEventInf->strName, newEventInf);
  774. //// Sys Exit
  775. //newEventInf = new _INTERFACE(nullptr);
  776. //newEventInf->strName = (TASK_MODE_EVENT_EXIT);
  777. //newEventInf->strFullName = (TASK_MODE_EVENT_EXIT);
  778. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  779. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  780. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  781. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  782. //newEventInf->value.Ptr = (void**)(
  783. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  784. // );
  785. //m_sysModes.insert(newEventInf->strName, newEventInf);
  786. //// Load Doc
  787. //newEventInf = new _INTERFACE(nullptr);
  788. //newEventInf->strName = (TASK_MODE_EVENT_DOCLOADED);
  789. //newEventInf->strFullName = (TASK_MODE_EVENT_DOCLOADED);
  790. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  791. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  792. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  793. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  794. //newEventInf->value.Ptr = (void**)(
  795. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  796. // );
  797. //m_sysModes.insert(newEventInf->strName, newEventInf);
  798. //// 100ms
  799. //newEventInf = new _INTERFACE(nullptr);
  800. //newEventInf->strName = (TASK_MODE_EVENT_TIME_100MS);
  801. //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_100MS);
  802. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  803. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  804. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  805. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  806. //newEventInf->value.Ptr = (void**)(
  807. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  808. // );
  809. //m_sysModes.insert(newEventInf->strName, newEventInf);
  810. //// 500ms
  811. //newEventInf = new _INTERFACE(nullptr);
  812. //newEventInf->strName = (TASK_MODE_EVENT_TIME_500MS);
  813. //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_500MS);
  814. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  815. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  816. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  817. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  818. //newEventInf->value.Ptr = (void**)(
  819. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  820. // );
  821. //m_sysModes.insert(newEventInf->strName, newEventInf);
  822. //// 1s
  823. //newEventInf = new _INTERFACE(nullptr);
  824. //newEventInf->strName = (TASK_MODE_EVENT_TIME_1S);
  825. //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_1S);
  826. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  827. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  828. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  829. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  830. //newEventInf->value.Ptr = (void**)(
  831. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  832. // );
  833. //m_sysModes.insert(newEventInf->strName, newEventInf);
  834. //// 5s
  835. //newEventInf = new _INTERFACE(nullptr);
  836. //newEventInf->strName = (TASK_MODE_EVENT_TIME_5S);
  837. //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_5S);
  838. //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
  839. //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
  840. //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
  841. //newEventInf->value.type = VALUE_TYPE::Type_Event;
  842. //newEventInf->value.Ptr = (void**)(
  843. // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
  844. // );
  845. //m_sysModes.insert(newEventInf->strName, newEventInf);
  846. }
  847. /// <summary>
  848. /// 定时器Even事件
  849. /// </summary>
  850. void TaskManager::onEventTimer()
  851. {
  852. // 100ms
  853. if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_100MS))
  854. {
  855. ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_100MS)->eventTrigger;
  856. QCoreApplication::sendEvent(this, pEvent);
  857. }
  858. // 500ms
  859. if (m_nTimerCounter % 5 == 0)
  860. {
  861. if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_500MS))
  862. {
  863. ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_500MS)->eventTrigger;
  864. QCoreApplication::sendEvent(this, pEvent);
  865. }
  866. }
  867. //1s
  868. if (m_nTimerCounter % 10 == 0)
  869. {
  870. if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_1S))
  871. {
  872. ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_1S)->eventTrigger;
  873. QCoreApplication::sendEvent(this, pEvent);
  874. }
  875. }
  876. //5s
  877. if (m_nTimerCounter % 50 == 0)
  878. {
  879. if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_5S))
  880. {
  881. ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_5S)->eventTrigger;
  882. QCoreApplication::sendEvent(this, pEvent);
  883. }
  884. }
  885. m_nTimerCounter++;
  886. }
  887. /// <summary>
  888. /// 等待event触发
  889. /// </summary>
  890. /// <param name="event"></param>
  891. /// <returns></returns>
  892. void TaskManager::customEvent(QEvent* event)
  893. {
  894. ToolEvent* pToolEvent = dynamic_cast<ToolEvent*>(event);
  895. // 判断事件类型
  896. if (pToolEvent->getExType() == TOOL_EVENT_TYPE::TOOL_TRIGGER)
  897. {
  898. // 即执行当前工具
  899. VPEnum::RETURN_VALUE ret = ExecuteTool(pToolEvent);
  900. pToolEvent->ret = ret;
  901. }
  902. else if (pToolEvent->getExType() == TOOL_EVENT_TYPE::TASK_TRIGGER)
  903. {
  904. // 先查找是否有匹配的Task,发送Task触发指令
  905. this->triggerTaskThread(pToolEvent);
  906. // 2022-9-4,由于事件还有可能触发Wait工具,还需要和Tool匹配一下
  907. this->triggerToolExecution(pToolEvent);
  908. }
  909. // Error,不应该走到这里
  910. else
  911. {
  912. vDebug() << "[Error] Unsupport ToolEvent Type: " << (short)pToolEvent->getExType();
  913. }
  914. event->accept();
  915. }
  916. /// <summary>
  917. /// 执行对应的工具
  918. /// </summary>
  919. /// <param name="pToolEvent"></param>
  920. VPEnum::RETURN_VALUE TaskManager::ExecuteTool(ToolEvent* pToolEvent)
  921. {
  922. if (pToolEvent == nullptr /*|| m_TaskEvents.size() <= 0*/)
  923. {
  924. return VPEnum::RETURN_VALUE::None;
  925. }
  926. //qDebug() << "[EVENT] event[" << pToolEvent->name() << "] activate.";
  927. QMap<QString, POU*>& allPous = g_pPouManager->getAllPous();
  928. // 遍历所有的Pou信息
  929. QMapIterator<QString, POU*> it(allPous);
  930. while (it.hasNext())
  931. {
  932. POU* pPou = it.next().value();
  933. //pPou->m_pParentTask = nullptr;
  934. if (pPou->pouName() == pToolEvent->groupName())
  935. {
  936. TOOL* pTool = pPou->GetToolByName(pToolEvent->name());
  937. if (pTool)
  938. {
  939. // 在PouManaer中执行本工具
  940. VPEnum::RETURN_VALUE ret = pPou->ToolExecuteStandard(pTool);
  941. //qWarning() << "ok";
  942. return ret;
  943. }
  944. }
  945. }
  946. return VPEnum::RETURN_VALUE::None;
  947. }
  948. /// <summary>
  949. /// 给Task 发送执行指令
  950. /// </summary>
  951. /// <param name="pToolEvent"></param>
  952. void TaskManager::triggerTaskThread(ToolEvent* pToolEvent)
  953. {
  954. if (pToolEvent == nullptr || m_EventTasks.size() <= 0)
  955. {
  956. return;
  957. }
  958. // 查找本事件是否有对应的Task触发(一个事件可能会对应着多个Task)
  959. QList<TASK*> tasks = m_EventTasks.values(pToolEvent->type());
  960. for (TASK* pTask : tasks)
  961. {
  962. // 如果Task没有处于busy状态, 则通知事件执行
  963. if (pTask->execParams.nStatus != VPEnum::EXEC_STATUS::Busy)
  964. {
  965. pTask->activator.wakeAll();
  966. }
  967. else
  968. {
  969. // 否则触发失败的次数+1
  970. pTask->execParams.nTriggerFailedCount++;
  971. //qWarning() << "[EVENT] Warning: event[" << pToolEvent->name() << "] activate, but task[" << pTask->strName << "] is busy.";
  972. }
  973. }
  974. //qDebug() << "[EVENT] event[" << pToolEvent->name() << "] activate.";
  975. //// 查找本事件是否有对应的Task触发(一个事件可能会对应着多个Task)
  976. //QList<TASK*> tasks = m_TaskEvents.values(pToolEvent->type());
  977. ////if (tasks.size() > 0)
  978. ////{
  979. // for (TASK* pTask : tasks)
  980. // {
  981. // // 如果Task没有处于busy状态, 则通知事件执行
  982. // if (pTask->execParams.nStatus != VPEnum::EXEC_STATUS::Busy)
  983. // {
  984. // pTask->activator.wakeAll();
  985. // }
  986. // else
  987. // {
  988. // // 否则触发失败的次数+1
  989. // pTask->execParams.nTriggerFailedCount++;
  990. // //qWarning() << "[EVENT] Warning: event[" << pToolEvent->name() << "] activate, but task[" << pTask->strName << "] is busy.";
  991. // }
  992. // }
  993. ////}
  994. ////else
  995. ////{
  996. // //qWarning() << "[EVENT] Warning: TaskManager:: event[" << pToolEvent->name() << "] activate, but can not find task.";
  997. ////}
  998. }
  999. /// <summary>
  1000. /// 2022-9-4 ToolEvent还可以同时触发Tool执行
  1001. /// (目前只有Wait工具可以触发,但是为了以后扩展,这里并没有写死,理论上是所有工具都能触发)
  1002. /// </summary>
  1003. /// <param name="pToolEvent"></param>
  1004. void TaskManager::triggerToolExecution(ToolEvent* pToolEvent)
  1005. {
  1006. if (pToolEvent == nullptr || m_EventTools.size() <= 0)
  1007. {
  1008. return;
  1009. }
  1010. // 查找本事件是否有对应的Task触发(一个事件可能会对应着多个Tool)
  1011. QList<TOOL*> tools = m_EventTools.values(pToolEvent->type());
  1012. for (TOOL* pTool : tools)
  1013. {
  1014. //// 如果Tool没有处于busy状态, 则触发该工具的通知事件
  1015. //if (pTool->execParams.nStatus != VPEnum::EXEC_STATUS::Busy)
  1016. //{
  1017. // 2022-9-25 增加,如果是Wait工具,那么需要判断一下这个Wait工具是否需要等待某一个值来触发,并且判断值是否命中
  1018. if (pTool->isWaitTool() && !this->isWaitToolHit(pTool, pToolEvent))
  1019. {
  1020. // 如果没有命中,则跳过此工具触发
  1021. continue;
  1022. }
  1023. // 如果不是WaitTool,或者是WaitTool并且值命中,则触发该工具的事件
  1024. pTool->activator.wakeAll();
  1025. // }
  1026. }
  1027. }
  1028. /// <summary>
  1029. /// 处理本轮中涉及到绑定至复杂控件中的变量,包括全局变量、Pou内部变量等(向Runtime触发)
  1030. /// Reason:在所有Tool执行完一轮之后,需要检查一下Pou的内部变量是否有用做复杂控件的Index的,需要安排触发一下
  1031. /// Reason2:每轮Task执行完毕之后,也需要安排触发一下
  1032. /// </summary>
  1033. /// <param name="strName"></param>
  1034. void TaskManager::syncComplexIndexToRuntime(QString strGroupName)
  1035. {
  1036. GVL* pGVL = g_pGvlManager->getGvl(strGroupName);
  1037. // 将作为索引的Pou内部变量添加到同步列表中
  1038. QList<VARIABLE*> syncComplexIndexes;
  1039. if (pGVL != nullptr)
  1040. {
  1041. const VARIABLES& vars = pGVL->Variables;
  1042. for (/*const*/ VARIABLE* var : vars)
  1043. {
  1044. if (var->bComplexLinkIndex)
  1045. {
  1046. syncComplexIndexes.push_back(var);
  1047. }
  1048. }
  1049. }
  1050. // 2021-12-15 进行复杂控件索引到Runtime的推送
  1051. if (syncComplexIndexes.size() > 0)
  1052. {
  1053. SyncValueEvent* valueEvent = new SyncValueEvent();
  1054. // 携带需要同步的多个接口
  1055. valueEvent->setSyncValues(syncComplexIndexes);
  1056. // post数值同步消息,post内部会自动释放event的指针,无需手工释放
  1057. QCoreApplication::postEvent((QObject*)g_pRuntime, valueEvent);
  1058. }
  1059. }
  1060. /// <summary>
  1061. /// 2022-9-25 WaitTool专用,判断Wait工具是否需要等待某一个值,并且这个值是否已经命中
  1062. /// </summary>
  1063. /// <param name="pTool"></param>
  1064. /// <returns></returns>
  1065. bool TaskManager::isWaitToolHit(TOOL* pTool, ToolEvent* toolEvent)
  1066. {
  1067. // 需要从Pou中找到这个Tool对应的Block,参数存在BlockItem里面
  1068. POU* pou = g_pPouManager->getPouByName(pTool->strPouName);
  1069. VALUE* waitValue = pou->getWaitToolValue(pTool);
  1070. // 检查是否需要等待Value,如果不需要等待,直接返回命中
  1071. if (waitValue == nullptr
  1072. || waitValue->type == VALUE_TYPE::Type_Unknown
  1073. || waitValue->Ptr == nullptr
  1074. || toolEvent->m_triggerValue.isNullptr()
  1075. )
  1076. {
  1077. return true;
  1078. }
  1079. vDebug() << "WaitTool : waitValue[" << waitValue->toString() << "]-eventValue[" << toolEvent->m_triggerValue.toString() << "].";
  1080. // 如果需要等待Value,那么检测这个Value是否命中,此处用到了重载的==
  1081. if (*waitValue == toolEvent->m_triggerValue)
  1082. {
  1083. return true;
  1084. }
  1085. return false;
  1086. }
  1087. //============================================================
  1088. //
  1089. // 并行 线程
  1090. //
  1091. //============================================================
  1092. /// <summary>
  1093. /// 线程函数
  1094. /// </summary>
  1095. void _TaskThread::run()
  1096. {
  1097. // 调用函数执行任务
  1098. g_pTaskManager->_executeTask(m_pRunningTask);
  1099. qDebug() << "[TASK][Thread] ThreadPool [" << m_pRunningTask->strName << "] exit.";
  1100. }