#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;
}