From dab01fbafd23ed5b648581482309dfc998f9f77d Mon Sep 17 00:00:00 2001 From: MistEO Date: Fri, 6 Aug 2021 00:48:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=9E=E8=B0=83=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E7=9A=84=E5=A4=84=E7=90=86=E7=BA=BF=E7=A8=8B=E5=92=8C?= =?UTF-8?q?=E9=98=9F=E5=88=97=EF=BC=9B=E5=AE=8C=E6=88=90=E4=B8=BB=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E7=9A=84=E5=9B=9E=E8=B0=83=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MeoAssistance/include/Assistance.h | 20 +++-- MeoAssistance/include/Logger.hpp | 3 +- MeoAssistance/include/Task.h | 8 +- MeoAssistance/src/Assistance.cpp | 66 ++++++++++++----- MeoAssistance/src/Task.cpp | 14 +++- MeoAsstGui/App.xaml | 9 ++- MeoAsstGui/MainWindow.xaml.cs | 113 ++++++++++++++++++----------- MeoAsstGui/MeoAsstGui.csproj | 4 + MeoAsstGui/packages.config | 6 ++ 9 files changed, 168 insertions(+), 75 deletions(-) create mode 100644 MeoAsstGui/packages.config diff --git a/MeoAssistance/include/Assistance.h b/MeoAssistance/include/Assistance.h index 57205bc4c9..87b83dd829 100644 --- a/MeoAssistance/include/Assistance.h +++ b/MeoAssistance/include/Assistance.h @@ -42,7 +42,8 @@ namespace asst { std::optional get_param(const std::string& type, const std::string& param); private: - static void working_proc(Assistance* pThis); + static void working_proc(Assistance* p_this); + static void msg_proc(Assistance* p_this); static void task_callback(TaskMsg msg, const json::value& detail, void* custom_arg); void append_match_task(const std::vector& tasks); @@ -55,15 +56,22 @@ namespace asst { std::shared_ptr m_identify_ptr = nullptr; bool m_inited = false; + bool m_thread_exit = false; + std::queue> m_tasks_queue; + TaskCallback m_callback = nullptr; + void* m_callback_arg = nullptr; + + bool m_thread_idle = true; std::thread m_working_thread; std::mutex m_mutex; std::condition_variable m_condvar; - bool m_thread_exit = false; - bool m_thread_idle = true; - std::queue> m_tasks_queue; - TaskCallback m_callback = nullptr; - void* m_callback_arg = nullptr; + std::thread m_msg_thread; + std::queue> m_msg_queue; + std::mutex m_msg_mutex; + std::condition_variable m_msg_condvar; + + }; } \ No newline at end of file diff --git a/MeoAssistance/include/Logger.hpp b/MeoAssistance/include/Logger.hpp index 574f1b9587..7fa962cf61 100644 --- a/MeoAssistance/include/Logger.hpp +++ b/MeoAssistance/include/Logger.hpp @@ -110,4 +110,5 @@ namespace asst { #define DebugTrace Logger::get_instance().log_trace #define DebugTraceInfo Logger::get_instance().log_info #define DebugTraceError Logger::get_instance().log_error -#define DebugTraceFunction LoggerAux _func_aux(__FUNCTION__) \ No newline at end of file +#define DebugTraceFunction LoggerAux _func_aux(__FUNCTION__) +#define DebugTraceScope LoggerAux _func_aux \ No newline at end of file diff --git a/MeoAssistance/include/Task.h b/MeoAssistance/include/Task.h index 91b1651980..1b6f3913db 100644 --- a/MeoAssistance/include/Task.h +++ b/MeoAssistance/include/Task.h @@ -10,6 +10,8 @@ #include "AsstDef.h" #include "AsstAux.h" +#include + namespace cv { class Mat; @@ -39,6 +41,7 @@ namespace asst { ImageIsEmpty, WindowMinimized, /* Info Msg */ + TaskStart, ImageMatched, TaskMatched, ReachedLimit, @@ -47,7 +50,7 @@ namespace asst { AppendMatchTask, TaskCompleted, PrintWindow, - MissionStop, + TaskStop, /* Open Recruit Msg */ TextDetected, RecruitTagsDetected, @@ -62,6 +65,7 @@ namespace asst { {TaskMsg::PtrIsNull, "PtrIsNull"}, {TaskMsg::ImageIsEmpty, "ImageIsEmpty"}, {TaskMsg::WindowMinimized, "WindowMinimized"}, + {TaskMsg::TaskStart, "TaskStart"}, {TaskMsg::ImageMatched, "ImageMatched"}, {TaskMsg::TaskMatched, "TaskMatched"}, {TaskMsg::ReachedLimit, "ReachedLimit"}, @@ -70,7 +74,7 @@ namespace asst { {TaskMsg::AppendMatchTask, "AppendMatchTask"}, {TaskMsg::TaskCompleted, "TaskCompleted"}, {TaskMsg::PrintWindow, "PrintWindow"}, - {TaskMsg::MissionStop, "MissionStop"}, + {TaskMsg::TaskStop, "TaskStop"}, {TaskMsg::TextDetected, "TextDetected"}, {TaskMsg::RecruitTagsDetected, "RecruitTagsDetected"}, {TaskMsg::OcrResultError, "OcrResultError"}, diff --git a/MeoAssistance/src/Assistance.cpp b/MeoAssistance/src/Assistance.cpp index 0f8bb7afb7..14f0a4c305 100644 --- a/MeoAssistance/src/Assistance.cpp +++ b/MeoAssistance/src/Assistance.cpp @@ -35,6 +35,7 @@ Assistance::Assistance(TaskCallback callback, void* callback_arg) m_identify_ptr->ocr_init_models(GetResourceDir() + "OcrLiteNcnn\\models\\"); m_working_thread = std::thread(working_proc, this); + m_msg_thread = std::thread(msg_proc, this); } Assistance::~Assistance() @@ -48,10 +49,14 @@ Assistance::~Assistance() m_thread_exit = true; m_thread_idle = true; m_condvar.notify_all(); + m_msg_condvar.notify_all(); if (m_working_thread.joinable()) { m_working_thread.join(); } + if (m_msg_thread.joinable()) { + m_msg_thread.join(); + } } std::optional Assistance::catch_emulator(const std::string& emulator_name) @@ -184,23 +189,24 @@ std::optional Assistance::get_param(const std::string& type, const return Configer::get_instance().get_param(type, param); } -void Assistance::working_proc(Assistance* pThis) +void Assistance::working_proc(Assistance* p_this) { DebugTraceFunction; int retry_times = 0; - while (!pThis->m_thread_exit) { - std::unique_lock lock(pThis->m_mutex); - if (!pThis->m_thread_idle && !pThis->m_tasks_queue.empty()) { + while (!p_this->m_thread_exit) { + DebugTraceScope("Assistance::working_proc Loop"); + std::unique_lock lock(p_this->m_mutex); + if (!p_this->m_thread_idle && !p_this->m_tasks_queue.empty()) { auto start_time = std::chrono::system_clock::now(); - std::shared_ptr task_ptr = pThis->m_tasks_queue.front(); - task_ptr->set_ptr(pThis->m_window_ptr, pThis->m_view_ptr, pThis->m_control_ptr, pThis->m_identify_ptr); - task_ptr->set_exit_flag(&pThis->m_thread_idle); + std::shared_ptr task_ptr = p_this->m_tasks_queue.front(); + task_ptr->set_ptr(p_this->m_window_ptr, p_this->m_view_ptr, p_this->m_control_ptr, p_this->m_identify_ptr); + task_ptr->set_exit_flag(&p_this->m_thread_idle); bool ret = task_ptr->run(); if (ret) { retry_times = 0; - pThis->m_tasks_queue.pop(); + p_this->m_tasks_queue.pop(); } else // 失败了不pop,一直跑。 Todo: 设一个上限 { @@ -210,8 +216,8 @@ void Assistance::working_proc(Assistance* pThis) // 如果下个任务是识别,就按识别的延时来;如果下个任务是点击,就按点击的延时来;…… // 如果都符合,就取个最大值 int delay = 0; - if (!pThis->m_tasks_queue.empty()) { - int next_type = pThis->m_tasks_queue.front()->get_task_type(); + if (!p_this->m_tasks_queue.empty()) { + int next_type = p_this->m_tasks_queue.front()->get_task_type(); std::vector candidate_delay = { 0 }; if (next_type & TaskType::TaskTypeClick) { candidate_delay.emplace_back(Configer::get_instance().m_options.task_control_delay); @@ -221,21 +227,45 @@ void Assistance::working_proc(Assistance* pThis) } delay = *std::max_element(candidate_delay.cbegin(), candidate_delay.cend()); } - pThis->m_condvar.wait_until(lock, + p_this->m_condvar.wait_until(lock, start_time + std::chrono::milliseconds(delay), - [&]() -> bool { return pThis->m_thread_idle; }); + [&]() -> bool { return p_this->m_thread_idle; }); } else { - pThis->m_thread_idle = true; - pThis->m_condvar.wait(lock); + p_this->m_thread_idle = true; + p_this->m_condvar.wait(lock); + } + } +} + +void Assistance::msg_proc(Assistance* p_this) +{ + DebugTraceFunction; + + while (!p_this->m_thread_exit) { + DebugTraceScope("Assistance::msg_proc Loop"); + std::unique_lock lock(p_this->m_msg_mutex); + if (!p_this->m_msg_queue.empty()) { + // 结构化绑定只能是引用,后续的pop会使引用失效,所以需要重新构造一份,这里采用了move的方式 + auto && [temp_msg, temp_detail] = p_this->m_msg_queue.front(); + TaskMsg msg = std::move(temp_msg); + json::value detail = std::move(temp_detail); + p_this->m_msg_queue.pop(); + lock.unlock(); + + if (p_this->m_callback) { + p_this->m_callback(msg, detail, p_this->m_callback_arg); + } + } + else { + p_this->m_msg_condvar.wait(lock); } } } void Assistance::task_callback(TaskMsg msg, const json::value& detail, void* custom_arg) { - DebugTraceFunction; - DebugTrace(msg, detail.to_string()); + DebugTrace("Assistance::task_callback |", msg, detail.to_string()); Assistance* p_this = (Assistance*)custom_arg; json::value more_detail = detail; @@ -259,7 +289,9 @@ void Assistance::task_callback(TaskMsg msg, const json::value& detail, void* cus } if (p_this->m_callback) { - p_this->m_callback(msg, more_detail, p_this->m_callback_arg); + std::unique_lock lock(p_this->m_msg_mutex); + p_this->m_msg_queue.emplace(msg, std::move(more_detail)); + p_this->m_msg_condvar.notify_one(); } } diff --git a/MeoAssistance/src/Task.cpp b/MeoAssistance/src/Task.cpp index 33debe8ad1..aeff24de45 100644 --- a/MeoAssistance/src/Task.cpp +++ b/MeoAssistance/src/Task.cpp @@ -140,6 +140,8 @@ bool MatchTask::run() return false; } + m_callback(TaskMsg::TaskStart, json::value(), m_callback_arg); + Rect rect; auto&& ret = match_image(&rect); if (!ret) { @@ -179,7 +181,7 @@ bool MatchTask::run() case MatchTaskType::DoNothing: break; case MatchTaskType::Stop: - m_callback(TaskMsg::MissionStop, json::value(), m_callback_arg); + m_callback(TaskMsg::TaskStop, json::value(), m_callback_arg); need_stop = true; break; case MatchTaskType::PrintWindow: @@ -206,12 +208,12 @@ bool MatchTask::run() return true; } - // 后置固定延时 - sleep(task.rear_delay); - callback_json["exec_times"] = task.exec_times; m_callback(TaskMsg::TaskCompleted, callback_json, m_callback_arg); + // 后置固定延时 + sleep(task.rear_delay); + json::value next_json = callback_json; next_json["tasks"] = json::array(task.next); m_callback(TaskMsg::AppendMatchTask, next_json, m_callback_arg); @@ -314,6 +316,8 @@ bool OpenRecruitTask::run() return false; } + m_callback(TaskMsg::TaskStart, json::value(), m_callback_arg); + /* Find all text */ std::vector