diff --git a/Inc/Nodes_And_Connectors.hpp b/Inc/Nodes_And_Connectors.hpp index 2722da1..8b21740 100644 --- a/Inc/Nodes_And_Connectors.hpp +++ b/Inc/Nodes_And_Connectors.hpp @@ -6,6 +6,7 @@ #include "imgui.h" #include "imnodes.h" #include "ID_Generator.hpp" +#include "DLT_Utilities.hpp" #include "Json_Utilities.hpp" // =====================================接口抽象====================================================== @@ -20,6 +21,14 @@ public: CONNECTOR_TYPE_INPUT, // 输入 } Connector_Type_Enum; // 接口类型枚举 + typedef struct + { + size_t package_count = 0; // 包计数 (常规非0) + size_t total_count = 0; // 总计数 (常规非0,不定长包时为0) + void *p_content_mem = nullptr; // 包存储 + size_t content_size = 0; // 包大小 + } Package; // 接口包定义 + protected: // ID 分配器 Independent_ID_Generator *ID_Generator; @@ -29,7 +38,7 @@ protected: const char *socket_str; // 套接字字符串 std::vector related_connector_list; // 关联列表 - void *product; // 产物(仅输出类节点持有) + Package pkg; // 接口包(仅输出类节点持有) public: // 显式禁用默认构造 @@ -50,15 +59,21 @@ public: // 与指定的接口断开连接 virtual bool Disconnect_To(Abs_Connector *target); - // 注册产物 - virtual bool Register_Product(void *product, size_t size); + /** + * 注册包 + * @param p_content 目标容物指针 + * @param content_size 容物大小 + * @param count 当前包位置 + * @param total_count 包流总长度 + */ + virtual bool Register_Package(void *p_content, size_t content_size, size_t count, size_t total_count); + + // 获取包 + virtual const Package Get_Package(void); // 获取关联接口列表 virtual std::vector Get_Related_List(void); - // 获取产物 - virtual void *Get_Product(void); - // 获取ID virtual int Get_ID(void); @@ -222,7 +237,20 @@ class MSG_Input_Node : public Abs_Node private: float node_width = 0; + DLT_Log log; + + // 执行相关 + bool excute_flag = false; + size_t private_excute_count = 0; + size_t private_excute_end_count = 0; + bool private_finish_flag = false; + public: + // 只读引用 + const bool &finish_flag = this->private_finish_flag; + const size_t &excute_count = this->private_excute_count; + const size_t &excute_end_count = this->private_excute_end_count; + // 显式禁用默认构造 MSG_Input_Node() = delete; diff --git a/Src/Nodes_And_Connectors.cpp b/Src/Nodes_And_Connectors.cpp index 680c696..6658dd5 100644 --- a/Src/Nodes_And_Connectors.cpp +++ b/Src/Nodes_And_Connectors.cpp @@ -1,6 +1,8 @@ #include "Nodes_And_Connectors.hpp" #include "Json_Utilities.hpp" #include "imgui_internal.h" +#include "Global_Variables.hpp" +#include "DLT_Utilities.hpp" // 客制化圆形带X按钮 bool CircleButtonWithX(const char *id, float radius) @@ -75,17 +77,14 @@ Abs_Connector::Abs_Connector(Independent_ID_Generator *ID_Generator, this->type = type; this->socket_str = socket_str; } - - // 指针初始化 - this->product = nullptr; }; // 析构 Abs_Connector::~Abs_Connector() { // 释放产物 - if (this->product != nullptr) - free(product); + if (this->pkg.p_content_mem != nullptr) + free(this->pkg.p_content_mem); // 断开所有连接 this->Disconnect_All(); // 释放ID @@ -155,24 +154,41 @@ bool Abs_Connector::Disconnect_To(Abs_Connector *target) return false; } -// 注册产物 -bool Abs_Connector::Register_Product(void *product, size_t size) +/** + * 注册包 + * @param p_content 目标容物指针 + * @param content_size 容物大小 + * @param count 当前包位置 + * @param total_count 包流总长度 + */ +bool Abs_Connector::Register_Package(void *p_content, size_t content_size, size_t count, size_t total_count) { // 非输出类接口 if (this->type != CONNECTOR_TYPE_OUTPUT) return false; // 释放之前的产物 - if (this->product != nullptr) - free(this->product); + if (this->pkg.p_content_mem != nullptr) + free(this->pkg.p_content_mem); // 分配空间 - this->product = malloc(size); - if (this->product == nullptr) - return false; + if (content_size > 0) + { + this->pkg.p_content_mem = malloc(content_size); + if (this->pkg.p_content_mem == nullptr) + return false; + + // 复制内容 + memcpy(this->pkg.p_content_mem, p_content, content_size); + } + else + this->pkg.p_content_mem = nullptr; + + // 包信息 + this->pkg.package_count = count; + this->pkg.total_count = total_count; + this->pkg.content_size = content_size; - // 复制内容 - memcpy(this->product, product, size); return true; } @@ -183,14 +199,14 @@ std::vector Abs_Connector::Get_Related_List(void) } // 获取产物 -void *Abs_Connector::Get_Product(void) +const Abs_Connector::Package Abs_Connector::Get_Package(void) { // 输出节点返回直接产物 if (this->type == CONNECTOR_TYPE_OUTPUT) - return this->product; + return this->pkg; // 其它情况返回空值 - return nullptr; + return {}; } // 获取ID @@ -487,7 +503,7 @@ MSG_Input_Node::MSG_Input_Node(Independent_ID_Generator *Node_ID_Generator, if (this->id != -1) { // 消息输出节点 - this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); + this->Connector_List.push_back(std::make_shared(Connector_ID_Generator)); // [0] -> MSG } } @@ -588,5 +604,75 @@ void MSG_Input_Node::Show(void) // 执行处理流程 bool MSG_Input_Node::Execute_Process(void) { + // 未开始执行时 + if (this->excute_flag == false) + { + private_finish_flag = false; + + // 错误信息 + std::string err_str; + const char *err_filename_str = nullptr; + + // 循环加载文件 + Input_File_Node *p_file_list = input_dlt_file_list_head; + while (p_file_list != nullptr) + { + err_str = this->log.Load_From_File(p_file_list->file_name_str); + if (!err_str.empty()) + { + err_filename_str = p_file_list->file_name_str; + break; + } + p_file_list = p_file_list->p_next; + } + + // 输出错误信息 + if (!err_str.empty()) + { + // 工具Lambda string 转 wstring + auto Lambda_String_To_WString = [](const std::string &str) -> std::wstring + { + if (str.empty()) + return std::wstring(); + int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0); + if (len <= 0) + return std::wstring(); + std::wstring wstr(len, L'\0'); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstr[0], len); + return wstr; + }; + + // 输出错误信息 + MessageBoxW(Main_Window_hWnd, (L"文件\"" + Lambda_String_To_WString(std::string(err_filename_str)) + L"\"读取失败\n" + Lambda_String_To_WString(err_str)).c_str(), L"", MB_OK | MB_ICONERROR); + return false; + } + + // 排序后消息处理 + this->log.Sort(); + this->excute_flag = true; + this->private_excute_end_count = this->log.msg_list.size(); + } + else + { + // 注册接口包,执行期间不可以释放log,否则传入的产物中vector会虚空索引 + 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); + this->private_excute_count++; + } + else + { + this->log.Clear(); + this->excute_flag = false; + this->private_excute_count = 0; + this->private_excute_end_count = 0; + this->private_finish_flag = true; + } + } + return true; }; \ No newline at end of file diff --git a/Src/Workflow_Editor.cpp b/Src/Workflow_Editor.cpp index 8dcd4f9..15f5997 100644 --- a/Src/Workflow_Editor.cpp +++ b/Src/Workflow_Editor.cpp @@ -672,18 +672,19 @@ bool Workflow_Editor::Execute_Workflow(void) * @todo 线程分离 * 将任务单独分离到线程中,并跟随进度条 */ + if (this->Build_Process_Route() == false) + return false; - bool status = this->Build_Process_Route(); - if (status == false) - return status; - + // 循环执行工作流 for (auto Route : this->Process_Route) - for (auto pNode : Route) + { + do { - status = pNode->Execute_Process(); - if (status == false) - return false; - } + for (auto pNode : Route) + if (pNode->Execute_Process() == false) + return false; + } while (!((MSG_Input_Node *)(&(*Route[0])))->finish_flag); + } return true; }