Changed the content pointer registered by Register_Package() method to const type && Added three logic gate nodes, now supporting AND, OR, NOT operations. More controlled or conditional type nodes will be added later && Improved the workflow packet passing execution process among existing connectors.

This commit is contained in:
LuChiChick 2026-05-20 15:40:50 +08:00
parent 986028a3a3
commit 5cc61e9486
3 changed files with 523 additions and 12 deletions

View File

@ -67,7 +67,7 @@ public:
* @param count
* @param total_count
*/
virtual bool Register_Package(void *p_content, size_t content_size, size_t count, size_t total_count);
virtual bool Register_Package(const void *p_content, size_t content_size, size_t count, size_t total_count);
// 获取包
virtual const Package Get_Package(void);
@ -99,6 +99,9 @@ public:
NODE_TYPE_CONNECTOR_TEST, // 接口测试节点
NODE_TYPE_MSG_LINE_INPUT, // 消息输入节点
NODE_TYPE_FILTER, // 筛选器节点
NODE_TYPE_LOGIC_AND, // 逻辑与门节点
NODE_TYPE_LOGIC_OR, // 逻辑或门节点
NODE_TYPE_LOGIC_NOT, // 逻辑非门节点
NODE_TYPE_CSV_EXPORTER, // CSV输出节点
} Node_Type_Enum; // 节点类型枚举
@ -303,4 +306,70 @@ public:
virtual bool Execute_Process(void);
};
// 逻辑与门
class Logic_AND_Node : public Abs_Node
{
private:
float node_width = 0;
public:
// 显式禁用默认构造
Logic_AND_Node() = delete;
// 必要构造
Logic_AND_Node(Independent_ID_Generator *Node_ID_Generator,
Independent_ID_Generator *Connector_ID_Generator,
ImVec2 initial_position = ImVec2(0, 0));
// 绘制节点
virtual void Show(void);
// 执行处理流程
virtual bool Execute_Process(void);
};
// 逻辑与门
class Logic_OR_Node : public Abs_Node
{
private:
float node_width = 0;
public:
// 显式禁用默认构造
Logic_OR_Node() = delete;
// 必要构造
Logic_OR_Node(Independent_ID_Generator *Node_ID_Generator,
Independent_ID_Generator *Connector_ID_Generator,
ImVec2 initial_position = ImVec2(0, 0));
// 绘制节点
virtual void Show(void);
// 执行处理流程
virtual bool Execute_Process(void);
};
// 逻辑与门
class Logic_NOT_Node : public Abs_Node
{
private:
float node_width = 0;
public:
// 显式禁用默认构造
Logic_NOT_Node() = delete;
// 必要构造
Logic_NOT_Node(Independent_ID_Generator *Node_ID_Generator,
Independent_ID_Generator *Connector_ID_Generator,
ImVec2 initial_position = ImVec2(0, 0));
// 绘制节点
virtual void Show(void);
// 执行处理流程
virtual bool Execute_Process(void);
};
#endif

View File

