1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378 |
- #include "TaskManager.h"
- #include "WindowAppTaskView.h"
- #include "Pou.h"
- #include "Preferences.h"
- #include "PouManager.h"
- #include "GvlManager.h"
- TaskManager* TaskManager::m_pTaskManager = nullptr;
- // 同时支持的Task最大线程数
- #define MAX_TASK_THREAD 20
- TaskManager::TaskManager()
- {
- // 支持线程池最大并行线程
- m_TaskThreadPool.setMaxThreadCount(MAX_TASK_THREAD);
- // 注册自定义线程参数
- // (切记需要注册,如果不注册的话线程参数不会正常传递到线程中执行)
- // qRegisterMetaType<TASK*>("TASK*");
- qRegisterMetaType<QVector<int>>("QVector<int>");
- // 生成系统内置事件
- this->initSysEvents();
- // 初始化系统定时器
- m_eventTimer.setInterval(SYS_TIMER);
- connect(&m_eventTimer, SIGNAL(timeout()), this, SLOT(onEventTimer()));
- }
- /// <summary>
- /// 接收来自各个View的Task注册信息
- /// </summary>
- /// <param name="pTask"></param>
- /// <param name="pView"></param>
- void TaskManager::registerTask(TASK* pTask, WindowAppTaskView* pView)
- {
- m_Tasks.insert(pTask->strName, pTask);
- m_TaskViews.insert(pTask->strName, pView);
- // 有了新的Task,更新一下Task和event的对应关系
- if (pTask->pEvent != nullptr)
- {
- m_EventTasks.insertMulti(pTask->pEvent->type(), pTask);
- }
- }
- ///// <summary>
- ///// 添加单独的Task
- ///// </summary>
- ///// <param name="newTask"></param>
- //void TaskManager::addTask(TASK* pNewTask)
- //{
- // pNewTask->nIndex = m_Tasks.size();
- // m_Tasks.insert(pNewTask->strName, pNewTask);
- //}
- ///// <summary>
- ///// 新建一个Task
- ///// </summary>
- ///// <param name="strTaskName"></param>
- //void TaskManager::addTask(const QString& strTaskName)
- //{
- // TASK newTask;
- //
- // newTask.nIndex = m_Tasks.size();
- // newTask.strName = strTaskName;
- //
- // m_Tasks.insert(strTaskName, newTask);
- //}
- /// <summary>
- /// 为指定的Task添加Pou
- /// </summary>
- /// <param name="strTaskName"></param>
- /// <param name="pous"></param>
- void TaskManager::addTaskPous(const QString& strTaskName, const QVector<POU*>& pous)
- {
- if (m_Tasks.find(strTaskName) != m_Tasks.end())
- {
- m_Tasks.value(strTaskName)->pous.append(pous);
- }
- else
- {
- qWarning() << "[Error] addTaskPous, but can't find the task, name :" << strTaskName;
- }
- }
- /// <summary>
- /// 删除整个Task
- /// </summary>
- /// <param name="strTaskName"></param>
- void TaskManager::delTask(const QString& strTaskName)
- {
- // 枚举Task中的每一个Task,并清理标记位
- QVectorIterator<POU*> it(m_Tasks.value(strTaskName)->pous);
- while (it.hasNext())
- {
- POU* pPou = it.next();
- pPou->m_pParentTask = nullptr;
- }
- m_Tasks.remove(strTaskName);
- m_TaskViews.remove(strTaskName);
- // TODO:需要删除event
- QHashIterator<EVENT_ID, TASK*> i(m_EventTasks);
- while (i.hasNext())
- {
- QList<TASK*> pTasks = m_EventTasks.values(i.next().key());
- for (TASK* pTask : pTasks)
- {
- if (pTask->strName == strTaskName)
- {
- m_EventTasks.remove(i.key(), pTask);
- break;
- }
- }
- }
- }
- /// <summary>
- /// 删除指定Task中的一个Pou
- /// </summary>
- /// <param name="strTaskName"></param>
- /// <param name="nPouIndex"></param>
- void TaskManager::delTaskPou(const QString& strTaskName, const int& nPouIndex)
- {
- m_Tasks.value(strTaskName)->pous.remove(nPouIndex);
- }
- /// <summary>
- /// 数据结构重置
- /// </summary>
- void TaskManager::reset()
- {
- m_Tasks.clear();
- m_TaskViews.clear();
- m_EventTasks.clear();
- m_EventTools.clear();
- m_ToolEvents.clear();
- }
- /// <summary>
- /// Pou信息交换顺序
- /// </summary>
- /// <param name="strGroup"></param>
- /// <param name="nIndex1"></param>
- /// <param name="nIndex2"></param>
- void TaskManager::swapTaskPou(const QString& strTaskName, const int& nIndex1, const int& nIndex2)
- {
- qSwap(m_Tasks.value(strTaskName)->pous[nIndex1], m_Tasks.value(strTaskName)->pous[nIndex2]);
- //PouManager* pTmp = m_Tasks.value(strTaskName).pous[nIndex2];
- //m_Tasks.value(strTaskName).pous[nIndex1] = m_Tasks.value(strTaskName).pous[nIndex2];
- //m_Tasks.value(strTaskName).pous[nIndex2] = pTmp;
- }
- //============================================================
- //
- // Task执行相关
- //
- //============================================================
- /// <summary>
- /// 执行所有任务
- /// </summary>
- /// <param name="bOnce">是否只执行一轮</param>
- bool TaskManager::executeAllTasks(bool bOnce)
- {
- Q_UNUSED(bOnce);
- // 检查是否有Task处于Busy状态
- if (isTaskBusy())
- {
- return false;
- }
- // 设定系统内置事件定时器
- if (!m_eventTimer.isActive())
- {
- // 启动定时器
- m_eventTimer.start();
- }
- // 重置时间计数器
- m_nTimerCounter = 0;
- // 循环所有任务启动执行
- QMap<QString, TASK*>::iterator iter = m_Tasks.begin();
- while (iter != m_Tasks.end())
- {
- this->executeTask(iter.key(), bOnce);
- iter++;
- }
- return true;
- }
- /// <summary>
- /// 执行Task
- /// </summary>
- /// <param name="strTaskName">待执行任务的名字</param>
- /// <param name="bOnce">是否是单次执行</param>
- void TaskManager::executeTask(const QString& strTaskName, bool bOnce /*= true*/)
- {
- // 确保任务的名字正确
- if (m_Tasks.find(strTaskName) == m_Tasks.end())
- {
- qWarning() << "[Error] executeTask, but can't find the task, name :" << strTaskName;
- return;
- }
- // 检查任务的状态是否为busy
- if (isTaskBusy(strTaskName))
- {
- return;
- }
- // 启动线程开始执行对应的Task
- if (bOnce)
- {
- m_Tasks.value(strTaskName)->execParams.runMode = TASK_RUN_MODE::RUN_ONCE;
- }
- else
- {
- m_Tasks.value(strTaskName)->execParams.runMode = TASK_RUN_MODE::RUN_LOOP;
- }
- // 设置线程参数
- qDebug() << "[TASK] Run task[" << strTaskName << "] thread pool....";
- // 启动线程(带Task线程优先级)
- m_TaskThreadPool.start(
- new _TaskThread(m_Tasks.value(strTaskName)),
- (int)m_Tasks.value(strTaskName)->execParams.nPriority
- );
- }
- /// <summary>
- /// 执行Task(供线程调用)
- /// </summary>
- /// <param name="strTaskName"></param>
- /// <param name="bOnce"></param>
- void TaskManager::_executeTask(TASK* pTask)
- {
- thePrefs.m_bSystemIsRunning = true;
- qDebug() << "[TASK] Run thread task[" << pTask->strName << "] _executeTask in mode:" << (short)pTask->execParams.runMode;
- WindowAppTaskView* pView = m_TaskViews.value(pTask->strName);
- // 重置一下Task的Timer
- pTask->execParams.nExecTime = 0;
- // 开始统计Task 执行时间
- QElapsedTimer taskTimer;
-
- // 循环执行
- forever
- {
- // 等到事件前,开始计时
- taskTimer.start();
- // 将Task置为Wait状态
- pTask->execParams.nStatus = VPEnum::EXEC_STATUS::Wait;
- emit pView->sigUpdateTaskStatus();
- // vDebug() << "Task[" << pTask->strName << "] waiting...";
- // 如果是事件任务,则等待Task事件触发后才执行
- bool bWaitDone = this->waitForEvents(pTask);
- // Q_UNUSED(bWaitDone);
- // vDebug() << "Task[" << pTask->strName << "] waiting finished.";
- // 等到事件后,开始计时
- taskTimer.start();
- // 2021-9-29 此处的判断还是需要打开,防止waitForEvents返回false时,task依然继续执行的问题
- if (!bWaitDone)
- {
- // 检查一下线程是否退出
- if (pTask->execParams.runMode == TASK_RUN_MODE::RUN_STOP)
- {
- this->setTaskStandBy(pTask, pView);
- break;
- }
- else
- {
- continue;
- }
- }
- qDebug() << "----- [TASK] Task[" << pTask->strName << "] activate.";
- // 将Task置为Busy状态
- pTask->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
- emit pView->sigUpdateTaskStatus();
- // 枚举Task中的每一个Pou,顺序执行
- QVectorIterator<POU*> it(pTask->pous);
- while (it.hasNext())
- {
- POU* pPou = it.next();
- this->_executePou(pTask, pPou, pView);
- }
- // 如果Task任务退出则退出循环
- if (pTask->execParams.runMode == TASK_RUN_MODE::RUN_STOP)
- {
- this->setTaskStandBy(pTask, pView);
- break;
- }
- //只执行一次的话,退出循环
- else if (pTask->execParams.runMode == TASK_RUN_MODE::RUN_ONCE)
- {
- this->setTaskDone(pTask, taskTimer, pView);
- break;
- }
- // 执行Task后延时
- Utility::qSleep(pTask->execParams.nPostDelay);
- // Task Done
- this->setTaskDone(pTask, taskTimer, pView);
- qDebug() << "----- [TASK] Task[" << pTask->strName << "] finished.";
- }
- thePrefs.m_bSystemIsRunning = false;
- // Task Done 吗,
- //this->setTaskDone(pTask, pView);
- qDebug() << "[TASK][Thread] Task[" << pTask->strName << "] _executeTask exit.";
- }
- /// <summary>
- /// 执行Pou(线程执行)
- /// </summary>
- /// <param name="pPou"></param>
- /// <param name="pView"></param>
- void TaskManager::_executePou(TASK* pTask, POU* pPou, WindowAppTaskView* pView)
- {
- // 开始统计 pou 执行时间
- QElapsedTimer pouTimer;
- pouTimer.start();
- //// For Test
- //Utility::qSleep(200);
- // 将Pou置为busy状态
- this->setPouBusy(pPou, pView);
- // 以Tool为单位执行
- const QVector<TOOL*>& allTools = pPou->GetAllStandardTools();
- for (int index = 0; index < allTools.size(); )
- {
- TOOL* pTool = allTools[index];
-
- // Tool Busy
- this->setToolBusy(pPou, pTool, pView);
- // 开始统计Tool执行时间
- QElapsedTimer toolTimer;
- toolTimer.start();
- VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
- // 交给Pou的Tool执行调度器执行
- ret = pPou->ToolExecutionDispatcher(pTool, index, TOOL_RUN_MODE::SEQUENTIAL);
- // 如果出现了错误,则Task的错误值需要 + 1 (Success和Goto混在一起判断了)
- if (ret != VPEnum::RETURN_VALUE::Success && ret != VPEnum::RETURN_VALUE::Goto)
- {
- pTask->execParams.nErrorCount++;
- }
- // 工具完成,执行更新
- this->setToolDone(pPou, pTool, toolTimer, pView);
- qDebug() << "[TASK:" << pTask->strName << "][POU:" << pPou->pouName() << "][Tool:" << pTool->strInstanceName << "][Index:"
- << pTool->nIndex << "] executed finished.";
- }
- // Pou完成,执行更新
- this->setPouDone(pPou, pouTimer, pView);
- }
- /// <summary>
- /// 停止所有任务
- /// </summary>
- /// <param name="bForce">是否强制停止</param>
- void TaskManager::stopAllTask(bool bForce /*= false*/)
- {
- Q_UNUSED(bForce);
-
- //// 检查是否有Task处于Busy状态
- //if (! isTaskBusy ())
- //{
- // return;
- //}
- // 设定系统内置事件定时器
- if (m_eventTimer.isActive())
- {
- // 启动定时器
- m_eventTimer.stop();
- }
- // 重置时间计数器
- m_nTimerCounter = 0;
- // 2022-9-4 循环所有Tool的activator,发送退出信号
- QMutableHashIterator<EVENT_ID, TOOL*> iter(m_EventTools);
- while (iter.hasNext())
- {
- QList<TOOL*> tools = m_EventTools.values(iter.next().key());
- foreach(TOOL* tool, tools)
- {
- tool->activator.wakeAll();
- }
- }
- // 循环所有Task,发送任务退出信号
- QMap<QString, TASK*>::iterator iter2 = m_Tasks.begin();
- while (iter2 != m_Tasks.end())
- {
- TASK* pTask = iter2.value();
- pTask->execParams.runMode = TASK_RUN_MODE::RUN_STOP;
- pTask->activator.wakeAll();
- iter2++;
- }
- }
- /// <summary>
- /// 检查Task状态是否Busy
- /// </summary>
- /// <param name="strTaskName"></param>
- /// <returns></returns>
- bool TaskManager::isTaskBusy(const QString& strTaskName /*= ""*/)
- {
- // 如果名字是空,则是检查所有任务的
- if (strTaskName.isEmpty())
- {
- QMap<QString, TASK*>::iterator iter = m_Tasks.begin();
- while (iter != m_Tasks.end())
- {
- if (iter.value()->execParams.nStatus == VPEnum::EXEC_STATUS::Busy)
- {
- //Utility::VPCriticalMessageBox("Task [" + iter.value()->strName + "] is busy!");
- return true;
- }
- iter++;
- }
- }
- else
- {
- if (m_Tasks.value(strTaskName)->execParams.nStatus == VPEnum::EXEC_STATUS::Busy)
- {
- //Utility::VPCriticalMessageBox("Task [" + strTaskName + "] is busy!");
- return true;
- }
- }
- return thePrefs.m_bSystemIsRunning;
- }
- /// <summary>
- /// 为TaskView添加一个新的Tool(用于Pou中动态增加Tool同步更新信息)
- /// </summary>
- /// <param name="strTaskName"></param>
- /// <param name="pPou"></param>
- /// <param name="pTool"></param>
- void TaskManager::addToolToTaskView(const QString& strTaskName, const POU* pPou, const TOOL* pTool)
- {
- // 首先找到对应的TaskView
- WindowAppTaskView* pView = m_TaskViews.value(strTaskName);
- pView->addTaskPouTool(pPou, pTool);
- }
- /// <summary>
- /// 执行Task的Event等待任务
- /// </summary>
- /// <param name="pTask"></param>
- bool TaskManager::waitForEvents(TASK* pTask)
- {
- // Loop执行或者是只执行一次,是不需要等待事件的
- if (pTask->strModeName == TASK_MODE_LOOP
- || pTask->execParams.runMode == TASK_RUN_MODE::RUN_ONCE)
- {
- //Utility::qSleep(50);
- return true;
- }
- //qDebug() << "[TASK] " << pTask->strName << " Wait for event[" << pTask->strMode << "]";
- // 否则开始等待任务事件触发
- pTask->mutex.lock();
- if (pTask->activator.wait(&pTask->mutex, pTask->timeOut) == false)
- {
- pTask->mutex.unlock();
- return false;
- }
- pTask->mutex.unlock();
- return true;
- }
- /// <summary>
- /// 2021-8-21 更新,Task设置更新后,要及时更新 m_TaskEvents 中的Event和Task的对应关系
- /// </summary>
- /// <param name="pTask"></param>
- void TaskManager::updateTaskEvent(QEvent::Type oldType, TASK* pTask)
- {
- // 删除旧的event-task绑定关系
- m_EventTasks.remove(oldType, pTask);
- // 有了新的Task,更新一下Task和event的对应关系
- if (pTask->pEvent != nullptr)
- {
- m_EventTasks.insertMulti(pTask->pEvent->type(), pTask);
- }
- }
- /// <summary>
- /// 2022-9-4 为了实现事件触发Tool等待执行而增加的系列函数
- /// </summary>
- /// <param name=""></param>
- /// <param name=""></param>
- void TaskManager::registerToolEvent(ToolEvent* event, TOOL* tool)
- {
- m_EventTools.insertMulti(event->type(), tool);
- m_ToolEvents.insert(tool, event);
- }
- /// <summary>
- /// 查询本工具是否绑定了触发事件
- /// </summary>
- /// <param name="pTool"></param>
- bool TaskManager::isToolTriggerable(TOOL* pTool)
- {
- QMutableHashIterator<EVENT_ID, TOOL*> iter(m_EventTools);
- while (iter.hasNext())
- {
- QList<TOOL*> tools = m_EventTools.values(iter.next().key());
- foreach(TOOL * tool, tools)
- {
- if (pTool == tool)
- {
- return true;
- }
- }
- }
- return false;
- }
- /// <summary>
- /// // 删除了一个工具的时候,需要到这里来反注册一下
- /// </summary>
- /// <param name=""></param>
- void TaskManager::unregisterTool(TOOL* pTool)
- {
- QMutableHashIterator<EVENT_ID, TOOL*> iter(m_EventTools);
- while (iter.hasNext())
- {
- QList<TOOL*> tools = m_EventTools.values(iter.next().key());
- foreach(TOOL * tool, tools)
- {
- if (pTool == tool)
- {
- m_EventTools.remove(iter.key(), pTool);
- return;
- }
- }
- }
- m_ToolEvents.remove(pTool);
- }
- /// <summary>
- /// 通过Tool查询ToolEvents信息(目前用于序列化中)
- /// </summary>
- /// <param name="pTool"></param>
- /// <returns></returns>
- ToolEvent* TaskManager::getEventByTool(TOOL* pTool)
- {
- return m_ToolEvents.value(pTool);
- }
- //============================================================
- //
- // Task界面设置 相关
- //
- //============================================================
- /// <summary>
- /// 设置tool为Busy状态
- /// </summary>
- /// <param name="pTool"></param>
- /// <param name="pView"></param>
- void TaskManager::setToolBusy(const POU* pPou, TOOL* pTool, WindowAppTaskView* pView)
- {
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
- emit pView->sigUpdateToolStatus(pPou, pTool);
- }
- /// <summary>
- /// 设置tool为完成状态
- /// </summary>
- /// <param name="pTool"></param>
- void TaskManager::setToolDone(
- POU* pPou,
- TOOL* pTool,
- QElapsedTimer& toolTimer,
- WindowAppTaskView* pView
- )
- {
- int nTimer = toolTimer.elapsed();
- // 统计Tool执行时间
- pTool->execParams.nExecTime = nTimer;
- // Tool Done
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- // 2022-8-29 由于执行次数各个工具内部的情况都不一样,干脆还是直接改回工具内部处理了
- //// 正常情况下,Tool 执行次数+1(需要排除掉Goto和ForLoop特殊处理)
- //if ((!pTool->isGotoTool()) && (!pTool->isForloopTool()))
- //{
- // pTool->execParams.nExecCount++;
- //}
- //// 2022-4-6增加,Goto工具只有在执行了Goto动作后执行次数才会 +1
- //else if (pTool->isGotoTool()
- // && pTool->execParams.nRetValue == VPEnum::RETURN_VALUE::Goto)
- //{
- // pTool->execParams.nExecCount++;
- //}
- //// 2022-8-28 增加,ForLoop工具的执行计数需要按照其循环执行的次数来+,所以只能在ForLoop工具内部处理
- //else if (pTool->isForloopTool())
- //{
- //}
- // 刷新所有表格
- emit pView->sigUpdateAllTables(pPou, pTool);
- }
- /// <summary>
- /// 设置Pou为Busy状态
- /// </summary>
- /// <param name="pPou"></param>
- /// <param name="pView"></param>
- void TaskManager::setPouBusy(POU* pPou, WindowAppTaskView* pView)
- {
- // 将Pou置为busy状态
- pPou->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
- emit pView->sigUpdatePouStatus(pPou);
- // 重置一下Pou的Timer
- pPou->execParams.nExecTime = 0;
- }
- /// <summary>
- /// 设置Pou为完成状态
- /// </summary>
- /// <param name="pPou"></param>
- void TaskManager::setPouDone(POU* pPou, QElapsedTimer& pouTimer, WindowAppTaskView* pView)
- {
- // 将Pou置为完成状态
- pPou->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- // Pou 执行次数+1
- pPou->execParams.nExecCount++;
- // 结束统计Pou执行时间
- pPou->execParams.nExecTime = pouTimer.elapsed();
- VARIABLE* pVar = g_pGvlManager->getVariableByName(pPou->pouName(), INTERNALVAR_NAME_EXECTIME);
- QString strValue = pVar->getValueString();
- // 更新一下Pou表格和Task表格
- emit pView->sigUpdatePouTable(pPou);
- // 2022-3-21,检查Pou内部变量是否绑定了复杂控件的索引(或刷新)并执行更新
- this->syncComplexIndexToRuntime(pPou->pouName());
- // 2022-9-10,发送Pou同步消息
- this->syncPouParamsToUi(pPou);
-
- }
- /// <summary>
- /// 设置Task为完成状态
- /// </summary>
- /// <param name="pTask"></param>
- void TaskManager::setTaskDone(TASK* pTask, QElapsedTimer& taskTimer, WindowAppTaskView* pView)
- {
- // 全部Pou执行完毕后,将Task置为Done状态
- pTask->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
-
- // Task执行次数 + 1
- pTask->execParams.nExecCount++;
- // 系统中的总执行次数 +1
- thePrefs.m_nRunningCount++;
- // 统计Task执行时间
- pTask->execParams.nExecTime = taskTimer.elapsed();
- // 刷新Task表格
- emit pView->sigUpdateTaskTable();
-
- // 2022-9-10,发送Task同步消息(向UI)
- this->syncTaskAndSystemParamsToUi(pTask);
- // 2022-9-12,检查全局变量是否绑定了复杂控件的索引并执行更新(向Runtime)
- this->syncComplexIndexToRuntime(GROUP_NAME_SYSTEM);
- }
- /// <summary>
- /// 设置Task为就绪状态
- /// </summary>
- /// <param name="pTask"></param>
- void TaskManager::setTaskStandBy(TASK* pTask, WindowAppTaskView* pView)
- {
- // 全部Pou执行完毕后,将Task置为Done状态
- pTask->execParams.nStatus = VPEnum::EXEC_STATUS::StandBy;
- // 刷新Task表格
- emit pView->sigUpdateTaskTable();
- }
- /// <summary>
- /// 2022-9-10,增加了Task完成时的数值触发动作,用于提供给外部进行绑定同步
- /// </summary>
- void TaskManager::syncTaskAndSystemParamsToUi(TASK* pTask)
- {
- SyncValueEvent* valueEvent = new SyncValueEvent();
- // Task执行次数
- VARIABLE* pVar = g_pGvlManager->getVariableByName(GROUP_NAME_SYSTEM, pTask->strName + EXEC_COUNT_POSTFIX);
- valueEvent->addSyncValue(pVar);
- // System执行总次数
- pVar = g_pGvlManager->getVariableByName(GROUP_NAME_SYSTEM, SYSTEMVAR_NAME_EXECCOUNT);
- valueEvent->addSyncValue(pVar);
- // TODO:其他参数由于没有变动,为了提高效率这里就没有触发,也就是说如果绑定其他参数的话,变动的时候应该不会得到同步
- // 更合理的方式应该是在其他变量变动的时候再同步即可,放在这里效率有点低了
- // post数值同步消息,post内部会自动释放event的指针,无需手工释放
- QCoreApplication::postEvent((QObject*)g_pUiManager, valueEvent);
- }
- /// <summary>
- /// 2022-9-10,增加了Pou完成时的数值触发动作,用于提供给外部进行绑定同步
- /// </summary>
- void TaskManager::syncPouParamsToUi(POU* pPou)
- {
- SyncValueEvent* valueEvent = new SyncValueEvent();
- // Pou的执行次数
- VARIABLE* pVar = g_pGvlManager->getVariableByName(pPou->pouName(), INTERNALVAR_NAME_EXECCOUNT);
- valueEvent->addSyncValue(pVar);
- // Pou执行时间
- pVar = g_pGvlManager->getVariableByName(pPou->pouName(), INTERNALVAR_NAME_EXECTIME);
- valueEvent->addSyncValue(pVar);
- // post数值同步消息,post内部会自动释放event的指针,无需手工释放
- QCoreApplication::postEvent((QObject*)g_pUiManager, valueEvent);
- }
- //============================================================
- //
- // Event 相关
- //
- //============================================================
- /// <summary>
- /// 初始化系统事件
- /// </summary>
- void TaskManager::initSysEvents()
- {
- // 为了统一事件触发机制,把系统内置变量的Event机制进行了重写
- _INTERFACE* newEventInf = new _INTERFACE(nullptr);
- // Task_loop(为了统一也作为一个事件,但是指针为nullptr)
- newEventInf->strName = (TASK_MODE_LOOP);
- newEventInf->strFullName = (TASK_MODE_LOOP);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = nullptr;
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // Task Run
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_RUN);
- newEventInf->strFullName = (TASK_MODE_EVENT_RUN);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // Task Stop
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_STOP);
- newEventInf->strFullName = (TASK_MODE_EVENT_STOP);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // Sys Exit
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_EXIT);
- newEventInf->strFullName = (TASK_MODE_EVENT_EXIT);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // Load Doc
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_DOCLOADED);
- newEventInf->strFullName = (TASK_MODE_EVENT_DOCLOADED);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // 100ms
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_TIME_100MS);
- newEventInf->strFullName = (TASK_MODE_EVENT_TIME_100MS);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // 500ms
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_TIME_500MS);
- newEventInf->strFullName = (TASK_MODE_EVENT_TIME_500MS);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // 1s
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_TIME_1S);
- newEventInf->strFullName = (TASK_MODE_EVENT_TIME_1S);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // 5s
- newEventInf = new _INTERFACE(nullptr);
- newEventInf->strName = (TASK_MODE_EVENT_TIME_5S);
- newEventInf->strFullName = (TASK_MODE_EVENT_TIME_5S);
- newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- newEventInf->Type = INF_TYPE::INF_TYPE_EVENT;
- newEventInf->eventTrigger = new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TASK_TRIGGER);
- m_sysEvents.insert(newEventInf->strFullName, newEventInf);
- // Old
- //// 构造Event类型的接口,为了和Tool中的Event接口统一
- //_INTERFACE* newEventInf = new _INTERFACE(nullptr);
- //// Task_loop(为了统一也作为一个事件,但是指针为nullptr)
- //newEventInf->strName = (TASK_MODE_LOOP);
- //newEventInf->strFullName = (TASK_MODE_LOOP);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = nullptr;
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// Task Run
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_RUN);
- //newEventInf->strFullName = (TASK_MODE_EVENT_RUN);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// Task Stop
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_STOP);
- //newEventInf->strFullName = (TASK_MODE_EVENT_STOP);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// Sys Exit
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_EXIT);
- //newEventInf->strFullName = (TASK_MODE_EVENT_EXIT);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// Load Doc
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_DOCLOADED);
- //newEventInf->strFullName = (TASK_MODE_EVENT_DOCLOADED);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// 100ms
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_TIME_100MS);
- //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_100MS);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// 500ms
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_TIME_500MS);
- //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_500MS);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// 1s
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_TIME_1S);
- //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_1S);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- //// 5s
- //newEventInf = new _INTERFACE(nullptr);
- //newEventInf->strName = (TASK_MODE_EVENT_TIME_5S);
- //newEventInf->strFullName = (TASK_MODE_EVENT_TIME_5S);
- //newEventInf->Direction = INF_DIRECTION::INF_DIR_OUT;
- //newEventInf->Type = INF_TYPE::INF_TYPE_STANDARD;
- //newEventInf->value.passMode = VALUE_PASS_MODE::PASS_BY_VALUE;
- //newEventInf->value.type = VALUE_TYPE::Type_Event;
- //newEventInf->value.Ptr = (void**)(
- // new ToolEvent(GROUP_NAME_SYSTEMEVENT, newEventInf->strFullName, TOOL_EVENT_TYPE::TRIGGER_TASK_THREAD)
- // );
- //m_sysModes.insert(newEventInf->strName, newEventInf);
- }
- /// <summary>
- /// 定时器Even事件
- /// </summary>
- void TaskManager::onEventTimer()
- {
- // 100ms
- if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_100MS))
- {
- ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_100MS)->eventTrigger;
- QCoreApplication::sendEvent(this, pEvent);
- }
- // 500ms
- if (m_nTimerCounter % 5 == 0)
- {
- if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_500MS))
- {
- ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_500MS)->eventTrigger;
- QCoreApplication::sendEvent(this, pEvent);
- }
- }
- //1s
- if (m_nTimerCounter % 10 == 0)
- {
- if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_1S))
- {
- ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_1S)->eventTrigger;
- QCoreApplication::sendEvent(this, pEvent);
- }
- }
- //5s
- if (m_nTimerCounter % 50 == 0)
- {
- if (m_sysEvents.contains(TASK_MODE_EVENT_TIME_5S))
- {
- ToolEvent* pEvent = (ToolEvent*)m_sysEvents.value(TASK_MODE_EVENT_TIME_5S)->eventTrigger;
- QCoreApplication::sendEvent(this, pEvent);
- }
- }
- m_nTimerCounter++;
- }
- /// <summary>
- /// 等待event触发
- /// </summary>
- /// <param name="event"></param>
- /// <returns></returns>
- void TaskManager::customEvent(QEvent* event)
- {
- ToolEvent* pToolEvent = dynamic_cast<ToolEvent*>(event);
- // 判断事件类型
- if (pToolEvent->getExType() == TOOL_EVENT_TYPE::TOOL_TRIGGER)
- {
- // 即执行当前工具
- VPEnum::RETURN_VALUE ret = ExecuteTool(pToolEvent);
- pToolEvent->ret = ret;
- }
- else if (pToolEvent->getExType() == TOOL_EVENT_TYPE::TASK_TRIGGER)
- {
- // 先查找是否有匹配的Task,发送Task触发指令
- this->triggerTaskThread(pToolEvent);
- // 2022-9-4,由于事件还有可能触发Wait工具,还需要和Tool匹配一下
- this->triggerToolExecution(pToolEvent);
- }
- // Error,不应该走到这里
- else
- {
- vDebug() << "[Error] Unsupport ToolEvent Type: " << (short)pToolEvent->getExType();
- }
- event->accept();
- }
- /// <summary>
- /// 执行对应的工具
- /// </summary>
- /// <param name="pToolEvent"></param>
- VPEnum::RETURN_VALUE TaskManager::ExecuteTool(ToolEvent* pToolEvent)
- {
- if (pToolEvent == nullptr /*|| m_TaskEvents.size() <= 0*/)
- {
- return VPEnum::RETURN_VALUE::None;
- }
- //qDebug() << "[EVENT] event[" << pToolEvent->name() << "] activate.";
- QMap<QString, POU*>& allPous = g_pPouManager->getAllPous();
- // 遍历所有的Pou信息
- QMapIterator<QString, POU*> it(allPous);
- while (it.hasNext())
- {
- POU* pPou = it.next().value();
- //pPou->m_pParentTask = nullptr;
- if (pPou->pouName() == pToolEvent->groupName())
- {
- TOOL* pTool = pPou->GetToolByName(pToolEvent->name());
- if (pTool)
- {
- // 在PouManaer中执行本工具
- VPEnum::RETURN_VALUE ret = pPou->ToolExecuteStandard(pTool);
- //qWarning() << "ok";
- return ret;
- }
- }
- }
- return VPEnum::RETURN_VALUE::None;
- }
- /// <summary>
- /// 给Task 发送执行指令
- /// </summary>
- /// <param name="pToolEvent"></param>
- void TaskManager::triggerTaskThread(ToolEvent* pToolEvent)
- {
- if (pToolEvent == nullptr || m_EventTasks.size() <= 0)
- {
- return;
- }
- // 查找本事件是否有对应的Task触发(一个事件可能会对应着多个Task)
- QList<TASK*> tasks = m_EventTasks.values(pToolEvent->type());
- for (TASK* pTask : tasks)
- {
- // 如果Task没有处于busy状态, 则通知事件执行
- if (pTask->execParams.nStatus != VPEnum::EXEC_STATUS::Busy)
- {
- pTask->activator.wakeAll();
- }
- else
- {
- // 否则触发失败的次数+1
- pTask->execParams.nTriggerFailedCount++;
- //qWarning() << "[EVENT] Warning: event[" << pToolEvent->name() << "] activate, but task[" << pTask->strName << "] is busy.";
- }
- }
- //qDebug() << "[EVENT] event[" << pToolEvent->name() << "] activate.";
- //// 查找本事件是否有对应的Task触发(一个事件可能会对应着多个Task)
- //QList<TASK*> tasks = m_TaskEvents.values(pToolEvent->type());
- ////if (tasks.size() > 0)
- ////{
- // for (TASK* pTask : tasks)
- // {
- // // 如果Task没有处于busy状态, 则通知事件执行
- // if (pTask->execParams.nStatus != VPEnum::EXEC_STATUS::Busy)
- // {
- // pTask->activator.wakeAll();
- // }
- // else
- // {
- // // 否则触发失败的次数+1
- // pTask->execParams.nTriggerFailedCount++;
- // //qWarning() << "[EVENT] Warning: event[" << pToolEvent->name() << "] activate, but task[" << pTask->strName << "] is busy.";
- // }
- // }
- ////}
- ////else
- ////{
- // //qWarning() << "[EVENT] Warning: TaskManager:: event[" << pToolEvent->name() << "] activate, but can not find task.";
- ////}
- }
- /// <summary>
- /// 2022-9-4 ToolEvent还可以同时触发Tool执行
- /// (目前只有Wait工具可以触发,但是为了以后扩展,这里并没有写死,理论上是所有工具都能触发)
- /// </summary>
- /// <param name="pToolEvent"></param>
- void TaskManager::triggerToolExecution(ToolEvent* pToolEvent)
- {
- if (pToolEvent == nullptr || m_EventTools.size() <= 0)
- {
- return;
- }
- // 查找本事件是否有对应的Task触发(一个事件可能会对应着多个Tool)
- QList<TOOL*> tools = m_EventTools.values(pToolEvent->type());
- for (TOOL* pTool : tools)
- {
- //// 如果Tool没有处于busy状态, 则触发该工具的通知事件
- //if (pTool->execParams.nStatus != VPEnum::EXEC_STATUS::Busy)
- //{
- // 2022-9-25 增加,如果是Wait工具,那么需要判断一下这个Wait工具是否需要等待某一个值来触发,并且判断值是否命中
- if (pTool->isWaitTool() && !this->isWaitToolHit(pTool, pToolEvent))
- {
- // 如果没有命中,则跳过此工具触发
- continue;
- }
- // 如果不是WaitTool,或者是WaitTool并且值命中,则触发该工具的事件
- pTool->activator.wakeAll();
- // }
- }
- }
- /// <summary>
- /// 处理本轮中涉及到绑定至复杂控件中的变量,包括全局变量、Pou内部变量等(向Runtime触发)
- /// Reason:在所有Tool执行完一轮之后,需要检查一下Pou的内部变量是否有用做复杂控件的Index的,需要安排触发一下
- /// Reason2:每轮Task执行完毕之后,也需要安排触发一下
- /// </summary>
- /// <param name="strName"></param>
- void TaskManager::syncComplexIndexToRuntime(QString strGroupName)
- {
- GVL* pGVL = g_pGvlManager->getGvl(strGroupName);
- // 将作为索引的Pou内部变量添加到同步列表中
- QList<VARIABLE*> syncComplexIndexes;
- if (pGVL != nullptr)
- {
- const VARIABLES& vars = pGVL->Variables;
- for (/*const*/ VARIABLE* var : vars)
- {
- if (var->bComplexLinkIndex)
- {
- syncComplexIndexes.push_back(var);
- }
- }
- }
- // 2021-12-15 进行复杂控件索引到Runtime的推送
- if (syncComplexIndexes.size() > 0)
- {
- SyncValueEvent* valueEvent = new SyncValueEvent();
- // 携带需要同步的多个接口
- valueEvent->setSyncValues(syncComplexIndexes);
- // post数值同步消息,post内部会自动释放event的指针,无需手工释放
- QCoreApplication::postEvent((QObject*)g_pRuntime, valueEvent);
- }
- }
- /// <summary>
- /// 2022-9-25 WaitTool专用,判断Wait工具是否需要等待某一个值,并且这个值是否已经命中
- /// </summary>
- /// <param name="pTool"></param>
- /// <returns></returns>
- bool TaskManager::isWaitToolHit(TOOL* pTool, ToolEvent* toolEvent)
- {
- // 需要从Pou中找到这个Tool对应的Block,参数存在BlockItem里面
- POU* pou = g_pPouManager->getPouByName(pTool->strPouName);
- VALUE* waitValue = pou->getWaitToolValue(pTool);
- // 检查是否需要等待Value,如果不需要等待,直接返回命中
- if (waitValue == nullptr
- || waitValue->type == VALUE_TYPE::Type_Unknown
- || waitValue->Ptr == nullptr
- || toolEvent->m_triggerValue.isNullptr()
- )
- {
- return true;
- }
- vDebug() << "WaitTool : waitValue[" << waitValue->toString() << "]-eventValue[" << toolEvent->m_triggerValue.toString() << "].";
- // 如果需要等待Value,那么检测这个Value是否命中,此处用到了重载的==
- if (*waitValue == toolEvent->m_triggerValue)
- {
-
- return true;
- }
- return false;
- }
- //============================================================
- //
- // 并行 线程
- //
- //============================================================
- /// <summary>
- /// 线程函数
- /// </summary>
- void _TaskThread::run()
- {
- // 调用函数执行任务
- g_pTaskManager->_executeTask(m_pRunningTask);
- qDebug() << "[TASK][Thread] ThreadPool [" << m_pRunningTask->strName << "] exit.";
- }
|