Modified the way connectors associate with storage.Now both input and output interface types are allowed to have multiple connections. && Added some utility methods to the Workflow_Editor class. && Implemented key response, users can now select nodes and connections with a bounding box and delete them using the Delete key. && Added a new node type for connector testing.

This commit is contained in:
LuChiChick 2026-03-31 11:24:32 +08:00
parent f1e29aaba9
commit 975495b2b7
4 changed files with 507 additions and 206 deletions

View File

@ -26,9 +26,8 @@ protected:
Connector_Type_Enum type; // 类型标识 Connector_Type_Enum type; // 类型标识
const char *socket_str; // 套接字字符串 const char *socket_str; // 套接字字符串
Abs_Connector *provider; // 提供者 std::vector<Abs_Connector *> related_connector_list; // 关联列表
std::vector<Abs_Connector *> receiver_list; // 接收方 void *product; // 产物(仅输出类节点持有)
void *product; // 产物
public: public:
// 显式禁用默认构造 // 显式禁用默认构造
@ -43,14 +42,17 @@ public:
// 连接到目标连接点 // 连接到目标连接点
virtual bool Connect_To(Abs_Connector *target); virtual bool Connect_To(Abs_Connector *target);
// 断开连接 // 断开所有连接
virtual void Disconnect(void); virtual void Disconnect_All(void);
// 与指定的接口断开连接
virtual bool Disconnect_To(Abs_Connector *target);
// 注册产物 // 注册产物
virtual bool Register_Product(void *product, size_t size); virtual bool Register_Product(void *product, size_t size);
// 获取上级节点 // 获取关联接口列表
virtual Abs_Connector *Get_Provider(void); virtual std::vector<Abs_Connector *> Get_Related_List(void);
// 获取产物 // 获取产物
virtual void *Get_Product(void); virtual void *Get_Product(void);
@ -70,6 +72,7 @@ protected:
typedef enum typedef enum
{ {
NODE_TYPE_UNKNOWN, // 未知节点类型 NODE_TYPE_UNKNOWN, // 未知节点类型
NODE_TYPE_CONNECTOR_TEST, // 接口测试节点
NODE_TYPE_MSG_LINE_INPUT, // 消息输入节点 NODE_TYPE_MSG_LINE_INPUT, // 消息输入节点
NODE_TYPE_CSV_EXPORTER, // CSV输出节点 NODE_TYPE_CSV_EXPORTER, // CSV输出节点
} Node_Type_Enum; // 节点类型枚举 } Node_Type_Enum; // 节点类型枚举
@ -106,6 +109,9 @@ public:
// 执行处理流程 // 执行处理流程
virtual bool Execute_Process(void) = 0; virtual bool Execute_Process(void) = 0;
// 获取ID
virtual int Get_ID(void);
// 获取关闭信号 // 获取关闭信号
virtual bool Get_CloseFlag(void); virtual bool Get_CloseFlag(void);

View File

@ -15,6 +15,7 @@ protected:
typedef enum typedef enum
{ {
NODE_TYPE_UNKNOWN, // 未知节点类型 NODE_TYPE_UNKNOWN, // 未知节点类型
NODE_TYPE_CONNECTOR_TEST, // 接口测试节点
NODE_TYPE_MSG_LINE_INPUT, // 消息输入节点 NODE_TYPE_MSG_LINE_INPUT, // 消息输入节点
NODE_TYPE_CSV_EXPORTER, // CSV输出节点 NODE_TYPE_CSV_EXPORTER, // CSV输出节点
} Node_Type_Enum; // 节点类型枚举 } Node_Type_Enum; // 节点类型枚举
@ -46,13 +47,33 @@ protected:
std::vector<std::vector<std::vector<std::shared_ptr<Abs_Node>>>> Process_Route; // 工作层级路由 std::vector<std::vector<std::vector<std::shared_ptr<Abs_Node>>>> Process_Route; // 工作层级路由
std::vector<std::shared_ptr<Abs_Node>> Separate_Node_List; // 散点列表 std::vector<std::shared_ptr<Abs_Node>> Separate_Node_List; // 散点列表
// =====================================函数声明================================================= // 删除节点 返回迭代器指定位置的下一个位置的迭代器,仅限内部使用
// 新增节点 true -> success / false -> failed std::vector<std::shared_ptr<Abs_Node>>::iterator Del_Node(std::vector<std::shared_ptr<Abs_Node>>::iterator iterator);
bool Add_Node(Node_Type_Enum type, ImVec2 initial_position = ImVec2(0, 0));
// 删除边 返回迭代器指定位置的下一个位置的迭代器,仅限内部使用
std::vector<Edge>::iterator Del_Link(std::vector<Edge>::iterator iterator);
public: public:
// 绘制节点编辑器 // 绘制节点编辑器
void Show(void); void Show(void);
// 新增节点 true -> success / false -> failed
bool Add_Node(Node_Type_Enum type, ImVec2 initial_position = ImVec2(0, 0));
// 删除节点 true -> success / false -> failed
bool Del_Node(int target_node_id);
// 新增连接 true -> success / false -> failed
bool Add_Link(int source_connector_id, int target_connector_id);
// 删除连接 true -> success / false -> failed
bool Del_Link(int source_connector_id, int target_connector_id);
// 读取配置文件
bool Read_Config(const char *file_path);
// 存储配置文件
bool Store_Config(const char *file_path);
}; };
#endif #endif