@ -165,7 +165,7 @@ bool Abs_Connector::Disconnect_To(Abs_Connector *target)
* @param count
* @param total_count
*/
bool Abs_Connector::Register_Package(void *p_content, size_t content_size, size_t count, size_t total_count)
bool Abs_Connector::Register_Package(const void *p_content, size_t content_size, size_t count, size_t total_count)
{
// 非输出类接口
if (this->type != CONNECTOR_TYPE_OUTPUT)
@ -708,10 +708,11 @@ bool MSG_Input_Node::Execute_Process(void)
if (this->private_excute_count < this->private_excute_end_count)
{
// [0] -> MSG
this->Connector_List[0]->Register_Package((void *)&(this->log.msg_list[this->private_excute_count]),
sizeof(this->log.msg_list[0]),
this->private_excute_count + 1,
this->excute_end_count);
if (this->Connector_List[0]->Register_Package(&(this->log.msg_list[this->private_excute_count]),
sizeof(this->log.msg_list[0]),
this->private_excute_count + 1,
this->excute_end_count) == false)
return false;
this->private_excute_count++;
}
else
@ -738,10 +739,10 @@ Filter_Node::Filter_Node(Independent_ID_Generator *Node_ID_Generator,
// 判定是否成功申请ID
if (this->id != -1)
{
// Boolean 输入节点
// Boolean 相关接口
this->Connector_List.push_back(std::make_shared<Boolean_InPut_Connector>(Connector_ID_Generator)); // [0] -> Boolean
// 消息输出节点
// DLT MSG 相关接口
this->Connector_List.push_back(std::make_shared<MSG_InPut_Connector>(Connector_ID_Generator, true)); // [1] -> MSG
this->Connector_List.push_back(std::make_shared<MSG_OutPut_Connector>(Connector_ID_Generator)); // [2] MSG ->
}
@ -882,12 +883,419 @@ bool Filter_Node::Execute_Process(void)
if (pass_allow)
{
auto pkg = this->Connector_List[1]->Get_Package();
this->Connector_List[2]->Register_Package(pkg.p_content_mem, pkg.content_size, pkg.package_count, pkg.total_count);
return this->Connector_List[2]->Register_Package(pkg.p_content_mem, pkg.content_size, pkg.package_count, pkg.total_count);
}
else
this->Connector_List[2]->Register_Package(nullptr, 0, 0, 0);
return true;
return this->Connector_List[2]->Register_Package(nullptr, 0, 0, 0);
}
// 必要构造
Logic_AND_Node::Logic_AND_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_LOGIC_AND,
initial_position)
{
// 判定是否成功申请ID
if (this->id != -1)
{
// Boolean 相关接口
this->Connector_List.push_back(std::make_shared<Boolean_InPut_Connector>(Connector_ID_Generator)); // [0] -> Boolean
this->Connector_List.push_back(std::make_shared<Boolean_OutPut_Connector>(Connector_ID_Generator)); // [1] Boolean ->
}
}
// 绘制节点
void Logic_AND_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);
}
// 全宽适配
bool all_width_fit = true;
// 绘制节点
ImNodes::BeginNode(this->id);
{
// 获取节点当前长宽维度
ImVec2 dimension = ImNodes::GetNodeDimensions(this->id);
// 标题部分
ImNodes::BeginNodeTitleBar();
{
const char *title_str = u8"Logic AND";
ImGui::Text(title_str);
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"逻辑与门,对输入逻辑状态进行与运算");
ImGui::EndTooltip();
}
ImGui::PopStyleVar();
}
ImGui::SameLine();
// 节点宽度调整
ImVec2 dimension = ImNodes::GetNodeDimensions(this->id);
auto button_diameter = ImGui::GetTextLineHeight();
auto text_width = ImGui::CalcTextSize(title_str).x + ImGui::CalcTextSize(u8"(?)").x;
auto Tittle_Str_Width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::GetStyle().ItemSpacing.x * 2;
// 宽度判定
if (dimension.x < Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x)
all_width_fit = false;
ImGui::Dummy(ImVec2(this->node_width - Tittle_Str_Width - button_diameter - ImGui::GetStyle().ItemSpacing.x, 0.0f));
ImGui::SameLine();
// 绘制关闭按钮
if (CircleButtonWithX("#X", button_diameter / 2))
this->close_flag = true;
}
ImNodes::EndNodeTitleBar();
// 节点主体部分
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y));
// 绘制 Boolean 相关接口组
{
// 宽度判定
auto text_width = ImGui::CalcTextSize("-> Boolean-In").x + ImGui::CalcTextSize("Boolean-Out ->").x;
if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::CalcTextSize("A").x)
all_width_fit = false;
// 宽度初始化
if (this->node_width == 0)
this->node_width = text_width;
this->Connector_List[0]->Show();
ImGui::SameLine();
ImGui::Text("-> Boolean-In");
ImGui::SameLine();
ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f));
ImGui::SameLine();
ImGui::Text("Boolean-Out ->");
ImGui::SameLine();
this->Connector_List[1]->Show();
}
ImGui::PopStyleVar();
}
// 使用递进的方式自适应宽度
if (all_width_fit == false)
this->node_width += 1.0f;
}
ImNodes::EndNode();
}
// 执行处理流程
bool Logic_AND_Node::Execute_Process(void)
{
bool out_logic = true;
for (auto connector : this->Connector_List[0]->Get_Related_List())
{
auto pkg = connector->Get_Package();
if ((pkg.content_size == 0) || (*((const bool *)pkg.p_content_mem) == false))
{
out_logic = false;
break;
}
}
return this->Connector_List[1]->Register_Package(&out_logic, sizeof(out_logic), 0, 0);
}
// 必要构造
Logic_OR_Node::Logic_OR_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_LOGIC_OR,
initial_position)
{
// 判定是否成功申请ID
if (this->id != -1)
{
// Boolean 相关接口
this->Connector_List.push_back(std::make_shared<Boolean_InPut_Connector>(Connector_ID_Generator)); // [0] -> Boolean
this->Connector_List.push_back(std::make_shared<Boolean_OutPut_Connector>(Connector_ID_Generator)); // [1] Boolean ->
}
}
// 绘制节点
void Logic_OR_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);
}
// 全宽适配
bool all_width_fit = true;
// 绘制节点
ImNodes::BeginNode(this->id);
{
// 获取节点当前长宽维度
ImVec2 dimension = ImNodes::GetNodeDimensions(this->id);
// 标题部分
ImNodes::BeginNodeTitleBar();
{
const char *title_str = u8"Logic OR";
ImGui::Text(title_str);
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"逻辑或门,对输入逻辑状态进行或运算");
ImGui::EndTooltip();
}
ImGui::PopStyleVar();
}
ImGui::SameLine();
// 节点宽度调整
ImVec2 dimension = ImNodes::GetNodeDimensions(this->id);
auto button_diameter = ImGui::GetTextLineHeight();
auto text_width = ImGui::CalcTextSize(title_str).x + ImGui::CalcTextSize(u8"(?)").x;
auto Tittle_Str_Width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::GetStyle().ItemSpacing.x * 2;
// 宽度判定
if (dimension.x < Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x)
all_width_fit = false;
ImGui::Dummy(ImVec2(this->node_width - Tittle_Str_Width - button_diameter - ImGui::GetStyle().ItemSpacing.x, 0.0f));
ImGui::SameLine();
// 绘制关闭按钮
if (CircleButtonWithX("#X", button_diameter / 2))
this->close_flag = true;
}
ImNodes::EndNodeTitleBar();
// 节点主体部分
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y));
// 绘制 Boolean 相关接口组
{
// 宽度判定
auto text_width = ImGui::CalcTextSize("-> Boolean-In").x + ImGui::CalcTextSize("Boolean-Out ->").x;
if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::CalcTextSize("A").x)
all_width_fit = false;
// 宽度初始化
if (this->node_width == 0)
this->node_width = text_width;
this->Connector_List[0]->Show();
ImGui::SameLine();
ImGui::Text("-> Boolean-In");
ImGui::SameLine();
ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f));
ImGui::SameLine();
ImGui::Text("Boolean-Out ->");
ImGui::SameLine();
this->Connector_List[1]->Show();
}
ImGui::PopStyleVar();
}
// 使用递进的方式自适应宽度
if (all_width_fit == false)
this->node_width += 1.0f;
}
ImNodes::EndNode();
}
// 执行处理流程
bool Logic_OR_Node::Execute_Process(void)
{
bool out_logic = false;
for (auto connector : this->Connector_List[0]->Get_Related_List())
{
auto pkg = connector->Get_Package();
if ((pkg.content_size > 0) && (*((const bool *)pkg.p_content_mem) == true))
{
out_logic = true;
break;
}
}
return this->Connector_List[1]->Register_Package(&out_logic, sizeof(out_logic), 0, 0);
}
// 必要构造
Logic_NOT_Node::Logic_NOT_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_LOGIC_NOT,
initial_position)
{
// 判定是否成功申请ID
if (this->id != -1)
{
// Boolean 相关接口
this->Connector_List.push_back(std::make_shared<Boolean_InPut_Connector>(Connector_ID_Generator, true)); // [0] -> Boolean
this->Connector_List.push_back(std::make_shared<Boolean_OutPut_Connector>(Connector_ID_Generator)); // [1] Boolean ->
}
}
// 绘制节点
void Logic_NOT_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);
}
// 全宽适配
bool all_width_fit = true;
// 绘制节点
ImNodes::BeginNode(this->id);
{
// 获取节点当前长宽维度
ImVec2 dimension = ImNodes::GetNodeDimensions(this->id);
// 标题部分
ImNodes::BeginNodeTitleBar();
{
const char *title_str = u8"Logic NOT";
ImGui::Text(title_str);
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"逻辑非门,对输入逻辑状态进行非运算");
ImGui::EndTooltip();
}
ImGui::PopStyleVar();
}
ImGui::SameLine();
// 节点宽度调整
ImVec2 dimension = ImNodes::GetNodeDimensions(this->id);
auto button_diameter = ImGui::GetTextLineHeight();
auto text_width = ImGui::CalcTextSize(title_str).x + ImGui::CalcTextSize(u8"(?)").x;
auto Tittle_Str_Width = text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::GetStyle().ItemSpacing.x * 2;
// 宽度判定
if (dimension.x < Tittle_Str_Width + button_diameter + ImGui::GetStyle().ItemSpacing.x)
all_width_fit = false;
ImGui::Dummy(ImVec2(this->node_width - Tittle_Str_Width - button_diameter - ImGui::GetStyle().ItemSpacing.x, 0.0f));
ImGui::SameLine();
// 绘制关闭按钮
if (CircleButtonWithX("#X", button_diameter / 2))
this->close_flag = true;
}
ImNodes::EndNodeTitleBar();
// 节点主体部分
{
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y));
// 绘制 Boolean 相关接口组
{
// 宽度判定
auto text_width = ImGui::CalcTextSize("-> Boolean-In").x + ImGui::CalcTextSize("Boolean-Out ->").x;
if (dimension.x < text_width + ImNodes::GetStyle().NodePadding.x * 2 + ImGui::CalcTextSize("A").x)
all_width_fit = false;
// 宽度初始化
if (this->node_width == 0)
this->node_width = text_width;
this->Connector_List[0]->Show();
ImGui::SameLine();
ImGui::Text("-> Boolean-In");
ImGui::SameLine();
ImGui::Dummy(ImVec2(this->node_width - text_width - ImNodes::GetStyle().NodePadding.x * 2, 0.0f));
ImGui::SameLine();
ImGui::Text("Boolean-Out ->");
ImGui::SameLine();
this->Connector_List[1]->Show();
}
ImGui::PopStyleVar();
}
// 使用递进的方式自适应宽度
if (all_width_fit == false)
this->node_width += 1.0f;
}
ImNodes::EndNode();
}
// 执行处理流程
bool Logic_NOT_Node::Execute_Process(void)
{
auto pkg = this->Connector_List[0]->Get_Related_List()[0]->Get_Package();
bool out_logic;
if (pkg.content_size == 0 || ((*(bool *)pkg.p_content_mem) == false))
out_logic = false;
else
out_logic = true;
out_logic = !out_logic;
return this->Connector_List[1]->Register_Package(&out_logic, sizeof(out_logic), 0, 0);
}
// END

