123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743 |
- #include "Pou.h"
- #include "WindowAppItemInterface.h"
- #include "WindowAppBlockStandard.h"
- #include "WindowAppBlockStandardBase.h"
- #include "WindowAppBlockGoto.h"
- #include "WindowAppBlockWait.h"
- #include "WindowAppVariableTable.h"
- #include "GvlManager.h"
- #include "TaskManager.h"
- #include "WindowAppTaskView.h"
- #include "WindowAppPouScene.h"
- #include "WindowAppPouFrame.h"
- #include "../Common/CameraBaseClass/IBaseCamCommon.h"
- #include "../Common/CameraBaseClass/IBaseCamera.h"
- //======================================================================
- //
- // 与Pou执行相关的函数集合
- //
- //======================================================================
- /// <summary>
- /// 2022-9-6,执行前预检查
- /// </summary>
- /// <param name="pTool"></param>
- /// <param name="runMode"></param>
- /// <returns></returns>
- VPEnum::RETURN_VALUE POU::ToolExecutionDispatcherPreCheck(TOOL*& pTool, TOOL_RUN_MODE runMode)
- {
- Q_UNUSED(runMode);
- // 如果本工具加入了并行组,则需要特殊处理一下
- if (pTool->isParallelSubTool())
- {
- //// 如果处于并行模式下运行,则等待执行信号
- //if (runMode == TOOL_RUN_MODE::IN_PARALLEL)
- //{
- // // 设置Tool为Wait状态
- // pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Wait;
- // vDebug() << "ParallelSubTool [" << pTool->strInstanceName << "] waiting...";
- // pTool->waitForExecution();
- // vDebug() << "ParallelSubTool [" << pTool->strInstanceName << "] waiting finished.";
- //}
- //// 否则,直接跳过执行
- //else
- //{
- vDebug() << "Ignore Tool[" + pTool->strInstanceName + "], reason: isParallelized.";
- return VPEnum::RETURN_VALUE::Abort;
- //}
- }
- // 如果本工具加入了For循环,则跳过执行
- else if (pTool->isForloopSubTool())
- {
- vDebug() << "Ignore Tool[" + pTool->strInstanceName + "], reason: isForlooped.";
- return VPEnum::RETURN_VALUE::Abort;
- }
- return VPEnum::RETURN_VALUE::Success;
- }
- /// <summary>
- /// 2022-5-1 工具的执行总调度
- /// </summary>
- /// <param name="pTool"></param>
- /// <returns></returns>
- VPEnum::RETURN_VALUE POU::ToolExecutionDispatcher(TOOL*& pTool, TOOL_RUN_MODE runMode)
- {
- VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
- // 执行预检查
- ret = this->ToolExecutionDispatcherPreCheck(pTool, runMode);
- if (ret != VPEnum::RETURN_VALUE::Success)
- {
- return ret;
- }
- // 正常流程
- // 设置Tool为Busy状态
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
-
- // 执行标准工具
- if (pTool->isStandardTool())
- {
- ret = this->ToolExecuteStandard(pTool);
- }
- // 执行Goto工具
- else if (pTool->isGotoTool())
- {
- int nNextIndex = 0;
- // 执行Goto工具
- ret = this->ToolExecuteGoto(pTool, nNextIndex);
- // TODO:此处是否需要跳转到下一个工具继续执行
- if (ret == VPEnum::RETURN_VALUE::Goto)
- {
- TOOL* pNextTool = m_StandardTools[nNextIndex];
- ret = this->ToolExecuteStandard(pNextTool);
- }
- }
- // 执行并行工具
- else if (pTool->isParallelTool())
- {
- ret = this->ToolExecuteParallel(pTool);
- }
- // 执行ForLoop工具
- else if (pTool->isForloopTool())
- {
- ret = this->ToolExecuteForloop(pTool);
- }
- // 执行Wait工具
- else if (pTool->isWaitTool())
- {
- ret = this->ToolExecuteWait(pTool, runMode);
- }
- else
- {
- qDebug() << "[Error] POU::ToolExecute - Unknown tool type:" << (short)pTool->Type;
- ret = VPEnum::RETURN_VALUE::Error;
- }
- // 设置Tool为完成状态
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- return ret;
- }
- /// <summary>
- /// 2022-5-1 工具的执行总调度(Task中使用,关联执行序号)
- /// </summary>
- /// <param name="pTool"></param>
- /// <param name="index"></param>
- /// <returns></returns>
- VPEnum::RETURN_VALUE POU::ToolExecutionDispatcher(TOOL*& pTool, int& index, TOOL_RUN_MODE runMode)
- {
- VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
-
- // 执行预检查
- ret = this->ToolExecutionDispatcherPreCheck(pTool, runMode);
- if (ret != VPEnum::RETURN_VALUE::Success)
- {
- return ret;
- }
- // 设置Tool为Busy状态
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
- // 如果是标准工具,正常执行
- if (pTool->isStandardTool())
- {
- ret = this->ToolExecuteStandard(pTool);
- index++;
- }
- // 如果是Goto工具,要做跳转
- else if (pTool->isGotoTool())
- {
- // 执行Goto
- ret = this->ToolExecuteGoto(pTool, index);
- // 如果执行过程中没有发生跳转,那么继续执行下一个工具
- if (ret != VPEnum::RETURN_VALUE::Goto)
- {
- index++;
- }
- }
- // 如果是并行工具,则并行执行
- else if (pTool->isParallelTool())
- {
- ret = this->ToolExecuteParallel(pTool);
- index++;
- }
- // 如果是For循环工具,则执行For循环
- else if (pTool->isForloopTool())
- {
- ret = this->ToolExecuteForloop(pTool);
- index++;
- }
- // 如果是Wait工具,则执行等待
- else if (pTool->isWaitTool())
- {
- ret = this->ToolExecuteWait(pTool, runMode);
- index++;
- }
- // 设置Tool为完成状态
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- return ret;
- }
- ///// <summary>
- ///// 执行当前工具
- ///// </summary>
- ///// <param name="pBlockItem"></param>
- //VPEnum::RETURN_VALUE POU::ToolExecuteStandard(WindowAppBlockStandardBase* pBlockItem)
- //{
- // // 重置所有工具执行状态
- // ResetToolExecCode();
- //
- // TOOL* pActiveTool = m_itemToTools.value(pBlockItem);
- //
- // // 交给调度器执行
- // return this->ToolExecutionDispatcher(pActiveTool);
- //}
- /// <summary>
- /// 执行当前工具
- /// </summary>
- /// <param name="pActiveTool"></param>
- VPEnum::RETURN_VALUE POU::ToolExecuteStandard(TOOL* pActiveTool)
- {
- VPEnum::RETURN_VALUE nRet = VPEnum::RETURN_VALUE::None;
- if (pActiveTool == nullptr)
- {
- qDebug() << "[Error] [POU:" << m_strPouName << "] ToolExecuteStandard failed: pActiveTool is nullptr.";
- return VPEnum::RETURN_VALUE::Error;
- }
- // Execute前更新上连接口
- nRet = this->ToolPreExecute(pActiveTool);
- // TODO:此处是否需要处理更新上行接口的执行结果
- // 然后执行本工具的Execute
- if (pActiveTool->pDllPtr != nullptr)
- {
- nRet = pActiveTool->pDllPtr->Execute();
- }
- else
- {
- qDebug() << "[POU:" << m_strPouName << "][Tool:" << pActiveTool->strInstanceName << "] executed finished.";
- }
-
- // 在窗体可见时候,才调用调试窗口。以便在后台运行的时候,提高运行速度
- if (this->parentScene()->parentFrame()->isVisible())
- {
- try
- {
- DebugData data = pActiveTool->pDllPtr->GetDebugData();
- this->parentScene()->parentFrame()->UpdataDebugData(data);
- }
- catch (...){ }
- }
-
- // 保存工具执行返回值
- pActiveTool->execParams.nRetValue = nRet;
- // 如果返回值不是成功的话,就需要加一个错误计数(Pou和Tool的都需要+1)
- if (nRet != VPEnum::RETURN_VALUE::Success)
- {
- pActiveTool->execParams.nErrorCount++;
- this->execParams.nErrorCount++;
- }
- // Execute后更新下连接口
- /*nRet =*/ this->ToolPostExecute(pActiveTool);
- //// 根据是否在Task中执行,输出不同的log
- //if (m_pParentTask == nullptr)
- //{
- qDebug() << "[POU:" << m_strPouName << "][Tool:" << pActiveTool->strInstanceName
- << "][Index:" << pActiveTool->nIndex << "] executed finished.";
- //}
- // 执行完之后,重绘一下此工具,用于功能块的状态显示
- WindowAppBlockBase* pBlock = this->m_instNameToToolItems[pActiveTool->strInstanceName];
- pBlock->update();
- // 执行计数 +1
- pActiveTool->execParams.nExecCount++;
- return nRet;
- }
- /// <summary>
- /// Execute前更新上连接口
- /// </summary>
- VPEnum::RETURN_VALUE POU::ToolPreExecute(TOOL* pActiveTool)
- {
- VPEnum::RETURN_VALUE nRet = VPEnum::RETURN_VALUE::None;
- // qDebug() << "[POU] Execute tool start ------- " << pActiveTool->strInstanceName;
- // 先检查一下所有的输入接口
- for (_INTERFACE* pInf : pActiveTool->Interfaces)
- {
- // 2022-4-30,跳过Tool类型接口(尽管这种情况不会出现,但是以防万一还是加上)
- if (pInf->isToolInterface())
- {
- continue;
- }
- // 如果本接口有link连接的话,需要先到link那边去取值
- if (pInf->Direction == INF_DIRECTION::INF_DIR_IN
- && pInf->pUpLinkInterface != nullptr)
- {
- // 从工具Dll中更新值
- if (pInf->pUpLinkInterface->Type == INF_TYPE::INF_TYPE_STANDARD)
- {
- // 2022-8-26增加,由于标准接口的情况分为两种,一种是dll工具,还有一种是系统内置工具,所以这里要区分一下
-
- // 如果上联工具为标准工具,则从Dll中更新值(这里这里要用realParent,防止Port工具绑定的情况)
- if (pInf->pUpLinkInterface->realParent()->Type == TOOL_TYPE::TOOL_TYPE_STANDARD)
- {
- QString strValueString = updateInterfaceValue(pInf, UPDATE_VALUE_MODE::MODE_FROM_TOOL);
- if (!strValueString.isEmpty())
- {
- qDebug() << "[POU] updateInterfaceValue from up link dll[" << pInf->strFullName << "], Value:" << strValueString;
- }
- else
- {
- // return nRet;
- continue;
- }
- }
- // 2022-8-26 是否应该是内置工具,直接从接口中取值,和变量一样
- else
- {
- QString strValueString = updateInterfaceValue(pInf, UPDATE_VALUE_MODE::MODE_FROM_VARIABLE);
- if (!strValueString.isEmpty())
- {
- qDebug() << "[POU] updateInterfaceValue from up link internal[" << pInf->strFullName << "], Value:" << strValueString;
- }
- else
- {
- // return nRet;
- continue;
- }
- }
- }
- // 从变量中更新值
- else if (pInf->pUpLinkInterface->Type == INF_TYPE::INF_TYPE_VALUE)
- {
- // 判断下上联的端口(全局变量组或者局部变量组)是否存在
- TOOL* pGvl = pInf->pUpLinkInterface->bindedParent();
- // 如果查询到了对应的变量组
- if (pGvl != nullptr)
- {
- QString strValueString = updateInterfaceValue(pInf, UPDATE_VALUE_MODE::MODE_FROM_VARIABLE);
- if (!strValueString.isEmpty())
- {
- qDebug() << "[POU] updateInterfaceValue from up link variable[" << pInf->strFullName << "], Value:" << strValueString;
- }
- else
- {
- // return nRet;
- continue;
- }
- }
- // 没查询到对应的全局变量或局部变量
- else
- {
- // 把端口的状态设置为Error
- TOOL* pPort = pInf->pUpLinkInterface->parent();
- if (pPort != nullptr)
- {
- pPort->setPortError();
- }
- QString strErrorMsg = pInf->pUpLinkInterface->strName + " ----------->" +
- pActiveTool->strInstanceName + "." + pInf->strName;
- qWarning() << strErrorMsg << "Error";
- }
- }
- // 2022-3-25 增加一个错误处理(此处屏蔽,因为有Goto连接到Tool的时候,一定会走到这里)
- else
- {
- qWarning() << "[Warning] POU::ToolPreExecute - Ingore value update, invalid interface category:" << (short)pInf->pUpLinkInterface->Type;
- }
- }
- }
- // 加上前延时
- Utility::qSleep(pActiveTool->execParams.nPreDelay);
- return nRet;
- }
- /// <summary>
- /// Execute后更新下连接口
- /// MEMO:对于Tool的接口来说不需要更新下联接口,但是对于Value类型,是需要更新下联接口的
- /// </summary>
- VPEnum::RETURN_VALUE POU::ToolPostExecute(TOOL* pActiveTool)
- {
- VPEnum::RETURN_VALUE nRet = VPEnum::RETURN_VALUE::None;
- // 加上后延时
- Utility::qSleep(pActiveTool->execParams.nPostDelay);
- // qDebug() << "[POU] Execute tool - " << pActiveTool->strInstanceName << " Index - " << pActiveTool->nIndex;
- // LOG("[POU] Execute tool - {} , index - {}.", pActiveTool->strInstanceName.toStdString(), pActiveTool->nIndex);
- // 2021-11-9,添加要向UI同步的接口
- QList<_INTERFACE*> syncInfs;
- // 2021-11-14,添加要向界面表格同步的接口
- QList<VARIABLE*> syncValues;
- // 2021-12-12,添加要向复杂控件同步的接口(直接发向Runtime)
- // 复杂控件的同步机制就是直接从Pou中索引链接的数值变动直接向Runtime触发的
- QList<VARIABLE*> syncComplexIndexes;
- // 2021-5-29添加,execute完毕之后,如果有下联接口是Value类型的话(全局变量或局部变量)
- // 需要额外更新一下Value的值
- for (_INTERFACE* pInf : pActiveTool->Interfaces)
- {
- // 2022-4-30,跳过Top类型
- // REASON: 因为Top类型都是用来下联Tool的,不需要执行更新
- if (pInf->isToolEnd())
- {
- continue;
- }
- QVector<_INTERFACE*> pDownLinks = pInf->pDownLinkInterfaces;
- // 增加需要同步到Runtime的接口信息
- if (pInf->bDataLink)
- {
- syncInfs.push_back(pInf);
- }
- // 2021-12-15 如果是复杂控件索引,加入推送通知列表中
- if (pInf->bComplexLinkIndex)
- {
- syncComplexIndexes.push_back(pInf);
- }
- // 遍历所有的下联接口
- for (int i = 0; i < pDownLinks.size(); i++)
- {
- _INTERFACE* pDownInf = pDownLinks[i];
- // 只需要更新数值类型的输出接口
- if (pInf->Direction == INF_DIRECTION::INF_DIR_OUT
- && pDownInf->Type == INF_TYPE::INF_TYPE_VALUE)
- {
- // 判断下上联的端口(全局变量组或者局部变量组)是否存在
- TOOL* pGvl = pDownInf->bindedParent();
- if (pGvl != nullptr)
- {
- // 将值更新到下接接口中
- QString strValueString = updateInterfaceValue(pDownInf, UPDATE_VALUE_MODE::MODE_TO_VARIABLE);
- if (strValueString.isEmpty())
- {
- // return nRet;
- continue;
- }
- qDebug() << "[POU] updateInterfaceValue to down link value - " << pDownInf->strFullName;
- }
- else
- // 没查询到对应的全局变量或局部变量
- {
- // 把端口的状态设置为Error
- TOOL* pPort = pDownInf->parent();
- if (pPort != nullptr)
- {
- pPort->setPortError();
- }
- QString strErrorMsg =
- pActiveTool->strInstanceName + "." + pInf->strName +
- " ----------->" +
- pDownInf->strName;
- qWarning() << strErrorMsg << "Error";
- }
- // 添加需要刷新到变量界面表格的接口
- syncValues.push_back(pDownInf);
- // 添加需要刷新到界面的接口
- if (pDownInf->bDataLink)
- {
- syncInfs.push_back(pDownInf);
- }
- // 2021-12-15 如果是复杂控件索引,加入推送通知列表中
- if (pDownInf->bComplexLinkIndex)
- {
- syncComplexIndexes.push_back(pInf);
- }
- }
- }
- }
- // 2021-11-14 增加,一次性使用postEvent异步刷新所有变量界面表格
- if (syncValues.size() > 0)
- {
- syncValuesToTableUI(syncValues);
- }
- // 如果需要的话,则向UI同步(只有非硬件工具才触发execute后的更新动作)
- if (syncInfs.size() > 0 && !pActiveTool->isHardwareTool())
- {
- syncValuesToUi(syncInfs);
- }
- // 2021-12-15 进行复杂控件索引到Runtime的推送
- if (syncComplexIndexes.size() > 0)
- {
- syncComplexIndexesToRuntime(syncComplexIndexes);
- }
- return nRet;
- }
- /// <summary>
- /// 执行Goto工具(应该为内部工具专门设计一套数据结构,暂时先放在这里)
- /// </summary>
- /// <param name="pGoto"></param>
- /// <param name="index">goto的下一步跳转目标</param>
- VPEnum::RETURN_VALUE POU::ToolExecuteGoto(TOOL* pTool, int& index)
- {
- // 是否执行了跳转
- VPEnum::RETURN_VALUE nRet = VPEnum::RETURN_VALUE::None;
- // Execute前更新上连接口
- nRet = this->ToolPreExecute(pTool);
- // TODO:此处是否需要处理上联接口状态
- //// 如果返回值不是成功的话,就需要加一个错误计数(Pou和Tool的都需要+1)
- //if (nRet != VPEnum::RETURN_VALUE::Success)
- //{
- // pGoto->execParams.nErrorCount++;
- // this->execParams.nErrorCount++;
- //}
- // 然后开始执行Goto的内部逻辑
- // 如果这个Goto已经绑定了工具
- if (pTool->Interfaces[GOTO_OUTPUT_INDX]->isBinded())
- {
- // 获取输入接口的值
- bool bInput = false;
- if (pTool->Interfaces[GOTO_INPUT_INDX]->value.Ptr != nullptr)
- {
- bInput = pTool->Interfaces[GOTO_INPUT_INDX]->value.getValue<bool>();
- }
- // 然后根据取反位决定是否执行跳转
- WindowAppBlockGoto* pGotoBlock = qgraphicsitem_cast<WindowAppBlockGoto*>(m_instNameToToolItems[pTool->strInstanceName]);
- bool bNegation = pGotoBlock->m_bNegation;
- bool bJmp = false;
- // 是否取反
- bNegation ? bJmp = !bInput : bJmp = bInput;
- if (bJmp)
- {
- // 执行跳转
- // index = pGoto->Interfaces[1]->bindedParent()->nIndex;
- // 取出跳转的Tool
- QString strToolName = pTool->Interfaces[GOTO_OUTPUT_INDX]->pBindInterface->strName;
- TOOL* pGotoTool = this->GetToolByName(strToolName);
- if (pGotoTool != nullptr)
- {
- index = pGotoTool->nIndex;
- // 设置Goto工具状态
- pGotoTool->execParams.nRetValue = VPEnum::RETURN_VALUE::Goto;
- // Goto工具只有执行跳转,执行计数才会 +1
- pGotoTool->execParams.nExecCount++;
- //qDebug() << "[POU] Execute Goto tool - " << pGoto->strInstanceName << " Index[" << pGoto->nIndex
- // << "] Goto Index[" << index << "].";
- if (m_pParentTask == nullptr)
- {
- qDebug() << "[POU:" << m_strPouName << "][Tool:" << pGotoTool->strInstanceName
- << "][Index:" << pGotoTool->nIndex << "] executed finished: GOTO Index[" << index << "].";
- }
- // 返回跳转标志
- return VPEnum::RETURN_VALUE::Goto;
- }
- }
- }
- // 不执行跳转
- qDebug() << "[POU:" << m_strPouName << "][Tool:" << pTool->strInstanceName
- << "][Index:" << pTool->nIndex << "] executed finished: but not GOTO.";
- //// 根据是否在Task中执行,输出不同的log
- //if (m_pParentTask != nullptr)
- //{
- // qDebug() << "[TASK:" << m_pParentTask->strName << "][POU:" << m_strGroup << "][Tool:" << pGoto->strInstanceName << "] executed finished.";
- //}
- //else
- //{
- // qDebug() << "[TASK:null][POU:" << m_strGroup << "][Tool:" << pGoto->strInstanceName << "] executed finished.";
- //}
- // 设置Goto工具状态
- pTool->execParams.nRetValue = VPEnum::RETURN_VALUE::Success;
- return VPEnum::RETURN_VALUE::Success;;
- }
- /// <summary>
- /// 2022-4-30 执行Parallel工具
- /// </summary>
- /// <param name="pTool"></param>
- /// <returns></returns>
- VPEnum::RETURN_VALUE POU::ToolExecuteParallel(TOOL* pTool)
- {
- // 并行工具一定需要有ToolEnd接口
- Q_ASSERT(pTool->ToolInterfaces.size() >=0 );
- QString strLog;
- // QVector<TOOL*> runningTools;
- // 首先解析出本并行工具组中有几个并行子工具,并且逐一触发执行
- for (auto pDownInf : pTool->ToolInterfaces[INF_END]->pDownLinkInterfaces)
- {
- TOOL* pRunningTool = pDownInf->parent();
- if (pRunningTool == nullptr)
- {
- continue;
- }
- strLog += pRunningTool->strInstanceName + " ";
- // 启动线程执行此工具
- m_ParallelThreadPool.start( new _ParallelThread(this, pRunningTool) );
- //// 触发并行子工具执行
- //pRunningTool->activator.wakeAll();
- //runningTools.push_back(pRunningTool);
-
- }
- //qDebug() << "[POU:" << m_strPouName << "][Parallel:" << pTool->strInstanceName
- // << "] Run parallel tools [" << strLog << "] start.";
- //// 等待所有Tool执行完毕(所有工具都是Done的状态)
- //
- //bool bContinue = true;
- //while (bContinue)
- //{
- // bContinue = false;
- // for (int i = 0; i < runningTools.size(); i++)
- // {
- // if (runningTools[i]->execParams.nStatus == VPEnum::EXEC_STATUS::Busy)
- // {
- // bContinue = true;
- // Utility::qSleep(10);
- // break;
- // }
- // }
- //}
- //qDebug() << "[POU:" << m_strPouName << "][Parallel:" << pTool->strInstanceName
- // << "] Run parallel tools [" << strLog << "] finished.";
- qDebug() << "[POU:" << m_strPouName << "][Parallel:" << pTool->strInstanceName
- << "] Run parallel tools [" << strLog << "] start.";
- // 等待所有线程执行完毕
- m_ParallelThreadPool.waitForDone();
- qDebug() << "[POU:" << m_strPouName << "][Parallel:" << pTool->strInstanceName
- << "] Run parallel tools [" << strLog << "] finished.";
- return VPEnum::RETURN_VALUE::Success;
- }
- /// <summary>
- /// 针对TOOL的index,从小到大排序
- /// </summary>
- /// <param name="a"></param>
- /// <param name="b"></param>
- /// <returns></returns>
- bool sortLoopTool(TOOL*& a, TOOL*& b)
- {
- if (a->nIndex < b->nIndex)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- /// <summary>
- /// 2022-8-25 执行ForLoop工具
- /// </summary>
- /// <param name="pForloopTool"></param>
- /// <returns></returns>
- VPEnum::RETURN_VALUE POU::ToolExecuteForloop(TOOL* pTool)
- {
- // 执行返回值
- VPEnum::RETURN_VALUE nRet = VPEnum::RETURN_VALUE::None;
- // ForLoop工具的计数与其他工具不同,需要在ForLoop工具内部处理运行计数,统计For循环的真正执行次数
- // Execute前首先更新上连接口,获取执行的Size(此处也有可能是通过对话框设置的Size,所以没有上级连接)
- nRet = this->ToolPreExecute(pTool);
- // 如果没有取到上联接口的值,则跳过ForLoop的执行,因为没有Size
- if (pTool->Interfaces[0]->isValueNullptr())
- {
- // 跳过执行
- qDebug() << "[POU:" << m_strPouName << "][Tool:" << pTool->strInstanceName
- << "][Index:" << pTool->nIndex << "] executed ignore: input size is <=0.";
- return VPEnum::RETURN_VALUE::Success;
- }
- // 然后开始执行Forloop的内部逻辑
- // 如果没有下联标准工具,直接跳过执行
- if (pTool->ToolInterfaces[INF_END]->pDownLinkInterfaces.size() <=0 )
- {
- // 跳过执行
- qDebug() << "[POU:" << m_strPouName << "][Tool:" << pTool->strInstanceName
- << "][Index:" << pTool->nIndex << "] executed ignore: invalid standard tool count in forloop.";
- return VPEnum::RETURN_VALUE::Success;
- }
- // 找到所有下联的工具,按照Index排序执行
- QVector<TOOL*> loopTools;
- for (auto& inf : pTool->ToolInterfaces[INF_END]->pDownLinkInterfaces)
- {
- if (inf->parent() != nullptr)
- {
- loopTools.push_back(inf->parent());
- }
- }
- // 按照Index排序(从小到大)
- qSort(loopTools.begin(), loopTools.end(), sortLoopTool);
- // 取出循环的Size(从Size输入接口中取)
- // 0号接口固定为ForLoop工具的Size输入值
- int nSize = pTool->Interfaces[0]->value.toInt();
- // 开始循环执行
- for (int i = 0; i < nSize; i++)
- {
- // 输出当前Index
- // 1号接口固定为ForLoop工具的Index输出值
- pTool->Interfaces[1]->value.setValue<int>(i);
- // 遍历所有For循环内部的工具,依次执行
- for (int toolIndex = 0; toolIndex < loopTools.size(); toolIndex++)
- {
- // 取出当前需要执行的工具
- TOOL* runningTool = loopTools[toolIndex];
- // 执行此工具
- this->ToolExecuteStandard(runningTool);
- qDebug() << "[ForLoop(" << pTool->strInstanceName << ") Index:" << i << "] | [POU:"
- << m_strPouName << "][Tool:" << runningTool->strInstanceName << "] executed finished.";
- }
- // 2022-8-28 ,执行次数 +1
- pTool->execParams.nExecCount++;
- }
- vDebug() << "[POU:" << m_strPouName << "][Forloop:" << pTool->strInstanceName << "] Round[" << nSize << "] finished.";
- // 设置ForLoop工具状态
- pTool->execParams.nRetValue = VPEnum::RETURN_VALUE::Success;
- return nRet;
- }
- /// <summary>
- /// 2022-9-3 执行Wait工具
- /// </summary>
- /// <param name="pTool"></param>
- /// <returns></returns>
- VPEnum::RETURN_VALUE POU::ToolExecuteWait(TOOL* pTool, TOOL_RUN_MODE runMode)
- {
- // WaitBlock指针,用于获取用户设定的功能块执行参数
- WindowAppBlockWait* pWaitBlock = qgraphicsitem_cast<WindowAppBlockWait*>(m_instNameToToolItems[pTool->strInstanceName]);
-
- // 异常
- if (pWaitBlock == nullptr)
- {
- vDebug() << "[Error] pWaitBlock is nullptr.";
- return VPEnum::RETURN_VALUE::Error;
- }
- // 如果处于单步执行状态,需要看一下用户是否选择了单步执行跳过等待
- if (runMode == TOOL_RUN_MODE::SINGLE_STEP)
- {
- if (pWaitBlock->m_bSkipWait)
- {
- vDebug() << "[POU:" << m_strPouName << "][Wait:" << pTool->strInstanceName << "] ignore waiting, reason: m_bSkipWait = true.";
- return VPEnum::RETURN_VALUE::Abort;
- }
- }
- // 如果本Wait工具都没有注册触发事件,则跳过等待
- if (!g_pTaskManager->isToolTriggerable(pTool))
- {
- vDebug() << "[POU:" << m_strPouName << "][Wait:" << pTool->strInstanceName << "] ignore waiting, reason: no event trigger.";
- return VPEnum::RETURN_VALUE::Abort;
- }
- // 启动等待机制
- vDebug() << "[POU:" << m_strPouName << "][Wait:" << pTool->strInstanceName
- << "] start waiting for " << pWaitBlock->m_nTimeout << "ms .......";
- // 设置Tool为Wait状态
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Wait;
- // 2022-9-26,为接口的等待时长计时
- QElapsedTimer waitTimer;
- waitTimer.start();
- // 直接开始等待工具事件触发
- pTool->waitForExecution(pWaitBlock->m_nTimeout);
- // 2022-9-26,然后将本轮等待时长输出到1号接口中
- int nWaitTime = waitTimer.elapsed();
- pTool->Interfaces[1]->value.setValue<int>(nWaitTime);
- // 等待结束,设置Tool为Busy状态
- pTool->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
- vDebug() << "[POU:" << m_strPouName << "][Wait:" << pTool->strInstanceName
- << "] waiting finished, elapse:" << nWaitTime;
- return VPEnum::RETURN_VALUE::Success;
- }
- /// <summary>
- /// BreakPoint
- /// </summary>
- /// <param name="pBlockItem"></param>
- void POU::ToolBreakPoint(WindowAppBlockStandardBase* pBlockItem)
- {
- TOOL* pTool = m_itemToTools.value(pBlockItem);
- if (pTool)
- {
- pTool->bEnableBreakPoint = !pTool->bEnableBreakPoint;
- if (pTool->bEnableBreakPoint)
- {
- qDebug() << "Enable Tool" << pTool->strName << "Enable BreakPoint ";
- }
- }
- }
- /// <summary>
- /// 从当前位置执行
- /// </summary>
- /// <param name="pBlockItem"></param>
- void POU::ToolExecuteSub(WindowAppBlockStandardBase* pBlockItem)
- {
- int nExecuteIndex = m_itemToTools.value(pBlockItem)->nIndex;
- // 从当前序号开始执行
- this->ToolExecuteAll(nExecuteIndex);
- }
- /// <summary>
- /// 全部按顺序执行
- /// </summary>
- void POU::ToolExecuteAll(const int startIndex)
- {
- qDebug() << "[POU:" << this->pouName() << "] ExecuteAll Start...";
- VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
- for (int index = startIndex; index < m_StandardTools.size(); )
- {
- TOOL* pRunningTool = m_StandardTools[index];
- //// 设置为busy状态
- //pRunningTool->execParams.nStatus = VPEnum::EXEC_STATUS::Busy;
- // 交给Pou执行调度器执行
- ret = this->ToolExecutionDispatcher(pRunningTool, index, TOOL_RUN_MODE::SEQUENTIAL);
- //// 设置为完成状态
- //pRunningTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- }
- qDebug() << "[POU:" << this->pouName() << "] ExecuteAll Finish.";
- }
- /// <summary>
- /// 单步执行
- /// </summary>
- void POU::ToolExecuteSingleStep()
- {
- int index = m_nExecuteIndex;
- VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
- if ((index >= 0) && (index < m_StandardTools.size()))
- {
- // 将前一个执行完毕的工具状态设置为Done
- if ((index == 0))
- {
- int nIndex = m_StandardTools.size() - 1;
- TOOL* pRunningTool = m_StandardTools[nIndex];
- pRunningTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- }
- else
- {
- int nIndex = index - 1;
- TOOL* pRunningTool = m_StandardTools[nIndex];
- pRunningTool->execParams.nStatus = VPEnum::EXEC_STATUS::Done;
- }
- TOOL* pRunningTool = m_StandardTools[index];
- // 2022-8-28,通过Dispatcher统一调度执行(以单步执行模式)
- ret = this->ToolExecutionDispatcher(pRunningTool, index, TOOL_RUN_MODE::SINGLE_STEP);
- }
- // 执行指针返回
- m_nExecuteIndex++;
- if (m_StandardTools.size() <= m_nExecuteIndex)
- {
- m_nExecuteIndex = 0;
- }
- }
- /// <summary>
- /// 根据不同的传值情况从dll中取值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="tValue"></param>
- /// <param name="pInf"></param>
- /// <param name="mode"></param>
- template<typename T>
- void POU::MoveValue(T& tValue, _INTERFACE* pInf, UPDATE_VALUE_MODE mode)
- {
- // 被标记为废弃的端口,不参与数据链接
- if (pInf->pUpLinkInterface->Discard != INF_DISCARD::INF_DEFAULT
- || pInf->Discard != INF_DISCARD::INF_DEFAULT
- )
- {
- qWarning() << "[LinkError]" <<
- m_strPouName << "." <<
- pInf->pUpLinkInterface->strFullName << " to " <<
- pInf->strFullName <<
- "Error Interface Is Discard.";
- return;
- }
- if (mode == UPDATE_VALUE_MODE::MODE_FROM_TOOL)
- {
- if (pInf->value.passMode == VALUE_PASS_MODE::PASS_BY_VALUE)
- {
- this->MoveValueByConverter(tValue, pInf->pUpLinkInterface, pInf);
- }
- else
- {
- T& value = GetDllInfValue<T>(pInf->pUpLinkInterface);
- SetDllInfValue(value, pInf);
- tValue = value;
- }
- }
- else if (mode == UPDATE_VALUE_MODE::MODE_FROM_VARIABLE)
- {
- tValue = pInf->pUpLinkInterface->getValue<T>();
- SetDllInfValue(tValue, pInf);
- }
- else if (mode == UPDATE_VALUE_MODE::MODE_TO_VARIABLE)
- {
- tValue = GetDllInfValue<T>(pInf->pUpLinkInterface);
- pInf->setValue(tValue, VALUE_PASS_MODE::PASS_BY_VALUE);
- }
- }
- /// <summary>
- /// 2021-8-24 将基础数据类型转换后,再执行操作
- /// </summary>
- /// <param name="pSrcInf"></param>
- /// <param name="pDstInf"></param>
- template<typename T>
- void POU::MoveValueByConverter(T& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf)
- {
- // 走到这个函数里的,应该都是两种类型相同的接口,那么直接计算即可
- tValue = GetDllInfValue<T>(pSrcInf);
- SetDllInfValue(tValue, pDstInf);
- //// 异常,不应该执行到这里
- //else
- //{
- // qWarning() << "[POU Execute] MoveValueByConverter(), but unknown value type.";
- //}
- }
- /// <summary>
- /// 模板特例化 - 目标类型是QString时(为了实现自动接口数值类型转换)
- /// </summary>
- /// <param name="tValue"></param>
- /// <param name="pSrcInf"></param>
- /// <param name="pDstInf"></param>
- void POU::MoveValueByConverter(QString& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf)
- {
- VALUE_TYPE srcType = pSrcInf->value.type;
- if (srcType == VALUE_TYPE::Type_Int)
- {
- int nValue = GetDllInfValue<int>(pSrcInf);
- tValue = QString::number(nValue);
- }
- // float
- else if (srcType == VALUE_TYPE::Type_Float)
- {
- float fValue = GetDllInfValue<float>(pSrcInf);
- tValue = QString("%1").arg(fValue);
- }
- // double
- else if (srcType == VALUE_TYPE::Type_Double)
- {
- double dValue = GetDllInfValue<double>(pSrcInf);
- tValue = QString("%1").arg(dValue);
- }
- // bool
- else if (srcType == VALUE_TYPE::Type_Bool)
- {
- bool bValue = GetDllInfValue<bool>(pSrcInf);
- tValue = QString("%1").arg(bValue);
- }
- else
- {
- tValue = GetDllInfValue<QString>(pSrcInf);
- }
- SetDllInfValue<QString>(tValue, pDstInf);
- }
- /// <summary>
- /// 模板特例化 - 目标类型是int时(为了实现自动接口数值类型转换)
- /// </summary>
- /// <param name="tValue"></param>
- /// <param name="pSrcInf"></param>
- /// <param name="pDstInf"></param>
- void POU::MoveValueByConverter(int& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf)
- {
- VALUE_TYPE srcType = pSrcInf->value.type;
- // QString
- if (srcType == VALUE_TYPE::Type_String)
- {
- QString strValue = GetDllInfValue<QString>(pSrcInf);
- tValue = strValue.toInt();
- }
- // float
- else if (srcType == VALUE_TYPE::Type_Float)
- {
- float fValue = GetDllInfValue<float>(pSrcInf);
- tValue = static_cast<int>(fValue);
- }
- // double
- else if (srcType == VALUE_TYPE::Type_Double)
- {
- double dValue = GetDllInfValue<double>(pSrcInf);
- tValue = static_cast<int>(dValue);
- }
- // bool
- else if (srcType == VALUE_TYPE::Type_Bool)
- {
- bool bValue = GetDllInfValue<bool>(pSrcInf);
- tValue = static_cast<int>(bValue);
- }
- else
- {
- tValue = GetDllInfValue<int>(pSrcInf);
- }
- SetDllInfValue<int>(tValue, pDstInf);
- }
- /// <summary>
- /// 模板特例化 - 目标类型是float时(为了实现自动接口数值类型转换)
- /// </summary>
- /// <param name="tValue"></param>
- /// <param name="pSrcInf"></param>
- /// <param name="pDstInf"></param>
- void POU::MoveValueByConverter(float& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf)
- {
- VALUE_TYPE srcType = pSrcInf->value.type;
- // QString
- if (srcType == VALUE_TYPE::Type_String)
- {
- QString strValue = GetDllInfValue<QString>(pSrcInf);
- tValue = strValue.toFloat();
- }
- // int
- else if (srcType == VALUE_TYPE::Type_Int)
- {
- int nValue = GetDllInfValue<int>(pSrcInf);
- tValue = static_cast<float>(nValue);
- }
- // double
- else if (srcType == VALUE_TYPE::Type_Double)
- {
- double dValue = GetDllInfValue<double>(pSrcInf);
- tValue = static_cast<float>(dValue);
- }
- // bool
- else if (srcType == VALUE_TYPE::Type_Bool)
- {
- bool bValue = GetDllInfValue<bool>(pSrcInf);
- tValue = static_cast<float>(bValue);
- }
- else
- {
- tValue = GetDllInfValue<float>(pSrcInf);
- }
- SetDllInfValue<float>(tValue, pDstInf);
- }
- /// <summary>
- /// 模板特例化 - 目标类型是double时(为了实现自动接口数值类型转换)
- /// </summary>
- /// <param name="tValue"></param>
- /// <param name="pSrcInf"></param>
- /// <param name="pDstInf"></param>
- void POU::MoveValueByConverter(double& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf)
- {
- VALUE_TYPE srcType = pSrcInf->value.type;
- // QString
- if (srcType == VALUE_TYPE::Type_String)
- {
- QString strValue = GetDllInfValue<QString>(pSrcInf);
- tValue = strValue.toDouble();
- }
- // int
- else if (srcType == VALUE_TYPE::Type_Int)
- {
- int nValue = GetDllInfValue<int>(pSrcInf);
- tValue = static_cast<double>(nValue);
- }
- // float
- else if (srcType == VALUE_TYPE::Type_Float)
- {
- float fValue = GetDllInfValue<float>(pSrcInf);
- tValue = static_cast<double>(fValue);
- }
- // bool
- else if (srcType == VALUE_TYPE::Type_Bool)
- {
- bool bValue = GetDllInfValue<bool>(pSrcInf);
- tValue = static_cast<double>(bValue);
- }
- else
- {
- tValue = GetDllInfValue<double>(pSrcInf);
- }
- SetDllInfValue<double>(tValue, pDstInf);
- }
- /// <summary>
- /// 模板特例化 - 目标类型是bool时(为了实现自动接口数值类型转换)
- /// </summary>
- /// <param name="tValue"></param>
- /// <param name="pSrcInf"></param>
- /// <param name="pDstInf"></param>
- void POU::MoveValueByConverter(bool& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf)
- {
- VALUE_TYPE srcType = pSrcInf->value.type;
- // QString
- if (srcType == VALUE_TYPE::Type_String)
- {
- QString strValue = GetDllInfValue<QString>(pSrcInf);
- if (strValue == STRING_TRUE || strValue == "1")
- {
- tValue = true;
- }
- else
- {
- tValue = false;
- }
- }
- // int
- else if (srcType == VALUE_TYPE::Type_Int)
- {
- int nValue = GetDllInfValue<int>(pSrcInf);
- tValue = static_cast<bool>(nValue);
- }
- // float
- else if (srcType == VALUE_TYPE::Type_Double)
- {
- double dValue = GetDllInfValue<float>(pSrcInf);
- tValue = static_cast<bool>(dValue);
- }
- // double
- else if (srcType == VALUE_TYPE::Type_Double)
- {
- double dValue = GetDllInfValue<double>(pSrcInf);
- tValue = static_cast<bool>(dValue);
- }
- else
- {
- tValue = GetDllInfValue<bool>(pSrcInf);
- }
- SetDllInfValue<bool>(tValue, pDstInf);
- }
- /// <summary>
- /// 2021-11-9 向UI同步接口数值
- /// </summary>
- /// <param name="pInf"></param>
- void POU::syncValuesToUi(QList<_INTERFACE*> pInfs)
- {
- SyncValueEvent* valueEvent = new SyncValueEvent();
- // 携带需要同步的多个接口
- valueEvent->setSyncValues(pInfs);
- // post数值同步消息,post内部会自动释放event的指针,无需手工释放
- QCoreApplication::postEvent((QObject*)g_pUiManager, valueEvent);
- }
- /// <summary>
- /// 2021-11-14 向变量表界面同步数值
- /// </summary>
- /// <param name="pInfs"></param>
- void POU::syncValuesToTableUI(QList<_INTERFACE*> pInfs)
- {
- SyncValueEvent* valueEvent = new SyncValueEvent();
- // 携带需要同步的多个接口
- valueEvent->setSyncValues(pInfs);
- // post数值同步消息,post内部会自动释放event的指针,无需手工释放
- QCoreApplication::postEvent((QObject*)g_pGvlManager, valueEvent);
- }
- /// <summary>
- /// 2021-12-15 向Runtime推送索引数值的变动
- /// </summary>
- /// <param name="pInfs"></param>
- void POU::syncComplexIndexesToRuntime(QList<VARIABLE*> pIndexes)
- {
- SyncValueEvent* valueEvent = new SyncValueEvent();
- // 携带需要同步的多个接口
- valueEvent->setSyncValues(pIndexes);
- // post数值同步消息,post内部会自动释放event的指针,无需手工释放
- QCoreApplication::postEvent((QObject*)g_pRuntime, valueEvent);
- }
- /// <summary>
- /// 更新接口的值(根据不同的模式)
- /// </summary>
- /// <param name="pInf"></param>
- /// <param name="mode"></param>
- QString POU::updateInterfaceValue(_INTERFACE* pInf, UPDATE_VALUE_MODE mode)
- {
- // 2021-6-5 增加, 防止变量中的变量被删除的情况,首先检查值是否为空
- //if (mode == UPDATE_VALUE_MODE::MODE_FROM_VARIABLE)
- //{
- // if (pInf->pUpLinkInterface->value.Ptr == nullptr)
- // {
- // Utility::VPCriticalMessageBox("Can't update value from " + pInf->pUpLinkInterface->strFullName + ", Reason: value is invalid.");
- // return false;
- // }
- //}
- // 被标记为废弃的端口,不参与数据链接
- if (pInf == nullptr || pInf->Discard != INF_DISCARD::INF_DEFAULT)
- {
- return "Interface Error";
- }
- // 根据不同类型分别进行操作
- VALUE_TYPE type = pInf->value.type;
- switch (type)
- {
- case VALUE_TYPE::Type_Bool:
- {
- bool value = false;
- MoveValue<bool>(value, pInf, mode);
- pInf->valueString = QString(value);
- }
- break;
- case VALUE_TYPE::Type_Int:
- {
- int value = 0;
- MoveValue<int>(value, pInf, mode);
- // 2021-11-9,保存接口数值
- pInf->valueString = QString::number(value);
- }
- break;
- case VALUE_TYPE::Type_Float:
- {
- float value = 0;
- MoveValue<float>(value, pInf, mode);
- pInf->valueString = QString("%1").arg(value);
- }
- break;
- case VALUE_TYPE::Type_Double:
- {
- double value = 0.0;
- MoveValue<double>(value, pInf, mode);
- pInf->valueString = QString("%1").arg(value);
- }
- break;
- //case VALUE_TYPE::Type_CharP:
- //{
- // char* value = nullptr;
- // MoveValue<char*>(value, pInf, mode);
- // return QString("%1").arg(value);
- //}
- //break;
- case VALUE_TYPE::Type_StdString:
- {
- std::string value = "";
- MoveValue<std::string>(value, pInf, mode);
- pInf->valueString = QString("%1").arg(value.c_str());
- }
- break;
- case VALUE_TYPE::Type_String:
- {
- QString value = "";
- MoveValue<QString>(value, pInf, mode);
- pInf->valueString = value;
- }
- break;
- case VALUE_TYPE::Type_QImage:
- {
- QImage value;
- MoveValue<QImage>(value, pInf, mode);
- //pInf->valueString = QString("%1 - %1").arg(value.size().width()).arg(value.size().height());
- pInf->valueString = QString("QImage");
- }
- break;
- case VALUE_TYPE::Type_Mat:
- {
- Mat value;
- MoveValue<Mat>(value, pInf, mode);
- //pInf->valueString = QString("%1 - %1").arg(value.size().width()).arg(value.size().height());
- pInf->valueString = QString("Mat");
- }
- break;
- case VALUE_TYPE::Type_HTuple:
- {
- HTuple value;
- MoveValue<HTuple>(value, pInf, mode);
- pInf->valueString = QString("HTuple");
- }
- break;
- case VALUE_TYPE::Type_HObject:
- {
- HObject value;
- MoveValue<HObject>(value, pInf, mode);
- pInf->valueString = QString("HObject");
- }
- break;
- case VALUE_TYPE::Type_HImage:
- {
- HImage value;
- MoveValue<HImage>(value, pInf, mode);
- pInf->valueString = QString("HImage");
- }
- break;
- case VALUE_TYPE::Type_ST_Pos:
- {
- ST_POS value;
- MoveValue<ST_POS>(value, pInf, mode);
- pInf->valueString = QString("ST Pose");
- }
- break;
- case VALUE_TYPE::Type_ST_HomMat2D:
- {
- HHomMat2D value;
- MoveValue<HHomMat2D>(value, pInf, mode);
- pInf->valueString = QString("HHomMat2D");
- }
- break;
- case VALUE_TYPE::Type_ST_Point:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Line:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Circle:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Disp:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Window:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Ncc_Modle:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Shape_Modle:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_Calibration:
- {
- }
- break;
- case VALUE_TYPE::Type_ST_CamParam_PoseCalib:
- {
- }
- break;
- case VALUE_TYPE::Type_pIBaseCamera:
- {
- IBaseCamera* value= nullptr;
- MoveValue<IBaseCamera*>(value, pInf, mode);
- if (value != nullptr)
- {
- pInf->valueString = QString("%1").arg(value->serial());
- }
- else
- {
- pInf->valueString = "null";
- }
-
- }
- break;
- case VALUE_TYPE::Type_pIpImage:
- {
- }
- break;
- case VALUE_TYPE::Type_pISocket:
- {
- }
- break;
- case VALUE_TYPE::Type_pArrayIn:
- {
- }
- break;
- case VALUE_TYPE::Type_pArrayOut:
- {
- }
- break;
- case VALUE_TYPE::Type_pArrayRobotPos:
- {
- }
- break;
- default:
- qWarning() << "[POU][LINK][ERROR]: updateInterfaceValue - Unknown value type: " << (short)type;
- return "";
- pInf->valueString.clear();
- }
- return pInf->valueString;
- // return "";
- }
- /// <summary>
- /// 重置所有工具执行状态
- /// </summary>
- void POU::ResetToolExecCode()
- {
- QHash<WindowAppBlockBase*, TOOL*>::iterator iter = m_itemToTools.begin();
- while (iter != m_itemToTools.end())
- {
- // 返回值
- iter.value()->execParams.nRetValue = VPEnum::RETURN_VALUE::None;
- // 状态
- iter.value()->execParams.nStatus = VPEnum::EXEC_STATUS::StandBy;
- iter++;
- }
- }
- /// <summary>
- /// 从Dll获取接口的值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="pInf"></param>
- /// <returns></returns>
- template<typename T>
- T& POU::GetDllInfValue(_INTERFACE* pInf)
- {
- // DllTool* pDllTool = pInf->pParentTool->pDllPtr;
- // 2022-3-23 根据真实的Parent获取对应的Dll(处理Port绑定的情况)
- DllTool* pDllTool = pInf->realParent()->pDllPtr;
- return pDllTool->Value<T>(pInf->nIndex);
- }
- /// <summary>
- /// 设置Dll中接口的值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="tValue"></param>
- /// <param name="pInf"></param>
- template<typename T>
- void POU::SetDllInfValue(T& tValue, _INTERFACE* pInf)
- {
- DllTool* pDllTool = pInf->realParent()->pDllPtr;
- if (pDllTool != nullptr)
- {
- if (pInf->value.passMode == VALUE_PASS_MODE::PASS_BY_VALUE)
- {
- pDllTool->UpdateValue<T>(pInf->nIndex, tValue);
- }
- else
- {
- pDllTool->UpdateValue<T>(pInf->nIndex, tValue, VALUE_PASS_MODE::PASS_BY_ADDRESS);
- }
- }
- else
- {
- pInf->setValue(tValue, VALUE_PASS_MODE::PASS_BY_VALUE);
- }
- }
- /// <summary>
- /// 2022-9-25,查询WaitTool的等待Value(用于在TaskManager触发WaitTool执行的时候进行判断)
- /// </summary>
- /// <param name="pTool"></param>
- /// <returns></returns>
- VALUE* POU::getWaitToolValue(TOOL* pTool)
- {
- WindowAppBlockWait* pWaitBlock = qgraphicsitem_cast<WindowAppBlockWait*>(m_instNameToToolItems[pTool->strInstanceName]);
- return &pWaitBlock->m_WaitValue;
- }
- //============================================================
- //
- // Task 线程
- //
- //============================================================
- /// <summary>
- /// 线程函数
- /// </summary>
- void _ParallelThread::run()
- {
- // 调用函数执行任务
- this->m_pPou->ToolExecutionDispatcher(m_pParallelSubTool, TOOL_RUN_MODE::IN_PARALLEL);
- }
- ///// <summary>
- ///// 线程函数
- ///// </summary>
- //void _ParallelThread::run()
- //{
- // VPEnum::RETURN_VALUE ret = VPEnum::RETURN_VALUE::None;
- //
- // // 循环执行任务,直到工具退出为止
- // while (ret != VPEnum::RETURN_VALUE::Abort)
- // {
- // // 调用函数执行任务
- // this->m_pPou->ToolExecutionDispatcher(m_pParallelSubTool, TOOL_RUN_MODE::IN_PARALLEL);
- // }
- //
- // vDebug() << " _ParallelThread of SubTool[" << m_pParallelSubTool->strInstanceName << "] exit.";
- //}
- //
- //
- ///// <summary>
- ///// 将本工具加入到并行子工具的预启动中
- ///// </summary>
- ///// <param name="pTool"></param>
- //void POU::addParallelSubTool(TOOL* pTool)
- //{
- // // 并行子工具在刚链接的时候,就直接启动线程,但是处于等待状态不执行
- // m_ParallelThreadPool.start(new _ParallelThread(this, pTool));
- //
- // vDebug() << "ParallelSubTool[" << pTool->strInstanceName << "] thread start...";
- //}
- //
- //
- ///// <summary>
- ///// 移除一个并行子工具
- ///// </summary>
- ///// <param name="pTool"></param>
- //void POU::removeParallelSubTool(TOOL* pTool)
- //{
- // Q_UNUSED(pTool);
- //}
|