diff --git a/Inc/Workflow_Editor.hpp b/Inc/Workflow_Editor.hpp index 088fa38..332abe8 100644 --- a/Inc/Workflow_Editor.hpp +++ b/Inc/Workflow_Editor.hpp @@ -26,18 +26,14 @@ protected: } Edge; // 数据池 - std::vector> Connector_Pool; // 连接点池 - std::vector> Node_Pool; // 节点池 - std::vector Edge_Pool; // 边池 + std::vector> Node_Pool; // 节点池 + std::vector Edge_Pool; // 边池 /** - * 顶层索引为启示工作流节点(N个元素即N个处理流程) - * 次级索引为工作流分层 - * 三级索引为平级工作流节点 - * 不参与工作流节点仅存于散点列表 + * 顶层索引为起始工作流节点(N个元素即N个处理流程) + * 次级索引为工作序列,表示完成一个处理流程的非冲突序列 */ - std::vector>>> Process_Route; // 工作层级路由 - std::vector> Separate_Node_List; // 散点列表 + std::vector>> Process_Route; // 工作层级路由 // 删除节点 返回迭代器指定位置的下一个位置的迭代器,仅限内部使用 std::vector>::iterator Del_Node(std::vector>::iterator iterator); @@ -67,10 +63,10 @@ public: // 清除工作路由 true -> success / false -> failed bool Clear_Process_Route(void); - // 读取配置文件 - bool Read_Config(const char *file_path); + // 加载取配置文件 true -> success / false -> failed + bool Load_Config(const char *file_path); - // 存储配置文件 + // 存储配置文件 true -> success / false -> failed bool Store_Config(const char *file_path); }; diff --git a/Src/Workflow_Editor.cpp b/Src/Workflow_Editor.cpp index 364031c..9e1e796 100644 --- a/Src/Workflow_Editor.cpp +++ b/Src/Workflow_Editor.cpp @@ -65,6 +65,10 @@ void Workflow_Editor::Show(void) if (ImGui::MenuItem(u8"删除所选内容", nullptr, nullptr, (bounding_box_link_nums > 0) || (bounding_box_node_nums > 0))) bounding_box_delete_flag = true; + if (ImGui::MenuItem(u8"构建工作树(Debug)")) + if (this->Build_Process_Route() == false) + MessageBoxW(Main_Window_hWnd, L"构建工作树失败\n检查是否有合法的起始节点", L"", MB_OK | MB_ICONERROR); + ImGui::EndPopup(); } ImGui::PopStyleVar(); @@ -185,37 +189,15 @@ bool Workflow_Editor::Add_Node(Abs_Node::Node_Type_Enum type, ImVec2 initial_pos { // 将新增的节点记录到接口池及散点池 this->Node_Pool.push_back(p_New_Node); - this->Separate_Node_List.push_back(p_New_Node); - - /** - * @todo - * 考量接口列表是否有必要存在,遍历时可以通过遍历节点所含的接口列表来定位 - * 如果有节点需要动态扩充接口,此时接口列表遍历方式存在问题 - */ - - // 记录节点内含的接口列表 - for (auto p_Connector : p_New_Node->Get_Connector_List()) - this->Connector_Pool.push_back(p_Connector); - - // 记录到散点池 return true; } + return false; } // 删除节点 返回迭代器指定位置的下一个位置的迭代器,仅限内部使用 std::vector>::iterator Workflow_Editor::Del_Node(std::vector>::iterator iterator) { - - // 散点删除 - int node_id = (*iterator)->Get_ID(); - for (auto iterator = this->Separate_Node_List.begin(); iterator != this->Separate_Node_List.end(); iterator++) - if ((*iterator)->Get_ID() == node_id) - { - iterator = this->Separate_Node_List.erase(iterator); - break; - } - // 获取接口列表 auto Connector_List = (*iterator)->Get_Connector_List(); @@ -234,21 +216,8 @@ std::vector>::iterator Workflow_Editor::Del_Node(std:: iterator = this->Edge_Pool.erase(iterator) - 1; } } - - // 从接口池中移除 - for (auto iterator = this->Connector_Pool.begin(); iterator != this->Connector_Pool.end(); iterator++) - if (*iterator == pConnector) - { - iterator = this->Connector_Pool.erase(iterator); - break; - } } - /** - * @todo 从工作路由中删除该节点并调整工作路由层级顺序 - * @todo 可能不需要对外暴露接口池 - */ - iterator = this->Node_Pool.erase(iterator); return iterator; @@ -376,10 +345,6 @@ bool Workflow_Editor::Add_Link(int source_connector_id, int target_connector_id) { // 记录到边池 this->Edge_Pool.push_back({this->Edge_ID_Generator.Request_ID(), source_connector_id, target_connector_id}); - - /** - * @todo 调整工作路由层级 - */ } return true; @@ -420,10 +385,6 @@ std::vector::iterator Workflow_Editor::Del_Link(std::vect // 成功删除连接关系 if (p_source_connector->Disconnect_To(p_target_connector.get()) == true) { - /** - * @todo 调整工作路由层级 - */ - // 释放ID并销毁容器 this->Edge_ID_Generator.Release_ID(iterator->id); return this->Edge_Pool.erase(iterator); @@ -450,6 +411,8 @@ bool Workflow_Editor::Del_Link(int source_connector_id, int target_connector_id) // 创建工作路由 true -> success / false -> failed bool Workflow_Editor::Build_Process_Route(void) { + this->Clear_Process_Route(); + // 找出所有的头节点 std::vector> Head_List; for (auto pNode : this->Node_Pool) @@ -458,6 +421,158 @@ bool Workflow_Editor::Build_Process_Route(void) Head_List.push_back(pNode); } + // 没有可以构建的工作序列 + if (Head_List.size() == 0) + return false; + + // 工具Lambda表达式,查找接口id的所属节点 + auto Lambda_Find_Owner = [&](int connector_id) -> std::shared_ptr + { + for (auto pNode : this->Node_Pool) + { + for (auto pConnector : pNode->Get_Connector_List()) + { + if (pConnector->Get_ID() == connector_id) + return pNode; + } + } + + return nullptr; + }; + + // 处理所有头节点工作流程 + for (auto pNode : Head_List) + { + // 工作序列 + std::vector> Process_Sequence_List; // 处理序列 + std::vector> pRelated_List; // 关联节点列表 + + // 构建相关节点列表 + auto Lambda_Find_Related_List = [&](auto self, std::shared_ptr pTargetNode) -> void + { + // 记录自身到关联列表中 + pRelated_List.push_back(pTargetNode); + + // 查找当前节点的关联节点 + std::vector Target_Related_Node_List; + for (auto pConnector : pTargetNode->Get_Connector_List()) + { + for (auto pRelated_Connector : pConnector->Get_Related_List()) + { + auto pRelated_Node = Lambda_Find_Owner(pRelated_Connector->Get_ID()); + bool duplicated = false; + + // 查重并加入子节点列表 + for (auto pNode : Target_Related_Node_List) + { + if (pNode == pRelated_Node) + { + duplicated = true; + break; + } + } + + if (!duplicated) + Target_Related_Node_List.push_back(pRelated_Node); + } + } + + // 泛洪检查所有相邻的节点 + for (auto pNode : Target_Related_Node_List) + { + bool find = false; + for (auto pCheckedNode : pRelated_List) + if (pCheckedNode == pNode) + { + find = true; + break; + } + + // 当前关联节点未被记录时,递归顺延泛洪 + if (!find) + self(self, pNode); + } + }; + + // 工具Lambda表达式,检查依赖节点 true -> ALL Dependency Find + auto Lambda_Check_Dependency = [&](Abs_Node *pTargetNode) -> bool + { + // 查找目标节点的依赖节点列表 + std::vector> Dependency_NodeList; + for (auto pConnector : pTargetNode->Get_Connector_List()) + { + if (pConnector->Get_Type() == Abs_Connector::CONNECTOR_TYPE_INPUT) + { + for (auto pPreConnector : pConnector->Get_Related_List()) + { + auto pPreNode = Lambda_Find_Owner(pPreConnector->Get_ID()); + bool duplicated = false; + + // 查重并加入依赖关系列表 + for (auto pNode : Dependency_NodeList) + { + if (pNode == pPreNode) + { + duplicated = true; + break; + } + } + + if (!duplicated) + Dependency_NodeList.push_back(pPreNode); + } + } + } + + // 比对依赖的节点和已处理的节点 + bool all_find_flag = true; + for (auto pDependencyNode : Dependency_NodeList) + { + bool find = false; + for (auto pProcessedNode : Process_Sequence_List) + { + if (pDependencyNode == pProcessedNode) + { + find = true; + break; + } + } + + if (!find) + { + all_find_flag = false; + break; + } + } + + return all_find_flag; + }; + + // 构建处理序列,遍历所有关联节点直到不存在散点,每次都加入已经满足依赖的所有节点 + Lambda_Find_Related_List(Lambda_Find_Related_List, pNode); + while (pRelated_List.size() > 0) + { + for (auto iterator = pRelated_List.begin(); iterator != pRelated_List.end(); iterator++) + { + if (Lambda_Check_Dependency(iterator->get()) == true) + { + Process_Sequence_List.push_back(*iterator); + iterator = pRelated_List.erase(iterator) - 1; + } + } + } + + // 工作序列中仅孤立节点时不加入工作路由表 + if (Process_Sequence_List.size() > 1) + this->Process_Route.push_back(Process_Sequence_List); + } + + /** + * @todo + * 工作路由序列合法性检查 + * 非法 -> return false + */ + return true; }