View File

@ -65,6 +65,20 @@ void Workflow_Editor::Show(void)
this->Add_Node(Abs_Node::NODE_TYPE_MSG_LINE_INPUT, click_pos);
if (ImGui::MenuItem(u8"消息筛选器"))
this->Add_Node(Abs_Node::NODE_TYPE_FILTER, click_pos);
// 逻辑门节点
if (ImGui::BeginMenu(u8"逻辑门节点"))
{
if (ImGui::MenuItem(u8"AND"))
this->Add_Node(Abs_Node::NODE_TYPE_LOGIC_AND, click_pos);
if (ImGui::MenuItem(u8"OR"))
this->Add_Node(Abs_Node::NODE_TYPE_LOGIC_OR, click_pos);
if (ImGui::MenuItem(u8"NOT"))
this->Add_Node(Abs_Node::NODE_TYPE_LOGIC_NOT, click_pos);
ImGui::EndMenu();
}
ImGui::EndMenu();
}
@ -278,7 +292,27 @@ bool Workflow_Editor::Add_Node(Abs_Node::Node_Type_Enum type, ImVec2 initial_pos
&this->Connector_ID_Generator,
initial_position);
break;
case Abs_Node::NODE_TYPE_LOGIC_AND: // 逻辑与门节点
// 创建节点
p_New_Node = std::make_shared<Logic_AND_Node>(&this->Node_ID_Generator,
&this->Connector_ID_Generator,
initial_position);
break;
case Abs_Node::NODE_TYPE_LOGIC_OR: // 逻辑或门节点
// 创建节点
p_New_Node = std::make_shared<Logic_OR_Node>(&this->Node_ID_Generator,
&this->Connector_ID_Generator,
initial_position);
break;
case Abs_Node::NODE_TYPE_LOGIC_NOT: // 逻辑非门节点
// 创建节点
p_New_Node = std::make_shared<Logic_NOT_Node>(&this->Node_ID_Generator,
&this->Connector_ID_Generator,
initial_position);
break;
case Abs_Node::NODE_TYPE_CSV_EXPORTER: // CSV输出器
break;
default: