#pragma once #include "DataStructure.h" #include "DataStructureInner.h" #include "Utility.h" #include "DllToolCommon.h" #include "VPGlobal.h" #include "PouManager.h" #include "TaskManager.h" #include "GvlManager.h" ////======================================================== //// //// TASK //// ////======================================================== /// /// EXEC_PARAMS 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const _tagExecutionParameters& ep) { // out << ep.nExecTime; // out << ep.nExecCount; // out << ep.nErrorCount; // // out << ep.nPreDelay; // out << ep.nPostDelay; // // out << ep.nStatus; // out << ep.nRetValue; int nParanum = 7;//参数数量 out << nParanum;//先保存参数数量 out << (int)1 << ep.nExecTime; out << (int)2 << ep.nExecCount; out << (int)3 << ep.nErrorCount; out << (int)4 << ep.nPreDelay; out << (int)5 << ep.nPostDelay; out << (int)6 << ep.nStatus; out << (int)7 << ep.nRetValue; return out; } /// /// EXEC_PARAMS 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, _tagExecutionParameters& ep) { // in >> ep.nExecTime; // in >> ep.nExecCount; // in >> ep.nErrorCount; // // in >> ep.nPreDelay; // in >> ep.nPostDelay; // // in >> ep.nStatus; // in >> ep.nRetValue; int nPara; int nParanum; in >> nParanum;//读取参数数量 // 校验 int nMaxParanum = 7;// 该参数的最大数量(需要根据参数的数量来调整,用来校验) if (nParanum < 0 || nParanum > nMaxParanum) { return in; } for (int i = 0; i < nParanum; i++) { in >> nPara; switch (nPara) { case 1: in >> ep.nExecTime; break; case 2: in >> ep.nExecCount; break; case 3: in >> ep.nErrorCount; break; case 4: in >> ep.nPreDelay; break; case 5: in >> ep.nPostDelay; break; case 6: in >> ep.nStatus; break; case 7: in >> ep.nRetValue; break; default: { qWarning() << "_tagExecutionParameters Serialized(In) Error"; } break; } } return in; } /// /// TASK_PARAMS 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const _tagTaskParameters& tp) { // out << tp.nExecTime; // out << tp.nExecCount; // out << tp.nErrorCount; // // out << tp.nPreDelay; // out << tp.nPostDelay; // // out << tp.nStatus; // out << tp.nRetValue; // // out << tp.bWatchDog; // out << tp.nWatchDog; // out << tp.nPriority; // out << tp.nTriggerFailedCount; // // out << tp.runMode; int nParanum = 12;//参数数量 out << nParanum;//先保存参数数量 out << (int)1 << tp.nExecTime; out << (int)2 << tp.nExecCount; out << (int)3 << tp.nErrorCount; out << (int)4 << tp.nPreDelay; out << (int)5 << tp.nPostDelay; out << (int)6 << tp.nStatus; out << (int)7 << tp.nRetValue; out << (int)8 << tp.bWatchDog; out << (int)9 << tp.nWatchDog; out << (int)10 << tp.nPriority; out << (int)11 << tp.nTriggerFailedCount; out << (int)12 << tp.runMode; return out; } /// /// TASK_PARAMS 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, _tagTaskParameters& tp) { // in >> tp.nExecTime; // in >> tp.nExecCount; // in >> tp.nErrorCount; // // in >> tp.nPreDelay; // in >> tp.nPostDelay; // // in >> tp.nStatus; // in >> tp.nRetValue; // // in >> tp.bWatchDog; // in >> tp.nWatchDog; // in >> tp.nPriority; // in >> tp.nTriggerFailedCount; // // in >> tp.runMode; int nPara; int nParanum; in >> nParanum;//读取参数数量 // 校验 int nMaxParanum = 12;// 该参数的最大数量(需要根据参数的数量来调整,用来校验) if (nParanum < 0 || nParanum > nMaxParanum) { return in; } for (int i = 0; i < nParanum; i++) { in >> nPara; switch (nPara) { case 1: in >> tp.nExecTime; break; case 2: in >> tp.nExecCount; break; case 3: in >> tp.nErrorCount; break; case 4: in >> tp.nPreDelay; break; case 5: in >> tp.nPostDelay; break; case 6: in >> tp.nStatus; break; case 7: in >> tp.nRetValue; break; case 8: in >> tp.bWatchDog; break; case 9: in >> tp.nWatchDog; break; case 10: in >> tp.nPriority; break; case 11: in >> tp.nTriggerFailedCount; break; case 12: in >> tp.runMode; break; default: { qWarning() << "_tagTaskParameters Serialized(In) Error"; } break; } } tp.nStatus = VPEnum::EXEC_STATUS::StandBy; tp.nExecTime = 0; tp.nExecCount = 0; tp.nTriggerFailedCount = 0; return in; } /// /// TASK序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const TASK& task) { out << task.strName; // out << task.nIndex; // out << task.strMode; // // unsigned long需要转换一下 // out << task.timeOut; // // // 由于eventID每次启动时是系统随机为event设置的ID // // 所以序列化时此处不能直接保存eventID,需要保存对应的Event名字信息 // // 下次Load时根据Event名字信息实时获取新的eventID // // out << task.eventID; // // // execParams // out << task.execParams; int nParanum = 5;//参数数量 out << nParanum;//先保存参数数量 out << (int)1 << task.nIndex; // 2022-9-2 加入了modeType out << (int)2 << task.modeType; out << (int)3 << task.strModeName; out << (int)4 << task.timeOut; out << (int)5 << task.execParams; return out; } /// /// TASK反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, TASK& task) { int nPara; int nParanum; in >> nParanum;//读取参数数量 // 校验 int nMaxParanum = 5;// 该参数的最大数量(需要根据参数的数量来调整,用来校验) if (nParanum < 0 || nParanum > nMaxParanum) { return in; } for (int i = 0; i < nParanum; i++) { in >> nPara; switch (nPara) { case 1: in >> task.nIndex; break; case 2: in >> task.modeType; break; case 3: in >> task.strModeName; break; case 4: in >> task.timeOut; task.bindEventByMode(); break; // 此处需要根据Event的信息重新到dll中绑定event case 5: in >> task.execParams; break; default: { qWarning() << "TASK Serialized(In) Error"; } break; } } return in; } /// /// 根据Mode类型绑定对应的Event /// QEvent::Type TASK::bindEventByMode() { // 2021-8-21 增加,保存上次的Event用于更新TaskManager QEvent::Type oldType = QEvent::None; if (this->pEvent != nullptr) { oldType = this->pEvent->type(); } #ifndef CST_VISIONPLUS_TOOL_LIB // 不属于Loop模式的话就保存一下触发的事件 if (this->strModeName != TASK_MODE_LOOP) { // 2022-9-1 重写了任务Event的绑定逻辑,任务模式分成了三类 // 0. 系统内置 if (this->modeType == TASK_MODE_TYPE::MODE_SYS) { // 内置的触发事件保存在eventTrigger里 this->pEvent = g_pTaskManager->m_sysEvents.value(this->strModeName)->eventTrigger; } // 1. 硬件组态 else if (this->modeType == TASK_MODE_TYPE::MODE_HDW) { QMap pHdwEvents = g_pPouManager->getPouByName(GROUP_NAME_HARDWARE)->getAllEvents(); if (pHdwEvents.contains(this->strModeName)) { // this->pEvent = pHdwEvents[this->strModeName]->eventTrigger; // 2022-9-19 由于exe中并不保存dll接口额值,所以每次此处需要从Dll中重新获取 // 硬件组态的Event要注意这里是有区别的,事件并不在 eventTrigger 里 this->pEvent = ((ToolEvent*)pHdwEvents[this->strModeName]->getValuePtr()); // 增加接口的引用计数(被Task选用了之后就不允许删除) // TODO: 此处检查一下后续是否删除了这个引用 pHdwEvents[this->strModeName]->nRefCount++; } } // 2. 变量触发 else if (this->modeType == TASK_MODE_TYPE::MODE_VAL) { QHash eventVars = g_pGvlManager->getAllEventVariables(); if (eventVars.contains(this->strModeName)) { // 变量的触发事件保存在eventTrigger里 this->pEvent = eventVars[this->strModeName]->eventTrigger; } } // Error,不应该执行到这里 else { qWarning() << "Error: can't not find event[" << this->strModeName << "] in tools."; } //// 系统内置事件 //if (g_pTaskManager->m_sysModes.contains(this->strModeName)) //{ // this->pEvent = ((ToolEvent*)g_pTaskManager->m_sysModes.value(this->strModeName)->value.Ptr); //} //// 硬件组态事件 //else //{ // QMap pHdwEvents = g_pPouManager->getPouByName(GROUP_NAME_HARDWARE)->getAllEvents(); // if (pHdwEvents.contains(this->strModeName)) // { // // 2021-8-3修改,由于exe中并不保存dll接口额值,所以每次此处获取的都是空的 // // m_TaskOption.pEvent = (ToolEvent*)pHdwEvents[m_TaskOption.mode]->value.Ptr; // // 所以需要每次都从dll中对应的位置获取 // //int nEventIndex = pHdwEvents[m_TaskOption.mode]->nIndex; // //DllTool* pDll = pHdwEvents[m_TaskOption.mode]->pOriginalTool->pDllPtr; // // m_TaskOption.pEvent = (ToolEvent*)pDll->Interface(nEventIndex).value.Ptr; // this->pEvent = ((ToolEvent*)pHdwEvents[this->strModeName]->getValuePtr()); // // 增加接口的引用计数(被Task选用了之后就不允许删除) // pHdwEvents[this->strModeName]->nRefCount++; // } // // 否则出现了异常,需要报错 // else // { // qWarning() << "Error: can't not find event[" << this->strModeName << "] in tools."; // } //} } else { this->pEvent = nullptr; } #endif return oldType; } /// /// 任务是否执行中(处于Busy和Wait状态) /// /// bool TASK::isRunning() const { return ( this->execParams.nStatus == VPEnum::EXEC_STATUS::Busy || this->execParams.nStatus == VPEnum::EXEC_STATUS::Wait ); } //QEvent::Type ToolEvent::m_eventID = QEvent::None; // //ToolEvent::ToolEvent() : QEvent(eventID()) //{ // //} // // //QEvent::Type ToolEvent::eventID() //{ // // 创建事件Type // if (m_eventID == QEvent::None) // { // // 注册自定义事件,ID范围在(1000 - 65535之间) // m_eventID = (QEvent::Type)QEvent::registerEventType(QEvent::User + 64); // } // // // return m_eventID; //} //============================================================ // // Designer、DataLink // //============================================================ // QStringList SystemCommand::m_Cmds; /// /// 重载!= /// /// /// bool DataLink::operator!= (const DataLink& dl) const { // Q_UNUSED(dl); //if (this->m_bindControlType != dl.m_bindControlType // || this->m_ValueList != dl.m_ValueList // ) //{ // return true; //} //return false; return this->value != dl.value; } /// /// 重载= /// /// /// DataLink& DataLink::operator = (const DataLink& dl) { if (*this != dl) { this->value = dl.value; if (!dl.title.isEmpty() ) { this->title = dl.title; } this->bForce = dl.bForce; // TODO:此处不知道是否存在隐患,正常应该不会 this->defaultValue = dl.defaultValue; } return *this; } /// /// 转换成字符串类型 /// /// QString DataLink::toString() const { QString strRet = value.join("|"); return strRet; } /// /// 从字符串解析 /// /// void DataLink::fromString(const QString& linkString) { value = linkString.split("|"); } /// /// 是否有效 /// /// bool DataLink::isValid() const { return this->value.size() == 3; } //============================================================ // // SystemCommand // //============================================================ /// /// 获取所有的可用指令 /// /// QStringList SystemCommand::getAllCmd() { QStringList listCmd; listCmd << SYS_CMD_TASK_RUN << SYS_CMD_TASK_RUNONCE << SYS_CMD_TASK_STOP << SYS_CMD_UI_SWITCH; return listCmd; } //============================================================ // // CONTROL_PROPERTY // //============================================================ /// /// DataLink 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const DataLink& datalink) { // out << datalink.title; // out << datalink.bForce; // // //out << *proplink.defaultValue; // //out << *proplink.linkValue; // // // 先写入总数量 // out << datalink.value.size(); int nParanum = 3;//参数数量 out << nParanum;//先保存参数数量 out << (int)1 << datalink.title; out << (int)2 << datalink.bForce; out << (int)3 << datalink.value.size(); // 如果数据有效,则逐个写入数据 for (const auto& i : datalink.value) { out << i; } return out; } /// /// DataLink 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, DataLink& datalink) { // 先读入总数量 int nCount = 0; // in >> datalink.title; // in >> datalink.bForce; // in >> nCount; int nPara; int nParanum; in >> nParanum;//读取参数数量 // 校验 int nMaxParanum = 3;// 该参数的最大数量(需要根据参数的数量来调整,用来校验) if (nParanum < 0 || nParanum > nMaxParanum) { return in; } for (int i = 0; i < nParanum; i++) { in >> nPara; switch (nPara) { case 1: in >> datalink.title; break; case 2: in >> datalink.bForce; break; case 3: in >> nCount; break; default: { qWarning() << "DataLink Serialized(In) Error"; } break; } } // 根据数量读取具体的内容 for (int i = 0; i < nCount; i++) { QString str; in >> str; datalink.value << str; } return in; } /// /// CONTROL_PROPERTY 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const CONTROL_PROPERTY& prop) { int nParanum = 21;//参数数量 out << nParanum;//先保存参数数量 out << (int)1 << prop.m_strText; // 控件文字 out << (int)2 << prop.m_strTip; // 控件提示信息 out << (int)3 << prop.m_clrText; // 文字颜色 out << (int)4 << prop.m_clrBg; // 背景色 out << (int)5 << prop.m_Font; // 控件字体 out << (int)6 << prop.m_bEnable; // 是否启用控件 out << (int)7 << prop.m_DataLink; // DataLink(复杂类型) out << (int)8 << prop.m_nRowCount; out << (int)9 << prop.m_nColCount; out << (int)10 << prop.m_nSliceCount; // 分块的数量 out << (int)11 << prop.m_clrBorder; // 控件边框颜色 out << (int)12 << prop.m_nHObjectCount; out << (int)13 << prop.m_nHTupleCount; out << (int)14 << prop.m_nDisplayCount; out << (int)15 << prop.m_nInteractions; out << (int)16 << prop.m_nDrawingMode; out << (int)17 << prop.m_nTickCountX; out << (int)18 << prop.m_nTickCountY; out << (int)19 << prop.m_RangeX; out << (int)20 << prop.m_RangeY; out << (int)21 << prop.m_nStringCount; return out; } /// /// CONTROL_PROPERTY 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, CONTROL_PROPERTY& prop) { int nPara; int nParanum; in >> nParanum;//读取参数数量 // 校验 int nMaxParanum = 21;// 该参数的最大数量(需要根据参数的数量来调整,用来校验) if (nParanum < 0 || nParanum > nMaxParanum) { return in; } for (int i = 0; i < nParanum; i++) { in >> nPara; switch (nPara) { case 1: in >> prop.m_strText; break;// 控件文字 case 2: in >> prop.m_strTip; break;// 控件提示信息 case 3: in >> prop.m_clrText; break;// 文字颜色 case 4: in >> prop.m_clrBg; break;// 背景色 case 5: in >> prop.m_Font; break;// 控件字体 case 6: in >> prop.m_bEnable; break;// 是否启用控件 case 7: in >> prop.m_DataLink; break;// DataLink(复杂类型) case 8: in >> prop.m_nRowCount; break; case 9: in >> prop.m_nColCount; break; case 10: in >> prop.m_nSliceCount; break;// 分块的数量 case 11: in >> prop.m_clrBorder; break;// 控件边框颜色 case 12: in >> prop.m_nHObjectCount; break; case 13: in >> prop.m_nHTupleCount; break; case 14: in >> prop.m_nDisplayCount; break; case 15: in >> prop.m_nInteractions; break; case 16: in >> prop.m_nDrawingMode; break; case 17: in >> prop.m_nTickCountX; break; case 18: in >> prop.m_nTickCountY; break; case 19: in >> prop.m_RangeX; break; case 20: in >> prop.m_RangeY; break; case 21: in >> prop.m_nStringCount; break; default: { qWarning() << "DataLink Serialized(In) Error"; } break; } } return in; } ///// ///// DataLink 序列化 ///// ///// ///// ///// //QDataStream& operator<<(QDataStream& out, const DataLink& proplink) //{ // out << proplink.title; // out << proplink.value; // // //out << *proplink.defaultValue; // //out << *proplink.linkValue; // // out << proplink.bForce; // // return out; //} // // ///// ///// DataLink 反序列化 ///// ///// ///// ///// //QDataStream& operator>>(QDataStream& in, DataLink& proplink) //{ // in >> proplink.title; // in >> proplink.value; // // //in >> *proplink.defaultValue; // //in >> *proplink.linkValue; // // in >> proplink.bForce; // // return in; //} /// /// PROPERTY_EX_SUBGROUP 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const PROPERTY_EX_SUBGROUP& subgroup) { out < /// PROPERTY_EX_SUBGROUP 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, PROPERTY_EX_SUBGROUP& subgroup) { in >> subgroup.strTitle; // 先写入数量 int count = 0; in >> count; for (int i = 0; i < count; i++) { DataLink datalink; in >> datalink; subgroup.dataLinks.push_back(datalink); } int nPara; int nParanum; in >> nParanum;//读取参数数量 // 校验 int nMaxParanum = 22;// 该参数的最大数量(需要根据参数的数量来调整,用来校验) if (nParanum < 0 || nParanum > nMaxParanum) { return in; } for (int i = 0; i < nParanum; i++) { in >> nPara; switch (nPara) { case 1: in >> subgroup.strValueName; break; case 2: in >> subgroup.strValue; break; case 3: in >> subgroup.strColorName; break; case 4: in >> subgroup.color; break; case 5: in >> subgroup.strLineWidthName; break; case 6: in >> subgroup.nLineWidth; break; case 7: in >> subgroup.strPtName; break; case 8: in >> subgroup.pt; break; case 9: in >> subgroup.strSize; break; case 10: in >> subgroup.nSize; break; case 11: in >> subgroup.strSaveImage; break; case 12: in >> subgroup.bEnSaveImage; break; case 13: in >> subgroup.strDumpWindow; break; case 14: in >> subgroup.bEnDumpWindow; break; case 15: in >> subgroup.strExecuteState; break; case 16: in >> subgroup.bEnExecuteState; break; case 17: in >> subgroup.strSaveMode; break; case 18: in >> subgroup.nSaveMode; break; case 19: in >> subgroup.strBufferSize; break; case 20: in >> subgroup.nBufferSize; break; case 21: in >> subgroup.strFreeTime; break; case 22: in >> subgroup.nFreeTime; break; default: { qWarning() << "PROPERTY_EX_SUBGROUP Serialized(In) Error"; } break; } } return in; } /// /// CONTROL_PROPERTY_EX 序列化 /// /// /// /// QDataStream& operator<<(QDataStream& out, const CONTROL_PROPERTY_EX& propEx) { // 扩展属性的总名称 out << propEx.m_strTitle; // 刷新链接 out << propEx.m_refreshLink; // 主数据链接(可能有多个) out << propEx.m_mainDataLinks.size(); for (const auto& datalink : propEx.m_mainDataLinks) { out << datalink; } // 所有扩展属性组 out << propEx.m_groups.size(); for (const auto& group : propEx.m_groups) { out << group.strRelationKey; out << group.strTitle; out << group.subGroups.size(); for (const auto& subgroup : group.subGroups) { out << subgroup; } } return out; } /// /// CONTROL_PROPERTY_EX 反序列化 /// /// /// /// QDataStream& operator>>(QDataStream& in, CONTROL_PROPERTY_EX& propEx) { // 扩展属性的总名称 in >> propEx.m_strTitle; // 刷新链接 in >> propEx.m_refreshLink; // 主数据链接 int count = 0; in >> count; for (int i = 0; i < count; i++) { DataLink newMainLink; in >> newMainLink; propEx.m_mainDataLinks.push_back(newMainLink); } // 扩展属性 in >> count; for (int i = 0; i < count; i++) { PROPERTY_EX_GROUP newGroup; in >> newGroup.strRelationKey; in >> newGroup.strTitle; int subCount = 0; in >> subCount; for (int j = 0; j < subCount; j++) { PROPERTY_EX_SUBGROUP subGroup; in >> subGroup; newGroup.subGroups.push_back(subGroup); } propEx.m_groups.push_back(newGroup); } return in; }