View File

@ -77,7 +77,6 @@ Abs_Connector::Abs_Connector(Independent_ID_Generator *ID_Generator,
// 指针初始化 // 指针初始化
this->product = nullptr; this->product = nullptr;
this->provider = nullptr;
}; };
// 析构 // 析构
@ -86,8 +85,8 @@ Abs_Connector::~Abs_Connector()
// 释放产物 // 释放产物
if (this->product != nullptr) if (this->product != nullptr)
free(product); free(product);
// 断开连接 // 断开所有连接
this->Disconnect(); this->Disconnect_All();
// 释放ID // 释放ID
this->ID_Generator->Release_ID(this->id); this->ID_Generator->Release_ID(this->id);
} }
@ -98,53 +97,61 @@ bool Abs_Connector::Connect_To(Abs_Connector *target)
// 判定接口是否匹配 // 判定接口是否匹配
if (strcmp(target->socket_str, this->socket_str) == 0) if (strcmp(target->socket_str, this->socket_str) == 0)
{ {
// 写连接关系 // 写连接关系 必须是一收一发
if ((this->type == CONNECTOR_TYPE_OUTPUT) && (target->type == CONNECTOR_TYPE_INPUT)) if (((this->type == CONNECTOR_TYPE_OUTPUT) && (target->type == CONNECTOR_TYPE_INPUT)) || ((this->type == CONNECTOR_TYPE_INPUT) && (target->type == CONNECTOR_TYPE_OUTPUT)))
{ {
target->provider = this; // 向双方写入关联信息
this->receiver_list.push_back(target); target->related_connector_list.push_back(this);
return true; this->related_connector_list.push_back(target);
}
if ((this->type == CONNECTOR_TYPE_INPUT) && (target->type == CONNECTOR_TYPE_OUTPUT))
{
target->receiver_list.push_back(this);
this->provider = target;
return true; return true;
} }
} }
return false; return false;
} }
// 断开连接 // 断开所有连接
void Abs_Connector::Disconnect(void) void Abs_Connector::Disconnect_All(void)
{ {
// 受点断开供方连接 for (auto target : this->related_connector_list)
if (this->type == CONNECTOR_TYPE_INPUT)
{ {
// 断开供方对自身的记录 // 删除连接点对自己的记录
for (auto iterator = this->provider->receiver_list.begin(); iterator != this->provider->receiver_list.end(); iterator++) for (auto iterator = target->related_connector_list.begin(); iterator != target->related_connector_list.end(); iterator++)
{ if (*iterator == this)
// 供方断开自身列表记录
if ((*iterator) == this)
{ {
this->provider->receiver_list.erase(iterator); iterator = target->related_connector_list.erase(iterator);
break; break;
} }
}
// 断开自身对供方的记录
this->provider = nullptr;
} }
// 供方断开所有受点的供方记录
if (this->type == CONNECTOR_TYPE_OUTPUT)
{
// 断开受点的供方记录
for (auto receiver : this->receiver_list)
receiver->provider = nullptr;
// 清空受点列表 // 清空自身列表
decltype(this->receiver_list) empty_list; decltype(this->related_connector_list) empty_list;
this->receiver_list.swap(empty_list); this->related_connector_list.swap(empty_list);
}
// 与指定的接口断开连接
bool Abs_Connector::Disconnect_To(Abs_Connector *target)
{
// 查找目标接口
for (auto iterator = this->related_connector_list.begin(); iterator != this->related_connector_list.end(); iterator++)
{
if (*iterator == target)
{
// 删除目标连接点对自己的记录
for (auto iterator = target->related_connector_list.begin(); iterator != target->related_connector_list.end(); iterator++)
if (*iterator == this)
{
iterator = target->related_connector_list.erase(iterator);
break;
}
// 自身删除对目标点的记录
iterator = this->related_connector_list.erase(iterator);
return true;
}
} }
// 未成功查找
return false;
} }
// 注册产物 // 注册产物
@ -169,9 +176,9 @@ bool Abs_Connector::Register_Product(void *product, size_t size)
} }
// 获取上级节点 // 获取上级节点
Abs_Connector *Abs_Connector::Get_Provider(void) std::vector<Abs_Connector *> Abs_Connector::Get_Related_List(void)
{ {
return this->provider; return this->related_connector_list;
} }
// 获取产物 // 获取产物
@ -181,15 +188,7 @@ void *Abs_Connector::Get_Product(void)
if (this->type == CONNECTOR_TYPE_OUTPUT) if (this->type == CONNECTOR_TYPE_OUTPUT)
return this->product; return this->product;
// 输入节点返回间接产物(提供者方产物) // 其它情况返回空值
if (this->type == CONNECTOR_TYPE_INPUT)
{
if (this->provider == nullptr)
return nullptr;
return this->provider->product;
}
// 未知类型
return nullptr; return nullptr;
} }
@ -232,6 +231,12 @@ Abs_Node::~Abs_Node()
this->Node_ID_Generator->Release_ID(this->id); this->Node_ID_Generator->Release_ID(this->id);
} }
// 获取ID
int Abs_Node::Get_ID(void)
{
return this->id;
}
// 获取关闭信号 // 获取关闭信号
bool Abs_Node::Get_CloseFlag(void) bool Abs_Node::Get_CloseFlag(void)
{ {
@ -246,17 +251,6 @@ std::vector<std::shared_ptr<Abs_Connector>> &Abs_Node::Get_Connector_List(void)
// ================================================================================================= // =================================================================================================
// 必要构造
MSG_OutPut_Connector::MSG_OutPut_Connector(Independent_ID_Generator *ID_Generator) : Abs_Connector(ID_Generator, CONNECTOR_TYPE_OUTPUT, "DLT MSG") {}
// 绘制接口
void MSG_OutPut_Connector::Show(void)
{
// 输出接口点
ImNodes::BeginOutputAttribute(this->id, 1);
ImNodes::EndOutputAttribute();
}
// 必要构造 // 必要构造
MSG_InPut_Connector::MSG_InPut_Connector(Independent_ID_Generator *ID_Generator) : Abs_Connector(ID_Generator, CONNECTOR_TYPE_INPUT, "DLT MSG") {} MSG_InPut_Connector::MSG_InPut_Connector(Independent_ID_Generator *ID_Generator) : Abs_Connector(ID_Generator, CONNECTOR_TYPE_INPUT, "DLT MSG") {}
@ -264,12 +258,168 @@ MSG_InPut_Connector::MSG_InPut_Connector(Independent_ID_Generator *ID_Generator)
void MSG_InPut_Connector::Show(void) void MSG_InPut_Connector::Show(void)
{ {
// 输出接口点 // 输出接口点
ImNodes::BeginInputAttribute(this->id, 1); ImNodes::BeginInputAttribute(this->id, ImNodesPinShape_CircleFilled);
// 填充占位
ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight()));
ImNodes::EndInputAttribute(); ImNodes::EndInputAttribute();
} }
// 必要构造
MSG_OutPut_Connector::MSG_OutPut_Connector(Independent_ID_Generator *ID_Generator) : Abs_Connector(ID_Generator, CONNECTOR_TYPE_OUTPUT, "DLT MSG") {}
// 绘制接口
void MSG_OutPut_Connector::Show(void)
{
// 输出接口点
ImNodes::BeginOutputAttribute(this->id, ImNodesPinShape_CircleFilled);
// 填充占位
ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight()));
ImNodes::EndOutputAttribute();
}
// 必要构造
CSV_Column_Input_Connector::CSV_Column_Input_Connector(Independent_ID_Generator *ID_Generator) : Abs_Connector(ID_Generator, CONNECTOR_TYPE_INPUT, "CSV Column") {}
// 绘制接口
void CSV_Column_Input_Connector::Show()
{
// 输出接口点
ImNodes::BeginInputAttribute(this->id, ImNodesPinShape_TriangleFilled);
// 填充占位
ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight()));
ImNodes::EndInputAttribute();
}
// 必要构造
CSV_Column_Output_Connector::CSV_Column_Output_Connector(Independent_ID_Generator *ID_Generator) : Abs_Connector(ID_Generator, CONNECTOR_TYPE_OUTPUT, "CSV Column") {}
// 绘制接口
void CSV_Column_Output_Connector::Show()
{
// 输出接口点
ImNodes::BeginOutputAttribute(this->id, ImNodesPinShape_TriangleFilled);
// 填充占位
ImGui::Dummy(ImVec2(0.0f, ImGui::GetTextLineHeight()));
ImNodes::EndOutputAttribute();
}
// ================================================================================================= // =================================================================================================
// 必要构造
Connector_Test_Node::Connector_Test_Node(Independent_ID_Generator *Node_ID_Generator,
Independent_ID_Generator *Connector_ID_Generator,
ImVec2 initial_position)
: Abs_Node(Node_ID_Generator,
Connector_ID_Generator,
NODE_TYPE_CONNECTOR_TEST,
initial_position)
{
// 判定是否成功申请ID , 后加载测试用节点列表
if (this->id != -1)
{
// DLT MSG 相关接口
this->Connector_List.push_back(std::make_shared<MSG_InPut_Connector>(Connector_ID_Generator)); // [0] -> MSG
this->Connector_List.push_back(std::make_shared<MSG_OutPut_Connector>(Connector_ID_Generator)); // [1] MSG ->
// CSV 相关接口
this->Connector_List.push_back(std::make_shared<CSV_Column_Input_Connector>(Connector_ID_Generator)); // [2] -> Column
this->Connector_List.push_back(std::make_shared<CSV_Column_Output_Connector>(Connector_ID_Generator)); // [3] -> Column
}
}
// 绘制节点
void Connector_Test_Node::Show(void)
{
if (this->close_flag == true)
return;
// 初始化位置设定
if ((this->initial_position.x != 0) || (this->initial_position.y != 0))
{
ImNodes::SetNodeScreenSpacePos(this->id, this->initial_position);
this->initial_position = ImVec2(0, 0);
}
// 绘制节点
ImNodes::BeginNode(this->id);
{
// 标题部分
ImNodes::BeginNodeTitleBar();
{
ImGui::Text(u8"接口测试用节点");
ImGui::SameLine();
{
ImGui::TextDisabled(u8"(?)");
// 上下边距为调整
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
if (ImGui::BeginItemTooltip())
{
ImGui::Text("Node ID : %d\n", this->id);
ImGui::Separator();
ImGui::Text(u8"注意!仅供接口测试使用!\n该节点不会进行任何处理操作,且不会生成任何产物");
ImGui::EndTooltip();
}
ImGui::PopStyleVar();
}
ImGui::SameLine();
// 节点宽度调整
ImGui::Dummy(ImVec2(120.0f, 0.0f));
ImGui::SameLine();
// 绘制关闭按钮
if (CircleButtonWithX("#X", ImGui::GetTextLineHeight() / 2))
this->close_flag = true;
}
ImNodes::EndNodeTitleBar();
// 绘制DLT相关接口组
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y));
this->Connector_List[0]->Show();
ImGui::SameLine();
ImGui::Text("-> DLT-In");
ImGui::SameLine();
ImGui::Dummy(ImVec2(ImNodes::GetNodeDimensions(this->id).x - ImGui::CalcTextSize("-> DLT-In").x - ImGui::CalcTextSize("DLT-Out ->").x - (ImNodes::GetStyle().NodePadding.x + ImGui::GetStyle().ItemSpacing.x) * 2, 0.0f));
ImGui::SameLine();
ImGui::Text("DLT-Out ->");
ImGui::SameLine();
this->Connector_List[1]->Show();
ImGui::PopStyleVar();
}
// 绘制CSV列相关接口组
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y));
this->Connector_List[2]->Show();
ImGui::SameLine();
ImGui::Text("-> CSV-Column-In");
ImGui::SameLine();
ImGui::Dummy(ImVec2(ImNodes::GetNodeDimensions(this->id).x - ImGui::CalcTextSize("-> CSV-Column-In").x - ImGui::CalcTextSize("CSV-Column-Out ->").x - (ImNodes::GetStyle().NodePadding.x + ImGui::GetStyle().ItemSpacing.x) * 2, 0.0f));
ImGui::SameLine();
ImGui::Text("CSV-Column-Out ->");
ImGui::SameLine();
this->Connector_List[3]->Show();
ImGui::PopStyleVar();
}
}
ImNodes::EndNode();
}
// 执行处理流程
bool Connector_Test_Node::Execute_Process(void)
{
return true;
}
// 必要构造 // 必要构造
MSG_Input_Node::MSG_Input_Node(Independent_ID_Generator *Node_ID_Generator, MSG_Input_Node::MSG_Input_Node(Independent_ID_Generator *Node_ID_Generator,
Independent_ID_Generator *Connector_ID_Generator, Independent_ID_Generator *Connector_ID_Generator,

View File

@ -1,63 +1,6 @@
#include "Workflow_Editor.hpp" #include "Workflow_Editor.hpp"
#include "imgui_internal.h" #include "imgui_internal.h"
// 新增节点
bool Workflow_Editor::Add_Node(Node_Type_Enum type, ImVec2 initial_position)
{
// 新节点
std::shared_ptr<Abs_Node> p_New_Node;
// 记录节点
switch (type)
{
case NODE_TYPE_MSG_LINE_INPUT: // 消息行输入 (头节点)
// 创建节点
p_New_Node = std::make_shared<MSG_Input_Node>(&this->Node_ID_Generator,
&this->Connector_ID_Generator,
initial_position);
break;
// // 记录到节点池和接口池
// this->Node_Pool.push_back(p_New_Node);
// for (auto p_Connector : p_New_Node->Get_Connector_List())
// this->Connector_Pool.push_back(p_Connector);
// // 编辑工作路由
// {
// // 起始层级只有起始节点
// std::vector<std::shared_ptr<Abs_Node>> Begin_Layer;
// Begin_Layer.push_back(p_New_Node);
// // 层级列表仅有起始层级
// std::vector<std::vector<std::shared_ptr<Abs_Node>>> Layer_List;
// Layer_List.push_back(Begin_Layer);
// // 插入工作路由表
// this->Process_Route.push_back(Layer_List);
// }
// return true;
case NODE_TYPE_CSV_EXPORTER: // CSV输出器
break;
default:
return false;
}
if (p_New_Node.get() != nullptr)
{
// 将新增的节点及其接口记录到对应的池
this->Node_Pool.push_back(p_New_Node);
for (auto p_Connector : p_New_Node->Get_Connector_List())
this->Connector_Pool.push_back(p_Connector);
// 记录到散点池
this->Separate_Node_List.push_back(p_New_Node);
return true;
}
return false;
}
// 绘制节点编辑器 // 绘制节点编辑器
void Workflow_Editor::Show(void) void Workflow_Editor::Show(void)
{ {
@ -68,45 +11,10 @@ void Workflow_Editor::Show(void)
// 显示所有节点 // 显示所有节点
for (auto iterator = this->Node_Pool.begin(); iterator != this->Node_Pool.end(); iterator++) for (auto iterator = this->Node_Pool.begin(); iterator != this->Node_Pool.end(); iterator++)
{ {
auto Connector_List = (*iterator)->Get_Connector_List();
if ((*iterator)->Get_CloseFlag() == true) if ((*iterator)->Get_CloseFlag() == true)
{ {
// 删除列表中所有与该节点接口相关的边并从接口池中删除 // 处理节点删除
for (auto pConnector : Connector_List) iterator = this->Del_Node(iterator);
{
int connector_id = pConnector->Get_ID();
// 遍历边池
for (auto iterator = this->Edge_Pool.begin(); iterator != this->Edge_Pool.end(); iterator++)
{
if ((iterator->source_connector_id == connector_id) || (iterator->target_connector_id == connector_id))
{
// 注销边ID
this->Edge_ID_Generator.Release_ID(connector_id);
// 注销边记录,迭代器删除后会返回下一个位置的迭代器
iterator = this->Edge_Pool.erase(iterator);
iterator--;
}
}
// 从接口池中移除
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);
iterator--; iterator--;
} }
else else
@ -135,6 +43,8 @@ void Workflow_Editor::Show(void)
// 节点添加菜单 // 节点添加菜单
if (ImGui::BeginMenu(u8"创建节点")) if (ImGui::BeginMenu(u8"创建节点"))
{ {
if (ImGui::MenuItem(u8"接口测试节点"))
this->Add_Node(NODE_TYPE_CONNECTOR_TEST, click_pos);
if (ImGui::MenuItem(u8"DLT信息输入节点")) if (ImGui::MenuItem(u8"DLT信息输入节点"))
this->Add_Node(NODE_TYPE_MSG_LINE_INPUT, click_pos); this->Add_Node(NODE_TYPE_MSG_LINE_INPUT, click_pos);
ImGui::EndMenu(); ImGui::EndMenu();
@ -158,60 +68,274 @@ void Workflow_Editor::Show(void)
{ {
int source_id = -1, target_id = -1; int source_id = -1, target_id = -1;
if (ImNodes::IsLinkCreated(&source_id, &target_id)) if (ImNodes::IsLinkCreated(&source_id, &target_id))
{ this->Add_Link(source_id, target_id);
}
// 查找接口 // 处理键盘事件
bool find = false; {
std::shared_ptr<Abs_Connector> p_source_connector; // Delete 按键释放
std::shared_ptr<Abs_Connector> p_target_connector; if (ImGui::IsKeyReleased(ImGuiKey_Delete))
for (auto pNode : this->Node_Pool) {
// 释放所有选中的边
{ {
for (auto pConnector : pNode->Get_Connector_List()) std::vector<int> target_edge_id_list;
target_edge_id_list.resize(ImNodes::NumSelectedLinks());
if (target_edge_id_list.size() > 0)
{ {
if (pConnector->Get_ID() == source_id) ImNodes::GetSelectedLinks(&target_edge_id_list[0]);
p_source_connector = pConnector; for (auto edge_iterator = this->Edge_Pool.begin(); edge_iterator != this->Edge_Pool.end(); edge_iterator++)
if (pConnector->Get_ID() == target_id)
p_target_connector = pConnector;
if ((p_source_connector.get() != nullptr) && (p_target_connector.get() != nullptr))
{ {
find = true; if (target_edge_id_list.size() > 0)
break; for (auto target_id_iterator = target_edge_id_list.begin(); target_id_iterator != target_edge_id_list.end(); target_id_iterator++)
{
if (*target_id_iterator == edge_iterator->id)
{
target_edge_id_list.erase(target_id_iterator);
edge_iterator = this->Del_Link(edge_iterator) - 1;
break;
}
}
else
break;
} }
} }
if (find)
break;
} }
// 判定查找结果 // 释放所有选中的节点
if (find)
{ {
// 输入类型节点只允许一个父接口,输出类型节点可以有多个子接口 std::vector<int> target_id_list;
if (p_target_connector->Get_Provider() != nullptr) target_id_list.resize(ImNodes::NumSelectedNodes());
{ if (target_id_list.size() > 0)
int origin_source_id = p_target_connector->Get_Provider()->Get_ID(); ImNodes::GetSelectedNodes(&target_id_list[0]);
for (auto iterator = this->Edge_Pool.begin(); iterator != this->Edge_Pool.end(); iterator++) for (auto target_id : target_id_list)
{ this->Del_Node(target_id);
if (iterator->source_connector_id == origin_source_id && iterator->target_connector_id == target_id)
{
this->Edge_ID_Generator.Release_ID(iterator->id);
this->Edge_Pool.erase(iterator);
break;
}
}
}
// 尝试连接
if (p_source_connector->Connect_To(p_target_connector.get()) == true)
{
// 记录到边池
this->Edge_Pool.push_back({this->Edge_ID_Generator.Request_ID(), source_id, target_id});
/**
* @todo
*/
}
} }
} }
} }
} }
// 新增节点 true -> success / false -> failed
bool Workflow_Editor::Add_Node(Node_Type_Enum type, ImVec2 initial_position)
{
// 新节点
std::shared_ptr<Abs_Node> p_New_Node;
// 记录节点
switch (type)
{
case NODE_TYPE_CONNECTOR_TEST: // 接口测试节点
p_New_Node = std::make_shared<Connector_Test_Node>(&this->Node_ID_Generator,
&this->Connector_ID_Generator,
initial_position);
break;
case NODE_TYPE_MSG_LINE_INPUT: // 消息行输入 (头节点)
// 创建节点
p_New_Node = std::make_shared<MSG_Input_Node>(&this->Node_ID_Generator,
&this->Connector_ID_Generator,
initial_position);
break;
case NODE_TYPE_CSV_EXPORTER: // CSV输出器
break;
default:
return false;
}
// 成功分配时
if (p_New_Node.get() != nullptr)
{
// 将新增的节点记录到接口池及散点池
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<std::shared_ptr<Abs_Node>>::iterator Workflow_Editor::Del_Node(std::vector<std::shared_ptr<Abs_Node>>::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();
// 删除列表中所有与该节点接口相关的边并从接口池中删除
for (auto pConnector : Connector_List)
{
int connector_id = pConnector->Get_ID();
// 遍历边池
for (auto iterator = this->Edge_Pool.begin(); iterator != this->Edge_Pool.end(); iterator++)
{
if ((iterator->source_connector_id == connector_id) || (iterator->target_connector_id == connector_id))
{
// 注销边ID
this->Edge_ID_Generator.Release_ID(connector_id);
// 注销边记录,迭代器删除后会返回下一个位置的迭代器
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;
}
// 删除节点 true -> success / false -> failed
bool Workflow_Editor::Del_Node(int target_node_id)
{
// 查找ID
for (auto iterator = this->Node_Pool.begin(); iterator != this->Node_Pool.end(); iterator++)
{
// 从节点池删除对应的节点
if ((*iterator)->Get_ID() == target_node_id)
{
this->Del_Node(iterator);
return true;
}
}
// 未成功查找
return false;
}
// 新增连接 true -> success / false -> failed
bool Workflow_Editor::Add_Link(int source_connector_id, int target_connector_id)
{
// 查找接口
bool find = false;
std::shared_ptr<Abs_Connector> p_source_connector;
std::shared_ptr<Abs_Connector> p_target_connector;
for (auto pNode : this->Node_Pool)
{
for (auto pConnector : pNode->Get_Connector_List())
{
if (pConnector->Get_ID() == source_connector_id)
p_source_connector = pConnector;
if (pConnector->Get_ID() == target_connector_id)
p_target_connector = pConnector;
if ((p_source_connector.get() != nullptr) && (p_target_connector.get() != nullptr))
{
find = true;
break;
}
}
if (find)
break;
}
// 判定查找结果
if (find)
{
// 先尝试连接,成功后再进行边池操作
if (p_source_connector->Connect_To(p_target_connector.get()) == true)
{
// 记录到边池
this->Edge_Pool.push_back({this->Edge_ID_Generator.Request_ID(), source_connector_id, target_connector_id});
/**
* @todo
*/
}
return true;
}
return false;
}
// 删除边 返回迭代器指定位置的下一个位置的迭代器,仅限内部使用
std::vector<Workflow_Editor::Edge>::iterator Workflow_Editor::Del_Link(std::vector<Edge>::iterator iterator)
{
// 查找接口
bool find = false;
std::shared_ptr<Abs_Connector> p_source_connector;
std::shared_ptr<Abs_Connector> p_target_connector;
for (auto pNode : this->Node_Pool)
{
for (auto pConnector : pNode->Get_Connector_List())
{
if (pConnector->Get_ID() == iterator->source_connector_id)
p_source_connector = pConnector;
if (pConnector->Get_ID() == iterator->target_connector_id)
p_target_connector = pConnector;
if ((p_source_connector.get() != nullptr) && (p_target_connector.get() != nullptr))
{
find = true;
break;
}
}
if (find)
break;
}
// 判定查找结果
if (find)
{
// 成功删除连接关系
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);
}
}
return iterator--;
}
// 删除连接 true -> success / false -> failed
bool Workflow_Editor::Del_Link(int source_connector_id, int target_connector_id)
{
// 遍历边池,删除对应的边
for (auto iterator = this->Edge_Pool.begin(); iterator != this->Edge_Pool.end(); iterator++)
if ((iterator->source_connector_id == source_connector_id) && (iterator->target_connector_id == target_connector_id))
{
this->Del_Link(iterator);
return true;
}
return false;
}