From 7dc0fd348d0336c65bbc670da4fa4d617f587ea2 Mon Sep 17 00:00:00 2001 From: MistEO Date: Tue, 2 May 2023 15:16:07 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E8=B5=84=E6=BA=90=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/MaaCore/Assistant.cpp | 5 +-- src/MaaCore/Config/AbstractConfig.cpp | 18 ++------ src/MaaCore/Config/AbstractConfig.h | 5 --- src/MaaCore/Config/ResourceLoader.cpp | 60 +++++++++++++++++++++++---- src/MaaCore/Config/ResourceLoader.h | 29 +++++++------ 5 files changed, 73 insertions(+), 44 deletions(-) diff --git a/src/MaaCore/Assistant.cpp b/src/MaaCore/Assistant.cpp index 338b3b0523..4f2f617cff 100644 --- a/src/MaaCore/Assistant.cpp +++ b/src/MaaCore/Assistant.cpp @@ -437,10 +437,7 @@ void Assistant::msg_proc() continue; } - // 结构化绑定只能是引用,后续的pop会使引用失效,所以需要重新构造一份,这里采用了move的方式 - auto&& [temp_msg, temp_detail] = m_msg_queue.front(); - AsstMsg msg = temp_msg; - json::value detail = std::move(temp_detail); + auto [msg, detail] = std::move(m_msg_queue.front()); m_msg_queue.pop(); lock.unlock(); diff --git a/src/MaaCore/Config/AbstractConfig.cpp b/src/MaaCore/Config/AbstractConfig.cpp index 146b22d4a7..9193b3be96 100644 --- a/src/MaaCore/Config/AbstractConfig.cpp +++ b/src/MaaCore/Config/AbstractConfig.cpp @@ -7,27 +7,15 @@ bool asst::AbstractConfig::load(const std::filesystem::path& path) { - return _load(path); -} + std::string class_name = utils::demangle(typeid(*this).name()); -void asst::AbstractConfig::async_load(const std::filesystem::path& path) -{ - m_load_future = std::async(std::launch::async, &AbstractConfig::_load, this, path); -} - -bool asst::AbstractConfig::_load(std::filesystem::path path) -{ if (!std::filesystem::exists(path) || !std::filesystem::is_regular_file(path)) { - std::string class_name = utils::demangle(typeid(*this).name()); - Log.error(class_name, "file does not exist", path); + Log.error(class_name, __FUNCTION__, "file does not exist", path); return false; } m_path = path; - std::unique_lock lock(m_load_mutex); - - std::string class_name = utils::demangle(typeid(*this).name()); - LogTraceScope(class_name); + LogTraceScope(class_name + " :: " + __FUNCTION__); Log.info(path); auto ret = json::open(path, true); diff --git a/src/MaaCore/Config/AbstractConfig.h b/src/MaaCore/Config/AbstractConfig.h index b5dacfc954..705365c99b 100644 --- a/src/MaaCore/Config/AbstractConfig.h +++ b/src/MaaCore/Config/AbstractConfig.h @@ -17,15 +17,10 @@ namespace asst public: virtual ~AbstractConfig() override = default; virtual bool load(const std::filesystem::path& path) override; - virtual void async_load(const std::filesystem::path& path); protected: virtual bool parse(const json::value& json) = 0; - bool _load(std::filesystem::path path); - std::filesystem::path m_path; - std::future m_load_future; - std::mutex m_load_mutex; }; } diff --git a/src/MaaCore/Config/ResourceLoader.cpp b/src/MaaCore/Config/ResourceLoader.cpp index 68cdb6841f..d814e3106a 100644 --- a/src/MaaCore/Config/ResourceLoader.cpp +++ b/src/MaaCore/Config/ResourceLoader.cpp @@ -23,6 +23,54 @@ #include "TemplResource.h" #include "Utils/Logger.hpp" +asst::ResourceLoader::ResourceLoader() +{ + m_load_thread = std::thread(&ResourceLoader::load_thread_func, this); +} + +void asst::ResourceLoader::load_thread_func() +{ + while (!m_load_thread_exit) { + std::unique_lock lock(m_load_mutex); + + if (m_load_queue.empty()) { + m_load_cv.wait(lock); + continue; + } + + auto [res_ptr, path] = std::move(m_load_queue.front()); + m_load_queue.pop_front(); + lock.unlock(); + + res_ptr->load(path); + } +} + +void asst::ResourceLoader::add_load_queue(std::shared_ptr res_ptr, const std::filesystem::path& path) +{ + if (!res_ptr || !std::filesystem::exists(path)) { + return; + } + + std::unique_lock lock(m_load_mutex); + m_load_queue.emplace_back(std::move(res_ptr), path); + m_load_cv.notify_all(); +} + +asst::ResourceLoader::~ResourceLoader() +{ + m_load_thread_exit = true; + + { + std::unique_lock lock(m_load_mutex); + m_load_cv.notify_all(); + } + + if (m_load_thread.joinable()) { + m_load_thread.join(); + } +} + bool asst::ResourceLoader::load(const std::filesystem::path& path) { if (!std::filesystem::exists(path)) { @@ -44,14 +92,10 @@ bool asst::ResourceLoader::load(const std::filesystem::path& path) // DEBUG 模式下这里同步加载,并检查返回值的,方便排查问题 #define AsyncLoadConfig(Config, Filename) LoadResourceAndCheckRet(Config, Filename) #else -#define AsyncLoadConfig(Config, Filename) \ - { \ - auto full_path = path / Filename; \ - bool ret = async_load_config(full_path); \ - if (!ret) { \ - Log.error(#Config, " load failed, path:", full_path); \ - return false; \ - } \ +#define AsyncLoadConfig(Config, Filename) \ + { \ + auto res_ptr = std::make_shared(); \ + add_load_queue(res_ptr, path / Filename); \ } #endif // ASST_DEBUG diff --git a/src/MaaCore/Config/ResourceLoader.h b/src/MaaCore/Config/ResourceLoader.h index f4b14e06e1..9e5f4d332a 100644 --- a/src/MaaCore/Config/ResourceLoader.h +++ b/src/MaaCore/Config/ResourceLoader.h @@ -2,7 +2,9 @@ #include "AbstractResource.h" +#include #include +#include #include "AbstractConfigWithTempl.h" #include "TemplResource.h" @@ -13,12 +15,17 @@ namespace asst class ResourceLoader final : public SingletonHolder, public AbstractResource { public: - virtual ~ResourceLoader() override = default; + virtual ~ResourceLoader() override; virtual bool load(const std::filesystem::path& path) override; bool loaded() const noexcept; + public: + ResourceLoader(); + private: + void load_thread_func(); + template requires std::is_base_of_v bool load_resource(const std::filesystem::path& path) @@ -29,17 +36,6 @@ namespace asst return SingletonHolder::get_instance().load(path); } - template - requires std::is_base_of_v - bool async_load_config(const std::filesystem::path& path) - { - if (!std::filesystem::exists(path)) { - return m_loaded; - } - SingletonHolder::get_instance().async_load(path); - return true; - } - template requires std::is_base_of_v bool load_resource_with_templ(const std::filesystem::path& path, const std::filesystem::path& templ_dir) @@ -54,7 +50,16 @@ namespace asst return load_resource(templ_dir); } + void add_load_queue(std::shared_ptr res_ptr, const std::filesystem::path& path); + private: bool m_loaded = false; + + // only for async load + bool m_load_thread_exit = false; + std::deque, std::filesystem::path>> m_load_queue; + std::mutex m_load_mutex; + std::condition_variable m_load_cv; + std::thread m_load_thread; }; } // namespace asst