#pragma once
#include "Common.h"
#include "CommonDraw.h"
class WindowAppItemLink;
class WindowAppPouScene;
class WindowAppItemInterface;
class WindowAppBlockPort;
class WindowAppBlockStandard;
class WindowAppBlockStandardBase;
class WindowAppBlockComment;
class WindowAppBlockBase;
class Document;
class TASK;
///
/// Parallel Tool 的执行线程体
///
class _ParallelThread : public QRunnable
{
public:
_ParallelThread(POU* pPou, TOOL* pRunningTool)
{
this->m_pPou = pPou;
this->m_pParallelSubTool = pRunningTool;
};
~_ParallelThread() {};
protected:
// 线程函数
virtual void run();
//signals:
//
// // 传递线程参数(暂未使用)
// void sigThreadParams();
private:
// 所在的Pou指针
POU* m_pPou;
// 并行子工具的指针
TOOL* m_pParallelSubTool;
// 互斥量,用于模拟线程的休眠
QMutex m_mutex;
};
///
/// 用于存储Link信息的类
///
typedef struct _tagLink
{
// 运行使用
WindowAppItemInterface* pSrcItem; // Link中起始接口的Item
WindowAppItemInterface* pDstItem; // Link中目的接口的Item
WindowAppItemLink* pLinkItem; // 本Link对应的LinkItem
LINK_MODE linkMode; // 连接模式
_tagLink()
{
linkMode = LINK_MODE::LINK_NORMAL;
pLinkItem = nullptr;
pSrcItem = nullptr;
pDstItem = nullptr;
}
} LINK;
///
/// 核心类,管理Pou界面中的Tool数据结构
///
class POU
{
public:
POU();
~POU();
// 完成Pou的初始化动作
void init(const QString& strName, WindowAppPouScene* pScene);
// 重置本Pou中所有的数据结构
void reset();
// 注册一个运行的功能块信息到当前Pou中
void registerTool(WindowAppBlockBase* pBlockItem, TOOL* pSelTool);
// 注册一个运行的接口信息到当前Pou中
void registerInterface(WindowAppItemInterface* pInfItem, _INTERFACE* pSelInf);
// 移除一个运行的Tool功能块
void removeTool(QGraphicsItem* pBlockItem);
// 显示当前工具对话框
void ShowToolDialog(WindowAppBlockStandardBase* pBlockItem);
// 获取当前DebugData
DebugData GetToolDebugData(WindowAppBlockStandardBase* pBlockItem);
// 执行当前工具
VPEnum::RETURN_VALUE ToolExecuteStandard(TOOL* pActiveTool);
//// 执行当前工具
//VPEnum::RETURN_VALUE ToolExecuteStandard(WindowAppBlockStandardBase* pBlockItem);
// 从当前位置执行
void ToolExecuteSub(WindowAppBlockStandardBase* pBlockItem);
// 全部按顺序执行
void ToolExecuteAll(const int startIndex = 0);
// 单步执行
void ToolExecuteSingleStep();
// Execute前更新上连接口
VPEnum::RETURN_VALUE ToolPreExecute(TOOL* pActiveTool);
// Execute后更新下连接口
VPEnum::RETURN_VALUE ToolPostExecute(TOOL* pActiveTool);
void ToolBreakPoint(WindowAppBlockStandardBase* pBlockItem);
// 调整工具的序号
void ToolMoveDown(WindowAppBlockStandardBase* pBlockItem);
void ToolMoveUp(WindowAppBlockStandardBase* pBlockItem);
void ToolMoveFirst(WindowAppBlockStandardBase* pBlockItem);
void ToolMoveLast(WindowAppBlockStandardBase* pBlockItem);
// 功能块复制粘贴
void ToolCopyBlock(WindowAppBlockStandardBase* pBlockItem);
void ToolCopyData(WindowAppBlockStandardBase* pBlockItem);
void ToolPaste(WindowAppBlockStandardBase* pBlockItem);
// 删除工具
void ToolDelete(WindowAppBlockBase* pBlockItem);
// 建立Link
void makeLink(
WindowAppItemInterface* srcInfItem,
WindowAppItemInterface* dstInfItem,
WindowAppItemLink* linkItem,
LINK_MODE linkMode = LINK_MODE::LINK_NORMAL
);
// 清除Link信息
void removeLink(WindowAppItemInterface* endInfItem);
// 获取全部的Link信息
const QVector& getAllLinks()
{
return m_Links;
}
// 注册新的Link信息
void registerLink(
WindowAppItemInterface* startInfItem,
WindowAppItemInterface* endInfItem,
WindowAppItemLink* linkItem,
LINK_MODE linkMode);
// 反注册Link信息
void unregisterLink(WindowAppItemInterface* endInfItem);
// 重置所有工具执行状态
void ResetToolExecCode();
// 将指定接口绑定到指定Port中
void bindPortAndInterface(WindowAppBlockBase* pPortItem, _INTERFACE* pBindInf, const QString& strInfName);
// 根据对应的Item指针获取对应的Tool
TOOL* GetToolByName(WindowAppBlockBase* pItem)
{
return m_itemToTools.value(pItem);
}
// 根据对应的InstanceName获取对应的Tool
TOOL* GetToolByName(QString strInstName)
{
return m_instNameToTools.value(strInstName);
}
// 根据对应的InstanceName获取对应的Tool Item
WindowAppBlockBase* GetToolItem(QString strInstName)
{
return m_instNameToToolItems.value(strInstName);
}
// 获取指定Item的绝对坐标
QPointF GetToolItemPos(QString strKey);
// 根据对应的Tool信息找到对应的Tool Item
WindowAppBlockBase* GetToolItem(const TOOL* pTool)
{
return m_instNameToToolItems.value(pTool->strInstanceName);
}
// 根据对应的Item指针获取对应的Interface
_INTERFACE* GetInterface(WindowAppItemInterface* pItem)
{
return m_itemToInterfaces.value(pItem);
}
// 根据对应的名字获取对应的Interface(toolinstancename.infname的形式)
_INTERFACE* GetInterface(const QString& strFullName)
{
return m_fullNameToInterfaces.value(strFullName);
}
// 2022-3-12,删除指定的接口相关数据结构
void DelInterface(const QString& strFullName, WindowAppItemInterface* pItem, _INTERFACE* pInf);
// 根据接口中对应的Dll数值获取接口指针(UIManager中使用)
_INTERFACE* GetInterfaceByValuePtr(void* pValue);
// 根据对应的名字获取对应的Interface Item(toolinstancename.infname的形式)
WindowAppItemInterface* GetInterfaceItemByName(QString strFullName) const
{
return m_fullNameToInterfaceItems.value(strFullName);
}
// 获取当前运行的所有工具数量
int GetAllToolsCount()
{
return m_itemToTools.size();
}
// 获取当前标准工具的数量(包括了Parallel、Goto、ForLoop以及StandardTools)
int GetStandardToolsCount()
{
return this->m_StandardTools.size();
}
// 获取当前索引序号的工具的数量(目前等同于GetStandardToolsCount(),但是后面会分开)
int GetIndexedToolsCount()
{
return this->m_StandardTools.size();
}
// 获取当前在运行的所有工具
const QMap GetAllTools() const
{
return m_instNameToTools;
}
// 获取当前运行的所有标准工具
const QVector& GetAllStandardTools() const
{
return m_StandardTools;
}
//// 2022-3-29,按执行顺序获取当前所有工具
//const QList GetOrderedStandardTools() const;
//// 2022-3-
// 获取当前在运行的所有接口
const QMap GetAllInterfaces() const
{
return m_fullNameToInterfaces;
}
// 获取所有的Event类型接口(如果有)
QMap getAllEvents();
// 生成工具新的实例名字
QString genToolInstanceName(const QString& strToolName);
// 更新工具的各个参数信息
// 设置工具的启用禁用
void setToolEnable(const TOOL* pToolInfo, bool bEnable);
// 设置接口的启用禁用
bool setInterfaceEnable(const _INTERFACE* pInfInfo, bool bEnable);
bool setInterfaceEnable(const TOOL* pToolInfo, int nInfIndex, bool bEnable);
// 更新工具的Info
void setToolInfo(const TOOL* pToolInfo, const QString& strInfo);
// 设置工具的延时参数
void setToolDelay(const TOOL* pToolInfo, const int inDelay, const int outDelay);
// 设置工具的实例名称
void setInstanceName(const TOOL* pToolInfo, const QString& strNewInsName, const QString& strOldInsName);
// 检查工具的实例名称是否重复(用于在Dialog对话框中判断用户是否可以重命名工具)
bool isInstanceNameDuplicated(const QString& strInsName);
// 查询可执行SmartLink的接口
WindowAppItemInterface* getSmartLinkInterface(const WindowAppItemInterface* pInf);
// 获取本Pou的名字
const QString pouName() const
{
return m_strPouName;
}
// 获取本Pou所在的Scene指针
WindowAppPouScene* parentScene()
{
return m_parentScene;
}
//// 是否处于执行状态(被Task选中,并加载执行)
//bool isRunning();
// 是否被Task选中
bool isSelByTask();
// 是否在Task中运行
bool isRunningInTask();
// 2021-9-15 增加,查找本Pou中指定类型的接口(用于设计界面中的数据链接用)
bool containInterface(VALUE_TYPE type, INF_DIRECTION dir = INF_DIRECTION::INF_DIR_OUT);
// 更新接口的值(根据不同的模式,返回更新值的字符串形式)
QString updateInterfaceValue(_INTERFACE* pInf, UPDATE_VALUE_MODE mode);
// 2022-6-21 增加,获取两个Block之间的所有LinkItem(用于进行批量移动)
QList getLinkItemsBetweenBlocks(WindowAppBlockBase* srcBlock, WindowAppBlockBase* dstBlock);
// 2022-6-21 获取指定接口Item的LinkItem序号
int getLinkIndexByDstInfItem(WindowAppItemInterface* dstItem);
//// 是否可以从Task列表中删除(Task尚未处于运行状态)
//bool couldBeDeletedFromTask();
//// 2022-3-29 执行内部工具
//VPEnum::RETURN_VALUE ExecuteInternal(TOOL* pActiveTool);
// 2022-3-29 执行Goto工具(TODO:应该为内部工具专门设计一套数据结构,暂时先放在这里)
VPEnum::RETURN_VALUE ToolExecuteGoto(TOOL* pTool, int& index);
// 2022-4-30 执行Parallel工具
VPEnum::RETURN_VALUE ToolExecuteParallel(TOOL* pTool);
// 2022-8-25 执行ForLoop工具
VPEnum::RETURN_VALUE ToolExecuteForloop(TOOL* pTool);
// 2022-9-3 执行Wait工具
VPEnum::RETURN_VALUE ToolExecuteWait(TOOL* pTool, TOOL_RUN_MODE runMode);
// 2022-5-1 工具的执行总调度
VPEnum::RETURN_VALUE ToolExecutionDispatcher(TOOL*& pTool, TOOL_RUN_MODE runMode);
// 2022-5-1 工具的执行总调度(Task中使用,关联执行序号)
VPEnum::RETURN_VALUE ToolExecutionDispatcher(TOOL*& pTool, int& index, TOOL_RUN_MODE runMode);
// 2022-9-6,执行前预检查
VPEnum::RETURN_VALUE ToolExecutionDispatcherPreCheck(TOOL*& pTool, TOOL_RUN_MODE runMode);
// 2022-9-25,查询WaitTool的等待Value(用于在TaskManager触发WaitTool执行的时候进行判断)
VALUE* getWaitToolValue(TOOL* pTool);
public:
friend Document;
// 本Pou运行时的参数和状态
EXEC_PARAMS execParams;
// 本Pou执行时所在的Task
const TASK* m_pParentTask = nullptr;
protected:
// 从Dll获取接口的值
template
T& GetDllInfValue(_INTERFACE* pInf);
// 设置Dll中接口的值
template
void SetDllInfValue(T& tValue, _INTERFACE* pInf);
// 重命名计数 + 1
void AddRenameRefCount(const QString& strName);
//// 刷新StandardTools列表
//void updateStandardToolsList(TOOL* pNewTool);
// MoveValue
template
void MoveValue(T& tValue, _INTERFACE* pInf, UPDATE_VALUE_MODE mode);
// 2021-8-24 将基础数据类型转换后,再执行操作
template
void MoveValueByConverter(T& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
// 根据其他需要特殊的类型做模板的特化(为了实现自动接口数值类型转换)
void MoveValueByConverter(QString& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
void MoveValueByConverter(int& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
void MoveValueByConverter(float& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
void MoveValueByConverter(double& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
void MoveValueByConverter(bool& tValue, _INTERFACE* pSrcInf, _INTERFACE* pDstInf);
// 2021-11-9 向UI同步接口数值
void syncValuesToUi(QList<_INTERFACE*> pInfs);
// 2021-11-14 向变量表界面同步数值
void syncValuesToTableUI(QList pInfs);
// 2021-12-15 向Runtime推送索引数值的变动
void syncComplexIndexesToRuntime(QList pIndexes);
// 用于调试的函数
// 输出所有工具相关的数据结构
void debugAllTools();
// 输出所有接口相关的数据结构
void debugAllInterface();
//// 输出所有引用计数的相关数据结构
//void debugAllRefCounter();
// 2022-2-15 增加Pou内部变量(仅用于统计,不显示、不序列化)
void initPouInternalVariables();
// 2022-2-16 绑定Pou内部变量和EXEC_PARAMS数据结构
void bindPouInternalVariables();
// 2022-3-6,检测功能块的变动是否需要向Task同步
void syncToolMoveToTaskView();
// 排序(用于在Pou中保持执行队列按index有序)
static bool sort_by_index(const TOOL* t1, const TOOL* t2)
{
return t1->nIndex < t2->nIndex;
}
private:
// 本Pou的名称
QString m_strPouName;
// 界面中正在运行的工具信息(Name Map对,自动排序)`
QMap m_instNameToTools;
// 界面中正在运行的所有接口信息(FullName Map对,自动排序)
QMap m_fullNameToInterfaces;
// 界面中正在运行的工具信息(QGraphicsItem Hash对)
QHash m_itemToTools;
// 界面中正在运行的所有接口信息(QGraphicsItem Hash对)
QHash m_itemToInterfaces;
// 界面中正在运行的工具信息(Name - Item Hash对)
QMap m_instNameToToolItems;
// 界面中正在运行的所有接口信息(FullName - Item Hash对)
QMap m_fullNameToInterfaceItems;
//// 每种运行工具的引用计数
//QHash m_ItemReferenceCounter;
// 每种工具的重命名Index
QMap m_AutoToolRenameIndex;
// 2021-8-14增加,为了提高TaskManager中的Tool执行效率,专门建立此数据结构
// 用于按执行顺序存储该Pou所有的标准工具
QVector m_StandardTools;
//用于临时数据的buffer
QBuffer m_BufferTemp;
// 单步执行的序号
int m_nExecuteIndex;
// 2022-4-30, 用于执行并行任务的线程池
QThreadPool m_ParallelThreadPool;
// 2022-6-12,用于存储本Pou中所有的Link信息,此后Link信息由Pou类统一管理(主要用于Link信息的序列化与反序列化)
QVector m_Links;
// 所属的Scene指针
WindowAppPouScene* m_parentScene;
};