mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-19 10:32:19 +08:00
perf: reduce amout of mutex in Assistant
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
#include <meojson/json.hpp>
|
||||
|
||||
#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<bool(void)> func, bool block,
|
||||
std::string what)
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
AsyncCallId id = 0;
|
||||
AsyncCallId id;
|
||||
{
|
||||
std::unique_lock<std::mutex> 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<std::mutex> 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<std::mutex> 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<AsyncCallItem::ConnectParams>(call_item.params);
|
||||
ret = ctrl_connect(adb_path, address, config);
|
||||
} break;
|
||||
case AsyncCallItem::Type::Click: {
|
||||
what = "Click";
|
||||
const auto& [x, y] = std::get<AsyncCallItem::ClickParams>(call_item.params);
|
||||
ret = ctrl_click(x, y);
|
||||
} break;
|
||||
case AsyncCallItem::Type::Screencap: {
|
||||
what = "Screencap";
|
||||
std::ignore = std::get<AsyncCallItem::ScreencapParams>(call_item.params);
|
||||
ret = ctrl_screencap();
|
||||
} break;
|
||||
default:
|
||||
what = "Unknown";
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
AsyncCallItem old_call_item;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> completed_call_lock(m_completed_call_mutex);
|
||||
m_completed_call = call_item.id;
|
||||
m_completed_call_condvar.notify_all();
|
||||
std::unique_lock<std::mutex> 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::milliseconds>(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 {
|
||||
|
||||
@@ -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<ConnectParams, ClickParams, ScreencapParams>;
|
||||
|
||||
AsyncCallId id;
|
||||
Type type;
|
||||
Parmas params;
|
||||
std::function<bool(void)> 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<bool(void)> 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<AsyncCallId> m_completed_call = 0; // 每个实例有自己独立的执行队列,所以不能静态
|
||||
|
||||
std::thread m_msg_thread;
|
||||
std::thread m_call_thread;
|
||||
|
||||
Reference in New Issue
Block a user