diff --git a/src/MaaCore/Assistant.cpp b/src/MaaCore/Assistant.cpp index 0c0995a504..6ce73597a4 100644 --- a/src/MaaCore/Assistant.cpp +++ b/src/MaaCore/Assistant.cpp @@ -5,7 +5,6 @@ #include #include "Config/GeneralConfig.h" -#include "Config/Miscellaneous/OcrPack.h" #include "Controller/Controller.h" #include "Status.h" #include "Task/Interface/AwardTask.h" @@ -160,16 +159,6 @@ bool asst::Assistant::ctrl_connect(const std::string& adb_path, const std::strin return ret; } -bool asst::Assistant::ctrl_click(int x, int y) -{ - return m_ctrler->click(Point(x, y)); -} - -bool asst::Assistant::ctrl_screencap() -{ - return m_ctrler->screencap(); -} - asst::Assistant::TaskId asst::Assistant::append_task(const std::string& type, const std::string& params) { Log.info(__FUNCTION__, type, params); @@ -281,23 +270,21 @@ asst::Assistant::AsyncCallId asst::Assistant::async_connect(const std::string& a { LogTraceFunction; - return append_async_call( - AsyncCallItem::Type::Connect, - AsyncCallItem::ConnectParams { .adb_path = adb_path, .address = address, .config = config }, block); + return append_async_call([=, this]() { return ctrl_connect(adb_path, address, config); }, block, "Connect"); } asst::Assistant::AsyncCallId asst::Assistant::async_click(int x, int y, bool block) { LogTraceFunction; - return append_async_call(AsyncCallItem::Type::Click, AsyncCallItem::ClickParams { .x = x, .y = y }, block); + return append_async_call([=, this]() { return m_ctrler->click(Point(x, y)); }, block, "Click"); } asst::Assistant::AsyncCallId asst::Assistant::async_screencap(bool block) { LogTraceFunction; - return append_async_call(AsyncCallItem::Type::Screencap, AsyncCallItem::ScreencapParams {}, block); + return append_async_call([this]() { return m_ctrler->screencap(); }, block, "Screencap"); } bool asst::Assistant::connected() const @@ -445,17 +432,16 @@ void Assistant::msg_proc() } } -asst::Assistant::AsyncCallId asst::Assistant::append_async_call(AsyncCallItem::Type type, AsyncCallItem::Parmas params, - bool block) +asst::Assistant::AsyncCallId asst::Assistant::append_async_call(std::function func, bool block, + std::string what) { LogTraceFunction; - AsyncCallId id = 0; + AsyncCallId id; { std::unique_lock lock(m_call_mutex); id = ++m_call_id; - AsyncCallItem item { .id = id, .type = type, .params = std::move(params) }; - + AsyncCallItem item = { id, std::move(func), std::move(what) }; m_call_queue.emplace(std::move(item)); m_call_condvar.notify_one(); } @@ -471,12 +457,9 @@ asst::Assistant::AsyncCallId asst::Assistant::append_async_call(AsyncCallItem::T bool asst::Assistant::wait_async_id(AsyncCallId id) { while (!m_thread_exit) { - std::unique_lock lock(m_completed_call_mutex); - // 需要保证队列中id一定是有序的 - if (id <= m_completed_call) { - return true; - } - m_completed_call_condvar.wait(lock); + auto old = m_completed_call.load(); + if (old >= id) return true; + m_completed_call.wait(old); } return false; } @@ -486,55 +469,30 @@ void asst::Assistant::call_proc() LogTraceFunction; while (!m_thread_exit) { - std::unique_lock lock(m_call_mutex); - if (m_call_queue.empty()) { - m_call_condvar.wait(lock); - continue; - } - - auto call_item = std::move(m_call_queue.front()); - m_call_queue.pop(); - lock.unlock(); - - auto start = std::chrono::steady_clock::now(); - bool ret = false; - std::string what; - - switch (call_item.type) { - case AsyncCallItem::Type::Connect: { - what = "Connect"; - const auto& [adb_path, address, config] = std::get(call_item.params); - ret = ctrl_connect(adb_path, address, config); - } break; - case AsyncCallItem::Type::Click: { - what = "Click"; - const auto& [x, y] = std::get(call_item.params); - ret = ctrl_click(x, y); - } break; - case AsyncCallItem::Type::Screencap: { - what = "Screencap"; - std::ignore = std::get(call_item.params); - ret = ctrl_screencap(); - } break; - default: - what = "Unknown"; - ret = false; - break; - } + AsyncCallItem old_call_item; { - std::unique_lock completed_call_lock(m_completed_call_mutex); - m_completed_call = call_item.id; - m_completed_call_condvar.notify_all(); + std::unique_lock lock(m_call_mutex); + if (m_call_queue.empty()) { + m_call_condvar.wait(lock); + continue; + } + old_call_item = std::move(m_call_queue.front()); + m_call_queue.pop(); } + auto start = std::chrono::steady_clock::now(); + bool ret = old_call_item.function(); + m_completed_call = old_call_item.id; + m_completed_call.notify_all(); + auto cost = std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count(); json::value cb_info = json::object { { "uuid", m_uuid }, - { "what", what }, - { "async_call_id", call_item.id }, + { "what", old_call_item.what }, + { "async_call_id", old_call_item.id }, { "details", json::object { diff --git a/src/MaaCore/Assistant.h b/src/MaaCore/Assistant.h index 84686e0352..9a15293578 100644 --- a/src/MaaCore/Assistant.h +++ b/src/MaaCore/Assistant.h @@ -104,35 +104,18 @@ namespace asst private: struct AsyncCallItem { - enum class Type - { - Connect, - Click, - Screencap, - }; - struct ConnectParams - { - std::string adb_path; - std::string address; - std::string config; - }; - struct ClickParams - { - int x = 0; - int y = 0; - }; - struct ScreencapParams - {}; - using Parmas = std::variant; - AsyncCallId id; - Type type; - Parmas params; + std::function function; + std::string what = "Unknown"; }; - AsyncCallId append_async_call(AsyncCallItem::Type type, AsyncCallItem::Parmas params, bool block = false); + + // submit async call task to queue + asst::Assistant::AsyncCallId append_async_call(std::function func, bool block, + std::string what = "Unknown"); bool wait_async_id(AsyncCallId id); private: + // thread executing async call tasks one by one from queue void call_proc(); void working_proc(); void msg_proc(); @@ -142,8 +125,6 @@ namespace asst bool inited() const noexcept; bool ctrl_connect(const std::string& adb_path, const std::string& address, const std::string& config); - bool ctrl_click(int x, int y); - bool ctrl_screencap(); std::string m_uuid; @@ -169,9 +150,7 @@ namespace asst std::mutex m_call_mutex; std::condition_variable m_call_condvar; - AsyncCallId m_completed_call = 0; // 每个实例有自己独立的执行队列,所以不能静态 - std::mutex m_completed_call_mutex; - std::condition_variable m_completed_call_condvar; + std::atomic m_completed_call = 0; // 每个实例有自己独立的执行队列,所以不能静态 std::thread m_msg_thread; std::thread m_call_thread;