From b271e4e9be8d9742dba65d08672d44eb0d219501 Mon Sep 17 00:00:00 2001 From: OEOTYAN Date: Mon, 30 Dec 2024 18:50:57 +0800 Subject: [PATCH] refactor: stable id abi, remove deprecated apis --- src-server/ll/core/plugin-abi/ErrorUtils.cpp | 37 -- src-server/ll/core/plugin-abi/Logger.cpp | 166 --------- src-server/ll/core/plugin-abi/Logger.h | 101 ------ src-server/ll/core/plugin-abi/Manifest.h | 7 - src-server/ll/core/plugin-abi/Memory.cpp | 39 --- .../ll/core/plugin-abi/NativePlugin.cpp | 27 -- src-server/ll/core/plugin-abi/NativePlugin.h | 38 --- src-server/ll/core/plugin-abi/OldI18n.cpp | 319 ------------------ src-server/ll/core/plugin-abi/Plugin.cpp | 112 ------ src-server/ll/core/plugin-abi/Plugin.h | 84 ----- .../ll/core/plugin-abi/PluginManager.cpp | 69 ---- src-server/ll/core/plugin-abi/PluginManager.h | 54 --- .../core/plugin-abi/PluginManagerRegistry.cpp | 166 --------- .../core/plugin-abi/PluginManagerRegistry.h | 50 --- .../ll/core/plugin-abi/TIckSyncTaskPool.cpp | 53 --- src-server/ll/core/plugin-abi/ThreadPool.cpp | 80 ----- .../ll/core/plugin-abi/schedule/Task.cpp | 55 --- src-server/ll/core/plugin-abi/schedule/Task.h | 71 ---- src-test/server/EventTest.cpp | 4 +- src/ll/api/command/OverloadData.cpp | 35 +- src/ll/api/command/OverloadData.h | 11 - src/ll/api/data/KeyValueDB.cpp | 11 - src/ll/api/data/KeyValueDB.h | 2 - src/ll/api/event/Cancellable.h | 4 +- src/ll/api/event/Event.cpp | 4 +- src/ll/api/event/Event.h | 7 +- src/ll/api/event/EventBus.cpp | 23 +- src/ll/api/event/EventBus.h | 21 +- src/ll/api/event/EventId.h | 45 ++- src/ll/api/event/MultiListener.h | 2 +- src/ll/api/mod/ModManager.cpp | 9 - src/ll/api/mod/ModManager.h | 2 - src/ll/api/mod/ModManagerRegistry.cpp | 18 - src/ll/api/mod/ModManagerRegistry.h | 5 - src/ll/api/reflection/TypeName.h | 8 +- src/ll/api/service/Service.h | 6 +- src/ll/api/service/ServiceId.h | 67 ++-- src/ll/api/service/ServiceManager.cpp | 42 +-- src/ll/api/service/ServiceManager.h | 4 +- src/ll/api/utils/HashUtils.h | 29 ++ src/ll/core/mod/NativeModManager.cpp | 17 +- 41 files changed, 141 insertions(+), 1763 deletions(-) delete mode 100644 src-server/ll/core/plugin-abi/ErrorUtils.cpp delete mode 100644 src-server/ll/core/plugin-abi/Logger.cpp delete mode 100644 src-server/ll/core/plugin-abi/Logger.h delete mode 100644 src-server/ll/core/plugin-abi/Manifest.h delete mode 100644 src-server/ll/core/plugin-abi/Memory.cpp delete mode 100644 src-server/ll/core/plugin-abi/NativePlugin.cpp delete mode 100644 src-server/ll/core/plugin-abi/NativePlugin.h delete mode 100644 src-server/ll/core/plugin-abi/OldI18n.cpp delete mode 100644 src-server/ll/core/plugin-abi/Plugin.cpp delete mode 100644 src-server/ll/core/plugin-abi/Plugin.h delete mode 100644 src-server/ll/core/plugin-abi/PluginManager.cpp delete mode 100644 src-server/ll/core/plugin-abi/PluginManager.h delete mode 100644 src-server/ll/core/plugin-abi/PluginManagerRegistry.cpp delete mode 100644 src-server/ll/core/plugin-abi/PluginManagerRegistry.h delete mode 100644 src-server/ll/core/plugin-abi/TIckSyncTaskPool.cpp delete mode 100644 src-server/ll/core/plugin-abi/ThreadPool.cpp delete mode 100644 src-server/ll/core/plugin-abi/schedule/Task.cpp delete mode 100644 src-server/ll/core/plugin-abi/schedule/Task.h diff --git a/src-server/ll/core/plugin-abi/ErrorUtils.cpp b/src-server/ll/core/plugin-abi/ErrorUtils.cpp deleted file mode 100644 index 4dd9134df0..0000000000 --- a/src-server/ll/core/plugin-abi/ErrorUtils.cpp +++ /dev/null @@ -1,37 +0,0 @@ - -#include "ll/api/utils/ErrorUtils.h" -#include "ll/api/io/LoggerRegistry.h" -#include "ll/core/plugin-abi/Plugin.h" - -namespace ll::inline utils::error_utils { -LLAPI void printCurrentException(Logger& logger, std::exception_ptr const& e) noexcept { - auto l = io::LoggerRegistry::getInstance().getOrCreate(logger.title); - printCurrentException(*l, io::LogLevel::Error, e); -} -LLAPI void printCurrentException(OutputStream& stream, std::exception_ptr const& e) noexcept { - auto p = io::LoggerRegistry::getInstance().getOrCreate(stream.logger->title); - - io::LogLevel lvl; - - switch (stream.level) { - case 5: - lvl = io::LogLevel::Debug; - break; - case 4: - lvl = io::LogLevel::Info; - break; - case 3: - lvl = io::LogLevel::Warn; - break; - case 2: - lvl = io::LogLevel::Error; - break; - default: - case 1: - lvl = io::LogLevel::Fatal; - break; - } - - printCurrentException(*p, lvl, e); -} -} // namespace ll::inline utils::error_utils diff --git a/src-server/ll/core/plugin-abi/Logger.cpp b/src-server/ll/core/plugin-abi/Logger.cpp deleted file mode 100644 index e74722df46..0000000000 --- a/src-server/ll/core/plugin-abi/Logger.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include "ll/core/plugin-abi/Logger.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fmt/chrono.h" // IWYU pragma: keep -#include "fmt/color.h" -#include "fmt/core.h" - -#include "ll/api/Config.h" -#include "ll/api/io/Logger.h" -#include "ll/api/io/LoggerRegistry.h" -#include "ll/api/utils/ErrorUtils.h" -#include "ll/api/utils/StringUtils.h" -#include "ll/api/utils/SystemUtils.h" -#include "ll/core/Config.h" - -#include "pl/Config.h" - -using namespace ll::string_utils; - -namespace ll { -void OutputStream::print(std::string_view s) const noexcept { - - io::LogLevel l; - - switch (level) { - case 5: - l = io::LogLevel::Debug; - break; - case 4: - l = io::LogLevel::Info; - break; - case 3: - l = io::LogLevel::Warn; - break; - case 2: - l = io::LogLevel::Error; - break; - default: - case 1: - l = io::LogLevel::Fatal; - break; - } - static ConcurrentDenseMap> loggers; - - loggers.lazy_emplace_l( - logger->title, - [&](auto& pair) { pair.second->log(l, s); }, - [&](auto const& ctor) { - auto shared = io::LoggerRegistry::getInstance().getOrCreate(logger->title); - ctor(logger->title, shared); - shared->log(l, s); - } - ); -} -OutputStream::OutputStream( - Logger& logger, - std::string levelPrefix, - int level, - std::array const& style, - std::array const& consoleFormat, - std::array const& fileFormat -) -: logger(&logger), - levelPrefix(std::move(levelPrefix)), - level(level), - style(style), - consoleFormat(consoleFormat), - fileFormat(fileFormat) {} - -Logger::Logger(std::string_view title) -: title(title), - debug(OutputStream{ - *this, - "DEBUG", - 5, - { - fmt::fg(fmt::color::light_blue), - fmt::fg(fmt::color::light_golden_rod_yellow), - fmt::fg(fmt::color::light_golden_rod_yellow), - fmt::fg(fmt::color::light_golden_rod_yellow) | fmt::emphasis::italic, - } -}), - info(OutputStream{ - *this, - "INFO", - 4, - { - fmt::fg(fmt::color::light_blue), - fmt::fg(fmt::color::light_sea_green), - {}, - {}, - } - }), - warn(OutputStream{ - *this, - "WARN", - 3, - { - fmt::fg(fmt::color::light_blue), - fmt::fg(fmt::terminal_color::bright_yellow), - fmt::fg(fmt::terminal_color::bright_yellow), - fmt::fg(fmt::terminal_color::bright_yellow) | fmt::emphasis::bold, - } - }), - error(OutputStream{ - *this, - "ERROR", - 2, - { - fmt::fg(fmt::color::light_blue), - fmt::fg(fmt::terminal_color::bright_red), - fmt::fg(fmt::terminal_color::bright_red), - fmt::fg(fmt::terminal_color::bright_red) | fmt::emphasis::bold, - } - }), - fatal(OutputStream{ - *this, - "FATAL", - 1, - { - fmt::fg(fmt::color::light_blue), - fmt::fg(fmt::color::red), - fmt::fg(fmt::color::red), - fmt::fg(fmt::color::red) | fmt::emphasis::bold, - } - }) {} - -LLNDAPI ll::Logger::Logger(std::string_view title, bool) : Logger(title) {} - -void Logger::resetFile() { - if (ofs) { - auto& value = *ofs; - if (value.is_open()) value.close(); - ofs = std::nullopt; - } -} - -bool Logger::setFile(std::filesystem::path const& logFile, bool appendMode) { - resetFile(); - if (logFile.empty()) { - return true; - } - - std::error_code ec; - std::filesystem::create_directories(logFile.parent_path(), ec); - ofs = std::ofstream(logFile, appendMode ? std::ios::app : std::ios::out); - return ofs->is_open(); -} - -std::lock_guard Logger::lock() { - static std::recursive_mutex mutex; - return std::lock_guard(mutex); -} -} // namespace ll diff --git a/src-server/ll/core/plugin-abi/Logger.h b/src-server/ll/core/plugin-abi/Logger.h deleted file mode 100644 index 02957ce70e..0000000000 --- a/src-server/ll/core/plugin-abi/Logger.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once -/** - * - * @brief Logger System - Log text to console, file and player easily - * - * Create Logger - * @code - * Logger logger("MyMod"); // Create a logger (default: only log to console) - * @endcode - * Use Logger - * @code - * logger.info("Infomation"); // Common - * logger.error("Error! Code:{}", -1); // fmt Format - * @endcode - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fmt/chrono.h" // IWYU pragma: keep -#include "fmt/color.h" -#include "fmt/core.h" -#include "fmt/format.h" -#include "fmt/os.h" // IWYU pragma: keep -#include "fmt/ranges.h" // IWYU pragma: keep -#include "fmt/std.h" // IWYU pragma: keep - -#include "ll/api/base/Concepts.h" // IWYU pragma: keep -#include "ll/api/base/Macro.h" - -namespace ll { -class Logger; -class OutputStream { - friend class Logger; - -private: - LLAPI void print(std::string_view) const noexcept; - -public: - Logger* logger; - std::string levelPrefix; - int level; - std::array style; - std::array consoleFormat; - std::array fileFormat; - std::array playerFormat = {"<{2}|{1}> [{0}] {3}", "{:%T}", "{}", "{}", "{}"}; - std::function playerOutputCallback; - - LLAPI explicit OutputStream( - Logger& logger, - std::string levelPrefix, - int level, - std::array const& style = {{}}, - std::array const& consoleFormat = {"{0} {1} {2} {3}", "{:%T}.{:0>3}", "{}", "[{}]", "{}"}, - std::array const& fileFormat = {"[{0} {1}][{2}] {3}", "{:%F %T}.{:0>3}", "{}", "{}", "{}"} - ); - - template - void operator()(fmt::format_string fmt, Args&&... args) const { - print(fmt::vformat(fmt.get(), fmt::make_format_args(args...))); - } - - template - void operator()(S const& msg) const { - print(msg); - } -}; - -class Logger { -public: - std::string title; - std::optional ofs = std::nullopt; - int consoleLevel = -1; - int fileLevel = -1; - int filler; - - OutputStream debug; - OutputStream info; - OutputStream warn; - OutputStream error; - OutputStream fatal; - - LLNDAPI explicit Logger(std::string_view title = __builtin_FUNCTION()); - - LLNDAPI Logger(std::string_view, bool); - - ~Logger() { resetFile(); } - - LLAPI void resetFile(); - LLAPI bool setFile(std::filesystem::path const& logFile, bool appendMode = true); - - LLAPI static std::lock_guard lock(); -}; -} // namespace ll diff --git a/src-server/ll/core/plugin-abi/Manifest.h b/src-server/ll/core/plugin-abi/Manifest.h deleted file mode 100644 index a702d5f38f..0000000000 --- a/src-server/ll/core/plugin-abi/Manifest.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "ll/api/mod/Manifest.h" - -namespace ll::plugin { -struct Manifest : public mod::Manifest {}; -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/Memory.cpp b/src-server/ll/core/plugin-abi/Memory.cpp deleted file mode 100644 index e737084985..0000000000 --- a/src-server/ll/core/plugin-abi/Memory.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "ll/api/memory/Memory.h" - -#include -#include -#include - -#include "pl/SymbolProvider.h" - -#include "ll/api/io/Logger.h" -#include "ll/api/service/GamingStatus.h" -#include "ll/api/thread/GlobalThreadPauser.h" -#include "ll/api/utils/StringUtils.h" -#include "ll/api/utils/SystemUtils.h" -#include "ll/core/LeviLamina.h" - -#include "mc/deps/core/memory/IMemoryAllocator.h" - -#include "demangler/Demangle.h" - -namespace ll::memory { -LLNDAPI FuncPtr resolveSignature(std::string_view signature, std::span range) { - if (range.empty() || signature.empty()) { - return nullptr; - } - return Signature::parse(signature).view().resolve(range); -} -LLNDAPI FuncPtr resolveSignature(std::string_view signature) { - return resolveSignature(signature, sys_utils::getImageRange()); -} -LLAPI FuncPtr resolveSymbol(std::string_view symbol, bool disableErrorOutput) { - auto sym = SymbolView{symbol}; - auto res = sym.resolve(true); - if (!disableErrorOutput && res == nullptr) { - getLogger().fatal("Couldn't find: {}", sym.toString()); - getLogger().fatal("In module: {}", sys_utils::getCallerModuleFileName()); - } - return res; -} -} // namespace ll::memory diff --git a/src-server/ll/core/plugin-abi/NativePlugin.cpp b/src-server/ll/core/plugin-abi/NativePlugin.cpp deleted file mode 100644 index ed9fc83b60..0000000000 --- a/src-server/ll/core/plugin-abi/NativePlugin.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -#include "ll/api/mod/NativeMod.h" -#include "ll/core/plugin-abi/NativePlugin.h" - -namespace ll::plugin { - -struct NativePlugin::Impl { - Handle handle; -}; - -NativePlugin::NativePlugin(Manifest manifest, Handle handle) -: Plugin(std::move(manifest)), - mImpl(std::make_unique(handle)) {} - -NativePlugin::~NativePlugin() = default; - -void NativePlugin::setHandle(Handle handle) { mImpl->handle = handle; } - -NativePlugin::Handle NativePlugin::getHandle() const { return mImpl->handle; } - -std::shared_ptr NativePlugin::getByHandle(Handle handle) { - return std::reinterpret_pointer_cast(mod::NativeMod::getByHandle(handle)); -} -std::shared_ptr NativePlugin::current(Handle handle) { return getByHandle(handle); } - -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/NativePlugin.h b/src-server/ll/core/plugin-abi/NativePlugin.h deleted file mode 100644 index 4a7b7877be..0000000000 --- a/src-server/ll/core/plugin-abi/NativePlugin.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - -#include "ll/api/base/Macro.h" -#include "ll/api/utils/SystemUtils.h" -#include "ll/core/plugin-abi/Manifest.h" -#include "ll/core/plugin-abi/Plugin.h" - -namespace ll::plugin { - -class NativePluginManager; -[[maybe_unused]] constexpr std::string_view NativePluginManagerName = "native"; - -class NativePlugin : public Plugin { - friend NativePluginManager; - struct Impl; - std::unique_ptr mImpl; - -public: - using Handle = void*; - -protected: - void setHandle(Handle handle); - -public: - NativePlugin(Manifest manifest, Handle handle = nullptr); - ~NativePlugin(); - - LLNDAPI Handle getHandle() const; - - LLNDAPI static std::shared_ptr getByHandle(Handle handle); - - LLNDAPI static std::shared_ptr current(Handle handle = sys_utils::getCurrentModuleHandle()); -}; - -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/OldI18n.cpp b/src-server/ll/core/plugin-abi/OldI18n.cpp deleted file mode 100644 index ffd89003ba..0000000000 --- a/src-server/ll/core/plugin-abi/OldI18n.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include "ll/api/i18n/I18n.h" -#include "ll/api/io/FileUtils.h" -#include "ll/api/utils/StringUtils.h" - -#include "nlohmann/json.hpp" - -namespace fs = std::filesystem; - -using ll::file_utils::u8path; -using ll::string_utils::splitByPattern; - -namespace ll::i18n { -const std::array GENERAL_LANGUAGES = {"en", "zh"}; - - -class I18N { - struct char_pointer_hash { - auto operator()(char const* ptr) const noexcept { return ::std::hash<::std::string_view>{}(ptr); } - }; - using transparent_string_hash = - TransparentOverloaded<::std::hash<::std::string>, ::std::hash<::std::string_view>, char_pointer_hash>; - -public: - using SubLangData = std::unordered_map>; - using LangData = std::unordered_map>; - - enum class Type : schar { - None, - SingleFile, - MultiFile, - Custom, - }; - - LangData mLangData{}; - LangData mDefaultLangData{}; - std::string mDefaultLocaleName; - - virtual ~I18N() = default; - - /** - * @brief Get the translation of the specified key. - * - * @param key The language key - * @param localeName The language code like en_US,zh_CN({} => this->mDefaultLocaleName) - * @return std::string The translation - * @see I18N::mDefaultLocaleName - */ - LLNDAPI std::string_view get(std::string_view key, std::string_view localeName = {}); - - /** - * @brief Get the type of the i18n object. - * - * @return The type of the i18n object - */ - LLNDAPI virtual Type getType() const = 0; -}; - -class SingleFileI18N : public I18N { - -public: - std::filesystem::path mFilePath; - - LLAPI void load(std::filesystem::path const& filePath); - LLAPI void save(); - - SingleFileI18N() = default; - /** - * @brief Construct a SingleFileI18N object. - * - * @param filePath The path to the i18n file(json) - * @param defaultLocaleName The default locale name - * @param defaultLangData The default translation data - */ - explicit SingleFileI18N( - std::filesystem::path const& filePath, - std::string defaultLocaleName = {}, - LangData defaultLangData = {} - ) { - this->mDefaultLangData = std::move(defaultLangData); - this->mDefaultLocaleName = std::move(defaultLocaleName); - load(filePath); - } - /// Copy constructor - SingleFileI18N(SingleFileI18N const& other) = default; - ~SingleFileI18N() override = default; - - LLNDAPI Type getType() const override; -}; - -class MultiFileI18N : public I18N { - -public: - std::filesystem::path mDirPath; - - LLAPI void load(std::filesystem::path const& dirPath); - LLAPI void save(bool nested = false); - - MultiFileI18N() = default; - /** - * @brief Construct a heavy I18N object. - * - * @param dirPath The path to the i18n dir - * @param defaultLocaleName The default locale name - * @param defaultLangData The default translation data - */ - explicit MultiFileI18N( - std::filesystem::path const& dirPath, - std::string defaultLocaleName = {}, - LangData defaultLangData = {} - ) { - this->mDefaultLangData = std::move(defaultLangData); - this->mDefaultLocaleName = std::move(defaultLocaleName); - load(dirPath); - } - /// Copy constructor - MultiFileI18N(MultiFileI18N const& other) = default; - ~MultiFileI18N() override = default; - - LLNDAPI Type getType() const override; -}; - -#pragma region I18N - -bool findTranslation( - I18N::LangData const& langData, - std::string_view key, - std::string_view localeName, - std::string_view localeType, - std::string_view& dest -) { - if (auto lang = langData.find(localeName); lang != langData.end()) { // If there is a translation for the language - auto& translations = lang->second; - if (auto it = translations.find(key); it != translations.end()) { // If there is matched key in the translations - dest = it->second; - return true; - } - } - // Search for the similar language in mLangData - for (auto& [name, translations] : langData) { - if (name.length() < 2) { - continue; - } - if (name.substr(0, 2) == localeType) { - if (auto it = translations.find(key); it != translations.end()) { - dest = it->second; - return true; - } - } - } - return false; -} - -std::string_view I18N::get(std::string_view key, std::string_view localeName) { - if (localeName.empty()) { - if (mDefaultLocaleName.empty()) { - localeName = getDefaultLocaleCode(); - } else { - localeName = mDefaultLocaleName; - } - } - auto localeType = localeName.substr(0, 2); - std::string_view result; - // Try finding the translation in loaded language data - if (findTranslation(mLangData, key, localeName, localeType, result)) { - return result; - } - // If not found, try falling back to the default language data - if (!mDefaultLangData.empty() && findTranslation(mDefaultLangData, key, localeName, localeType, result)) { - return result; - } - // Try finding general languages - for (auto& lang : GENERAL_LANGUAGES) { - if (findTranslation(mLangData, key, lang, lang, result)) { - return result; - } - if (!mDefaultLangData.empty() && findTranslation(mDefaultLangData, key, lang, lang, result)) { - return result; - } - } - // Use the first (dictionary order) language data - if (!mLangData.empty()) { - auto& lang = mLangData.begin()->second; - if (auto it = lang.find(key); it != lang.end()) { - return it->second; - } - } - // Finally, still not found, return the key - return key; -} - -#pragma endregion - -#pragma region SingleFileI18N - -void SingleFileI18N::load(std::filesystem::path const& filePath) { - this->mFilePath = filePath; - if (!fs::exists(filePath)) { - fs::create_directories(filePath.parent_path()); - std::fstream file(filePath, std::ios::out | std::ios::app); - nlohmann::json j = mDefaultLangData; - file << std::setw(4) << j; // Dump default language data - file.close(); - mLangData = mDefaultLangData; - return; // Skip parsing - } - std::fstream file(filePath, std::ios::in); - nlohmann::json j; - file >> j; - mLangData = j.get(); - file.close(); - // Replenish the missing keys - for (auto& [lang, dat] : mLangData) { - if (mDefaultLangData.count(lang)) { - for (auto& [k, v] : mDefaultLangData[lang]) { - if (!dat.count(k)) { - dat[k] = v; - } - } - } - } - save(); -} - -void SingleFileI18N::save() { - std::fstream file; - if (fs::exists(mFilePath)) file.open(mFilePath, std::ios::out | std::ios::ate); - else file.open(mFilePath, std::ios::out | std::ios::app); - nlohmann::json j = mLangData; - file << std::setw(4) << j; - file.close(); -} - -I18N::Type SingleFileI18N::getType() const { return Type::SingleFile; } - -#pragma endregion - -#pragma region MultiFileI18N - -I18N::SubLangData parseNestedData(nlohmann::json const& j, std::string const& prefix = {}) { - I18N::SubLangData data; - if (!j.is_object()) { - return data; // Empty - } - for (auto& it : j.items()) { - auto& val = it.value(); - if (val.is_object()) { - data.merge(parseNestedData(val, prefix + it.key() + '.')); - } else if (val.is_string()) { - data.emplace(prefix + it.key(), val.get()); - } else { - continue; // Ignore - } - } - return data; -} - -void MultiFileI18N::load(std::filesystem::path const& dirPath) { - this->mDirPath = dirPath; - if (!fs::exists(dirPath) || fs::is_empty(dirPath)) { - if (this->mDefaultLangData.empty()) { - return; - } - this->mLangData = this->mDefaultLangData; - save(); - return; - } - for (auto& f : fs::directory_iterator(dirPath)) { - if (!f.is_regular_file() || f.path().extension() != ".json") { - continue; - } - auto langName = f.path().stem().string(); - std::replace(langName.begin(), langName.end(), '_', '-'); - std::fstream file(f.path().wstring(), std::ios::in); - nlohmann::json j; - file >> j; - auto data = parseNestedData(j); - this->mLangData.emplace(langName, data); - } -} - -void MultiFileI18N::save(bool nested) { - if (!fs::exists(mDirPath)) { - fs::create_directories(mDirPath); - for (auto& [lc, lv] : this->mDefaultLangData) { - auto langName = lc; - std::replace(langName.begin(), langName.end(), '-', '_'); - - auto fileName = mDirPath.append(langName + ".json").wstring(); - std::fstream file; - if (fs::exists(fileName)) { - file.open(fileName, std::ios::out | std::ios::ate); - } else { - file.open(fileName, std::ios::out | std::ios::app); - } - if (nested) { - auto out = nlohmann::json::object(); - for (auto& [k, v] : lv) { - auto keys = splitByPattern(k, "."); - auto name = keys.back(); - keys.pop_back(); - nlohmann::json& j = out; - for (auto& key : keys) { - j.emplace(key, nlohmann::json::object()); - j = j.at(key); - } - j.emplace(name, v); - } - file << nlohmann::json(out).dump(4); - } else { - file << nlohmann::json(lv).dump(4); - } - } - } -} - -I18N::Type MultiFileI18N::getType() const { return Type::MultiFile; } - -#pragma endregion -} // namespace ll::i18n diff --git a/src-server/ll/core/plugin-abi/Plugin.cpp b/src-server/ll/core/plugin-abi/Plugin.cpp deleted file mode 100644 index 23adf48cda..0000000000 --- a/src-server/ll/core/plugin-abi/Plugin.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "ll/core/plugin-abi/Plugin.h" - -namespace ll::plugin { -using namespace mod; -std::filesystem::path const& getPluginsRoot() { return getModsRoot(); } - -Plugin::Plugin(Manifest manifest) : Mod(std::move(manifest)) {} -Plugin::~Plugin() = default; - -Manifest const& Plugin::getManifest() const { return (Manifest const&)Mod::getManifest(); } - -std::filesystem::path const& Plugin::getPluginDir() const { return Mod::getModDir(); } - -std::filesystem::path const& Plugin::getDataDir() const { return Mod::getDataDir(); } - -std::filesystem::path const& Plugin::getConfigDir() const { return Mod::getConfigDir(); } - -std::filesystem::path const& Plugin::getLangDir() const { return Mod::getLangDir(); } - -bool Plugin::hasOnLoad() const noexcept { return Mod::hasOnLoad(); } - -bool Plugin::hasOnUnload() const noexcept { return Mod::hasOnUnload(); } - -bool Plugin::hasOnEnable() const noexcept { return Mod::hasOnEnable(); } - -bool Plugin::hasOnDisable() const noexcept { return Mod::hasOnDisable(); } - -Expected<> Plugin::onLoad() noexcept { return Mod::onLoad(); } - -Expected<> Plugin::onUnload() noexcept { return Mod::onUnload(); } - -Expected<> Plugin::onEnable() noexcept { return Mod::onEnable(); } - -Expected<> Plugin::onDisable() noexcept { return Mod::onDisable(); } - -void Plugin::onLoad(CallbackFn func) noexcept { return Mod::onLoad(std::move((Mod::CallbackFn&)func)); } - -void Plugin::onUnload(CallbackFn func) noexcept { return Mod::onUnload(std::move((Mod::CallbackFn&)func)); } - -void Plugin::onEnable(CallbackFn func) noexcept { return Mod::onEnable(std::move((Mod::CallbackFn&)func)); } - -void Plugin::onDisable(CallbackFn func) noexcept { return Mod::onDisable(std::move((Mod::CallbackFn&)func)); } - -void Plugin::setState(State state) const { return Mod::setState((Mod::State)state); } - -Plugin::State Plugin::getState() const { return (State)Mod::getState(); } - -static StringNodeMap oldLoggers; - -Logger& Plugin::getLogger() const { - return oldLoggers.lazy_emplace( - Mod::getName(), - [&](auto const& ctor) { ctor(Mod::getName(), Mod::getName()); } - )->second; -} - -} // namespace ll::plugin - -#pragma comment( \ - linker, \ - "/export:?printScheduleError@detail@schedule@ll@@YAXAEAVTaskBase@task@23@@Z=?printScheduleError@detail@schedule@ll@@YAXAEAVTask@task@23@@Z" \ -) - -#pragma comment( \ - linker, \ - "/export:?getLogger@Mod@mod@ll@@QEBAAEAVLogger@3@XZ=?getLogger@Plugin@plugin@ll@@QEBAAEAVLogger@3@XZ" \ -) - -#pragma comment( \ - linker, \ - "/export:?getOrCreateCommand@CommandRegistrar@command@ll@@QEAAAEAVCommandHandle@23@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0W4CommandPermissionLevel@@UCommandFlag@@V?$weak_ptr@VPlugin@plugin@ll@@@6@@Z=?getOrCreateCommand@CommandRegistrar@command@ll@@QEAAAEAVCommandHandle@23@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0W4CommandPermissionLevel@@UCommandFlag@@V?$weak_ptr@VMod@mod@ll@@@6@@Z" \ -) -#pragma comment( \ - linker, \ - "/export:?setEventEmitter@EventBus@event@ll@@QEAAXV?$function@$$A6A?AV?$unique_ptr@VEmitterBase@event@ll@@U?$default_delete@VEmitterBase@event@ll@@@std@@@std@@AEAVListenerBase@event@ll@@@Z@std@@VEventId@23@V?$weak_ptr@VPlugin@plugin@ll@@@5@@Z=?setEventEmitter@EventBus@event@ll@@QEAAXV?$function@$$A6A?AV?$unique_ptr@VEmitterBase@event@ll@@U?$default_delete@VEmitterBase@event@ll@@@std@@@std@@AEAVListenerBase@event@ll@@@Z@std@@VEventId@23@V?$weak_ptr@VMod@mod@ll@@@5@@Z" \ -) -#pragma comment( \ - linker, \ - "/export:?runtimeOverload@CommandHandle@command@ll@@QEAA?AVRuntimeOverload@23@V?$weak_ptr@VPlugin@plugin@ll@@@std@@@Z=?runtimeOverload@CommandHandle@command@ll@@QEAA?AVRuntimeOverload@23@V?$weak_ptr@VMod@mod@ll@@@std@@@Z" \ -) -#pragma comment( \ - linker, \ - "/export:??0RuntimeOverload@command@ll@@AEAA@AEAVCommandHandle@12@V?$weak_ptr@VPlugin@plugin@ll@@@std@@@Z=??0RuntimeOverload@command@ll@@AEAA@AEAVCommandHandle@12@V?$weak_ptr@VMod@mod@ll@@@std@@@Z" \ -) -#pragma comment( \ - linker, \ - "/export:??0OverloadData@command@ll@@IEAA@AEAVCommandHandle@12@V?$weak_ptr@VPlugin@plugin@ll@@@std@@@Z=??0OverloadData@command@ll@@IEAA@AEAVCommandHandle@12@V?$weak_ptr@VMod@mod@ll@@@std@@@Z" \ -) -#pragma comment( \ - linker, \ - "/export:??0ListenerBase@event@ll@@IEAA@W4EventPriority@12@V?$weak_ptr@VPlugin@plugin@ll@@@std@@@Z=??0ListenerBase@event@ll@@IEAA@W4EventPriority@12@V?$weak_ptr@VMod@mod@ll@@@std@@@Z" \ -) - - -#pragma comment( \ - linker, \ - "/export:?resolveIdentifier@memory@ll@@YAPEAXV?$basic_string_view@DU?$char_traits@D@std@@@std@@_N@Z=?resolveSymbol@memory@ll@@YAPEAXV?$basic_string_view@DU?$char_traits@D@std@@@std@@_N@Z" \ -) - - -#pragma comment( \ - linker, \ - "/export:?getServerStatus@ll@@YA?AW4ServerStatus@1@XZ=?getGamingStatus@ll@@YA?AW4GamingStatus@1@XZ" \ -) -#pragma comment( \ - linker, \ - "/export:?setServerStatus@ll@@YAXW4ServerStatus@1@@Z=?setGamingStatus@ll@@YAXW4GamingStatus@1@@Z" \ -) -#pragma comment( \ - linker, \ - "/export:?self@PlayerEvent@player@event@ll@@QEBAAEAVServerPlayer@@XZ=?self@PlayerEvent@player@event@ll@@QEBAAEAVPlayer@@XZ" \ -) diff --git a/src-server/ll/core/plugin-abi/Plugin.h b/src-server/ll/core/plugin-abi/Plugin.h deleted file mode 100644 index 94645ed49c..0000000000 --- a/src-server/ll/core/plugin-abi/Plugin.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "ll/api/Expected.h" -#include "ll/api/base/Macro.h" -#include "ll/api/io/Logger.h" -#include "ll/api/mod/Mod.h" -#include "ll/core/plugin-abi/Logger.h" -#include "ll/core/plugin-abi/Manifest.h" - -namespace ll::plugin { - -LLAPI std::filesystem::path const& getPluginsRoot(); - -class PluginManager; -class Plugin : public mod::Mod { - -public: - enum class State { - Enabled, - Disabled, - }; - using callback_t = bool(Plugin&); - using CallbackFn = std::function; - - LLNDAPI explicit Plugin(Manifest manifest); - - LLAPI ~Plugin(); - - LLNDAPI State getState() const; - - LLNDAPI Manifest const& getManifest() const; - - LLNDAPI std::filesystem::path const& getPluginDir() const; - - LLNDAPI std::filesystem::path const& getDataDir() const; - - LLNDAPI std::filesystem::path const& getConfigDir() const; - - LLNDAPI std::filesystem::path const& getLangDir() const; - - LLNDAPI Logger& getLogger() const; - - [[nodiscard]] bool isEnabled() const { return getState() == State::Enabled; } - - [[nodiscard]] bool isDisabled() const { return getState() == State::Disabled; } - - // set on load callback and etc... - LLAPI void onLoad(CallbackFn func) noexcept; - - LLAPI void onUnload(CallbackFn func) noexcept; - - LLAPI void onEnable(CallbackFn func) noexcept; - - LLAPI void onDisable(CallbackFn func) noexcept; - -protected: - LLAPI void setState(State state) const; - - // is callback set - LLNDAPI bool hasOnLoad() const noexcept; - - LLNDAPI bool hasOnUnload() const noexcept; - - LLNDAPI bool hasOnEnable() const noexcept; - - LLNDAPI bool hasOnDisable() const noexcept; - - // call on load callback and etc... - LLAPI Expected<> onLoad() noexcept; - - LLAPI Expected<> onUnload() noexcept; - - LLAPI Expected<> onEnable() noexcept; - - LLAPI Expected<> onDisable() noexcept; - -private: - friend PluginManager; -}; -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/PluginManager.cpp b/src-server/ll/core/plugin-abi/PluginManager.cpp deleted file mode 100644 index 9d7945a01f..0000000000 --- a/src-server/ll/core/plugin-abi/PluginManager.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "ll/core/plugin-abi/PluginManager.h" - -namespace ll::plugin { - -struct PluginManager::Impl { - std::string type; - std::recursive_mutex mutex; - StringMap> plugins; - explicit Impl(std::string type) : type(std::move(type)) {} -}; - -PluginManager::PluginManager(std::string_view type) : impl(std::make_unique(std::string{type})) {} - -PluginManager::~PluginManager() = default; - -std::lock_guard PluginManager::lock() { return std::lock_guard(impl->mutex); } - -void PluginManager::addPlugin(std::string_view name, std::shared_ptr const& plugin) { - auto l(lock()); - impl->plugins.try_emplace(std::string{name}, plugin); -} - -void PluginManager::erasePlugin(std::string_view name) { - auto l(lock()); - if (auto i = impl->plugins.find(name); i != impl->plugins.end()) { - impl->plugins.erase(i); - } -} - -Expected<> PluginManager::enable(std::string_view name) { - auto l(lock()); - return getPlugin(name)->onEnable(); -} - -Expected<> PluginManager::disable(std::string_view name) { - auto l(lock()); - return getPlugin(name)->onDisable(); -} - -[[nodiscard]] std::string const& PluginManager::getType() const { return impl->type; } - -[[nodiscard]] bool PluginManager::hasPlugin(std::string_view name) { - auto l(lock()); - return impl->plugins.contains(name); -} - -[[nodiscard]] std::shared_ptr PluginManager::getPlugin(std::string_view name) { - auto l(lock()); - if (auto i = impl->plugins.find(name); i != impl->plugins.end()) { - return i->second; - } - return {}; -} - -[[nodiscard]] size_t PluginManager::getPluginCount() { - auto l(lock()); - return impl->plugins.size(); -} - -void PluginManager::forEachPlugin(std::function const& fn) { - auto l(lock()); - for (auto& [name, plugin] : impl->plugins) { - if (!fn(name, *plugin)) { - return; - } - } -} - -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/PluginManager.h b/src-server/ll/core/plugin-abi/PluginManager.h deleted file mode 100644 index acb05b4a0d..0000000000 --- a/src-server/ll/core/plugin-abi/PluginManager.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "ll/api/Expected.h" -#include "ll/api/base/Macro.h" -#include "ll/core/plugin-abi/Manifest.h" -#include "ll/core/plugin-abi/Plugin.h" - - -namespace ll::plugin { -class PluginManagerRegistry; -class PluginManager { - friend PluginManagerRegistry; - -public: - LLNDAPI std::string const& getType() const; - - LLNDAPI bool hasPlugin(std::string_view name); - - LLNDAPI std::shared_ptr getPlugin(std::string_view name); - - LLNDAPI size_t getPluginCount(); - - LLAPI void forEachPlugin(std::function const& fn); - -protected: - struct Impl; - std::unique_ptr impl; - - LLNDAPI std::lock_guard lock(); - - LLNDAPI explicit PluginManager(std::string_view type); - - LLAPI virtual ~PluginManager(); - - LLAPI void addPlugin(std::string_view name, std::shared_ptr const& plugin); - - LLAPI void erasePlugin(std::string_view name); - - virtual Expected<> load(Manifest manifest) = 0; - - virtual Expected<> unload(std::string_view name) = 0; - - LLAPI virtual Expected<> enable(std::string_view name); - - LLAPI virtual Expected<> disable(std::string_view name); -}; -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/PluginManagerRegistry.cpp b/src-server/ll/core/plugin-abi/PluginManagerRegistry.cpp deleted file mode 100644 index 93ead9c09e..0000000000 --- a/src-server/ll/core/plugin-abi/PluginManagerRegistry.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include "ll/core/plugin-abi/PluginManagerRegistry.h" -#include "ll/api/i18n/I18n.h" - -#include "ll/core/LeviLamina.h" - -#include "ll/api/mod/ModManagerRegistry.h" - -namespace ll::plugin { -struct PluginManagerRegistry::Impl { - std::recursive_mutex mutex; - StringMap> managers; - StringMap loadedPlugins; // k, v: name, type -}; - -PluginManagerRegistry::PluginManagerRegistry() : impl(std::make_unique()) {} - -PluginManagerRegistry::~PluginManagerRegistry() = default; - -PluginManagerRegistry& PluginManagerRegistry::getInstance() { - return (PluginManagerRegistry&)mod::ModManagerRegistry::getInstance(); -} - -Expected<> PluginManagerRegistry::loadPlugin(Manifest manifest) noexcept { - try { - std::lock_guard lock(impl->mutex); - if (hasManager(manifest.type)) { - if (hasPlugin(manifest.name)) { - return makeStringError("Mod {0} already loaded"_tr(manifest.name)); - } - std::string name = manifest.name; - std::string type = manifest.type; - return getManager(type)->load(std::move(manifest)).transform([&, this] { - impl->loadedPlugins.insert_or_assign(std::move(name), std::move(type)); - }); - } else { - return makeStringError("Unrecognized plugin type: {0}"_tr(manifest.type)); - } - } catch (...) { - return makeExceptionError(); - } -} - -Expected<> PluginManagerRegistry::unloadPlugin(std::string_view name) noexcept { - try { - std::lock_guard lock(impl->mutex); - if (!hasPlugin(name)) { - return makeStringError("Mod {0} not found"_tr(name)); - } - return getManagerForPlugin(name)->unload(name).transform([&, this] { - impl->loadedPlugins.erase(std::string{name}); - }); - } catch (...) { - return makeExceptionError(); - } -} - -Expected<> PluginManagerRegistry::enablePlugin(std::string_view name) const noexcept { - try { - std::lock_guard lock(impl->mutex); - if (!hasPlugin(name)) { - return makeStringError("Mod {0} not found"_tr(name)); - } - return getManagerForPlugin(name)->enable(name); - } catch (...) { - return makeExceptionError(); - } -} - -Expected<> PluginManagerRegistry::disablePlugin(std::string_view name) const noexcept { - try { - std::lock_guard lock(impl->mutex); - if (!hasPlugin(name)) { - return makeStringError("Mod {0} not found"_tr(name)); - } - return getManagerForPlugin(name)->disable(name); - } catch (...) { - return makeExceptionError(); - } -} - -bool PluginManagerRegistry::addManager(std::shared_ptr const& manager) { - std::lock_guard lock(impl->mutex); - if (!manager) { - return false; - } - return impl->managers.emplace(manager->getType(), manager).second; -} - -bool PluginManagerRegistry::hasManager(std::string_view type) const { - std::lock_guard lock(impl->mutex); - return impl->managers.contains(type); -} - -std::shared_ptr PluginManagerRegistry::getManager(std::string_view type) const { - std::lock_guard lock(impl->mutex); - if (hasManager(type)) { - return impl->managers.find(type)->second; - } - return {}; -} - -std::shared_ptr PluginManagerRegistry::getManagerForPlugin(std::string_view name) const { - std::lock_guard lock(impl->mutex); - if (hasPlugin(name)) { - return getManager(impl->loadedPlugins.find(name)->second); - } - return {}; -} - -bool PluginManagerRegistry::eraseManager(std::string_view type) { - std::lock_guard lock(impl->mutex); - if (auto i = impl->managers.find(type); i != impl->managers.end()) { - erase_if(impl->loadedPlugins, [type](auto& item) { return item.second == type; }); - impl->managers.erase(i); - return true; - } - return false; -} - -void PluginManagerRegistry::forEachManager(std::function const& fn) const { - std::lock_guard lock(impl->mutex); - for (auto& [type, manager] : impl->managers) { - if (!fn(type, *manager)) { - return; - } - } -} - -void PluginManagerRegistry::forEachPluginWithType( - std::function const& fn -) const { - std::lock_guard lock(impl->mutex); - bool interrupted = false; - forEachManager([&](std::string_view type, PluginManager& manager) { - manager.forEachPlugin([&](std::string_view name, Plugin& plugin) { - if (!fn(type, name, plugin)) { - interrupted = true; - } - return !interrupted; - }); - return !interrupted; - }); -} - -bool PluginManagerRegistry::hasPlugin(std::string_view name) const { - std::lock_guard lock(impl->mutex); - return impl->loadedPlugins.contains(name) && hasManager(impl->loadedPlugins.find(name)->second); -} - -std::string PluginManagerRegistry::getPluginType(std::string_view name) const { - std::lock_guard lock(impl->mutex); - if (hasPlugin(name)) { - return impl->loadedPlugins.find(name)->second; - } - return {}; -} - -std::shared_ptr PluginManagerRegistry::getPlugin(std::string_view name) const { - std::lock_guard lock(impl->mutex); - if (!hasPlugin(name)) { - return {}; - } - return getManagerForPlugin(name)->getPlugin(name); -} - -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/PluginManagerRegistry.h b/src-server/ll/core/plugin-abi/PluginManagerRegistry.h deleted file mode 100644 index 04e4613eb6..0000000000 --- a/src-server/ll/core/plugin-abi/PluginManagerRegistry.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "ll/api/Expected.h" -#include "ll/api/base/Macro.h" -#include "ll/api/data/DependencyGraph.h" -#include "ll/core/plugin-abi/PluginManager.h" - -namespace ll::plugin { -class PluginRegistrar; -class PluginManagerRegistry { - friend PluginRegistrar; - struct Impl; - std::unique_ptr impl; - - PluginManagerRegistry(); - ~PluginManagerRegistry(); - - Expected<> loadPlugin(Manifest manifest) noexcept; - - Expected<> unloadPlugin(std::string_view name) noexcept; - - Expected<> enablePlugin(std::string_view name) const noexcept; - - Expected<> disablePlugin(std::string_view name) const noexcept; - -public: - LLNDAPI static PluginManagerRegistry& getInstance(); - - LLNDAPI bool addManager(std::shared_ptr const& manager); - - LLNDAPI bool eraseManager(std::string_view type); - - LLNDAPI bool hasManager(std::string_view type) const; - - LLNDAPI std::shared_ptr getManager(std::string_view type) const; - - LLNDAPI std::shared_ptr getManagerForPlugin(std::string_view name) const; - - LLAPI void forEachManager(std::function const& fn) const; - - LLAPI void - forEachPluginWithType(std::function const& fn) const; - - LLNDAPI bool hasPlugin(std::string_view name) const; - - LLNDAPI std::string getPluginType(std::string_view name) const; - - LLNDAPI std::shared_ptr getPlugin(std::string_view name) const; -}; -} // namespace ll::plugin diff --git a/src-server/ll/core/plugin-abi/TIckSyncTaskPool.cpp b/src-server/ll/core/plugin-abi/TIckSyncTaskPool.cpp deleted file mode 100644 index a54243232e..0000000000 --- a/src-server/ll/core/plugin-abi/TIckSyncTaskPool.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include - -#include "ll/api/event/EventBus.h" -#include "ll/api/event/world/LevelTickEvent.h" -#include "ll/api/utils/ErrorUtils.h" -#include "ll/core/LeviLamina.h" - -#include "ll/api/base/Containers.h" - -namespace ll::thread { -class TickSyncTaskPool { - struct Worker; - struct Impl; - std::unique_ptr impl; - - LLAPI void addTaskImpl(std::function f); - -public: - LLAPI TickSyncTaskPool(); - LLAPI ~TickSyncTaskPool(); -}; -} // namespace ll::thread - - -namespace ll::thread { - -static ConcurrentQueue> works; - -struct TickSyncTaskPool::Impl {}; - -TickSyncTaskPool::TickSyncTaskPool() : impl(std::make_unique()) { - static auto worker = event::EventBus::getInstance().emplaceListener( - [](auto&) { - std::function f; - while (works.try_dequeue(f)) { - try { - f(); - } catch (...) { - getLogger().error("Error in TickSyncTaskPool:"); - error_utils::printCurrentException(getLogger()); - } - } - }, - event::EventPriority::Low - ); -} -TickSyncTaskPool::~TickSyncTaskPool() {} - -void TickSyncTaskPool::addTaskImpl(std::function f) { works.enqueue(std::move(f)); } - -} // namespace ll::thread diff --git a/src-server/ll/core/plugin-abi/ThreadPool.cpp b/src-server/ll/core/plugin-abi/ThreadPool.cpp deleted file mode 100644 index 9b6651a268..0000000000 --- a/src-server/ll/core/plugin-abi/ThreadPool.cpp +++ /dev/null @@ -1,80 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include - -#include "ll/api/utils/ErrorUtils.h" - -namespace ll::thread { -class ThreadPool { - struct Impl; - std::unique_ptr impl; - - LLAPI void addTaskImpl(std::function); - -public: - LLAPI explicit ThreadPool(size_t nThreads = 1); - LLAPI ~ThreadPool(); - - LLAPI void resize(size_t nThreads = 1); - LLAPI void destroy(); -}; -} // namespace ll::thread - -namespace ll::thread { - -struct ThreadPool::Impl { - std::vector workers; - std::queue> tasks; - std::mutex mutex; - std::condition_variable condition; - bool stop{false}; - Impl(size_t nThreads) { - for (size_t i = 0; i < nThreads; ++i) { - workers.emplace_back([this] { - ll::error_utils::initExceptionTranslator(); - for (;;) { - std::function task; - { - std::unique_lock lock{mutex}; - condition.wait(lock, [this] { return stop || !tasks.empty(); }); - if (stop && tasks.empty()) return; - task = std::move(tasks.front()); - tasks.pop(); - } - task(); - } - }); - } - } - ~Impl() { - { - std::lock_guard lock{mutex}; - stop = true; - } - condition.notify_all(); - for (auto& worker : workers) { - if (worker.joinable()) worker.join(); - } - } -}; - -ThreadPool::ThreadPool(size_t nThreads) : impl(std::make_unique(nThreads)) {} - -void ThreadPool::resize(size_t nThreads) { impl = std::make_unique(nThreads); } - -void ThreadPool::destroy() { impl.reset(); } - -ThreadPool::~ThreadPool() {} -void ThreadPool::addTaskImpl(std::function task) { - { - std::lock_guard lock{impl->mutex}; - impl->tasks.emplace(std::move(task)); - } - impl->condition.notify_one(); -} -} // namespace ll::thread diff --git a/src-server/ll/core/plugin-abi/schedule/Task.cpp b/src-server/ll/core/plugin-abi/schedule/Task.cpp deleted file mode 100644 index a855678679..0000000000 --- a/src-server/ll/core/plugin-abi/schedule/Task.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "ll/core/plugin-abi/schedule/Task.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ll/api/io/Logger.h" -#include "ll/api/utils/ErrorUtils.h" -#include "ll/core/LeviLamina.h" - -namespace ll::schedule::detail { -void printScheduleError(Task& task) noexcept { - try { - getLogger().error( - "Error in schedule task[{}] of {}:", - task.getId(), - task.modPtr.expired() ? "unknown mod" : task.modPtr.lock()->getName() - ); - } catch (...) {} - error_utils::printCurrentException(getLogger()); -} -uint64 nextTaskId() noexcept { - static std::atomic_uint64_t id{0}; - return id++; -} -static std::optional tryParseTime(std::string_view expression, std::string_view format) { - std::tm tm{}; - auto time_now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - localtime_s(&tm, &time_now); - if (std::ispanstream{expression} >> std::get_time(&tm, format.data())) { - return std::mktime(&tm); - } - return std::nullopt; -} -std::chrono::system_clock::time_point parseTime(std::string_view expression) { - - if (auto res = tryParseTime(expression, "%H:%M:%S"); res) { - auto time = std::chrono::system_clock::from_time_t(*res); - if (std::chrono::system_clock::now() > time) { - time += std::chrono::hours(24); - } - return time; - } - return std::chrono::system_clock::from_time_t( - tryParseTime(expression, "%Y-%m-%d %H:%M:%S") - .value_or(tryParseTime(expression, "%Y/%m/%d %H:%M:%S").value_or(0)) - ); -} -} // namespace ll::schedule::detail diff --git a/src-server/ll/core/plugin-abi/schedule/Task.h b/src-server/ll/core/plugin-abi/schedule/Task.h deleted file mode 100644 index ae75a9ea98..0000000000 --- a/src-server/ll/core/plugin-abi/schedule/Task.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ll/api/base/Concepts.h" -#include "ll/api/base/Macro.h" -#include "ll/api/base/StdInt.h" -#include "ll/api/mod/Mod.h" -#include "ll/api/mod/NativeMod.h" - -namespace ll::schedule { -inline namespace task { -class Task; -} -namespace detail { -LLAPI void printScheduleError(Task&) noexcept; -LLAPI uint64 nextTaskId() noexcept; -LLNDAPI std::chrono::system_clock::time_point parseTime(std::string_view); -} // namespace detail -} // namespace ll::schedule - -namespace ll::schedule::inline task { -class Task { -public: - using Id = uint64; - -private: - Id id; - std::function fn; - bool isNextAfterCall; - bool cancelled{false}; - -public: - std::weak_ptr modPtr; - - Task(std::function fn, bool isNextAfterCall, std::weak_ptr mod = mod::NativeMod::current()) - : id(detail::nextTaskId()), - fn(std::move(fn)), - isNextAfterCall(isNextAfterCall), - modPtr(std::move(mod)) {} - - void call() noexcept { - try { - fn(); - } catch (...) { - detail::printScheduleError(*this); - } - } - - [[nodiscard]] constexpr bool nextAfterCall() noexcept { return isNextAfterCall; } - - [[nodiscard]] constexpr bool isCancelled() noexcept { return cancelled; } - - constexpr void setCancelled(bool cancel) noexcept { cancelled = cancel; } - - constexpr void cancel() noexcept { setCancelled(true); } - - [[nodiscard]] constexpr Id getId() const noexcept { return id; } - - virtual ~Task() = default; - - virtual std::optional getNextTime() = 0; -}; -} // namespace ll::schedule::inline task diff --git a/src-test/server/EventTest.cpp b/src-test/server/EventTest.cpp index eea383069b..ee8b0d2021 100644 --- a/src-test/server/EventTest.cpp +++ b/src-test/server/EventTest.cpp @@ -54,9 +54,9 @@ class TestEventB : public ll::event::Event { class TestEvent1 final : public TestEventB { public: - static constexpr ll::event::EventId CustomEventId{"My custom Id"}; + static constexpr ll::event::EventIdView CustomEventId{"My custom Id"}; - ll::event::EventId getId() const override { return CustomEventId; } + ll::event::EventIdView getId() const override { return CustomEventId; } TestEvent1() { some = "TestEvent1 haha"; } }; diff --git a/src/ll/api/command/OverloadData.cpp b/src/ll/api/command/OverloadData.cpp index 3069ea2ee5..7515df99dc 100644 --- a/src/ll/api/command/OverloadData.cpp +++ b/src/ll/api/command/OverloadData.cpp @@ -51,37 +51,6 @@ std::lock_guard OverloadData::lock() { return std::lock_gu CommandParameterData& OverloadData::back() { return impl->params.back(); } -CommandParameterData& OverloadData::addParamImpl( - Bedrock::typeid_t id, - CommandRegistry::ParseFunction parser, - std::string_view name, - CommandParameterDataType type, - char const* enumNameOrPostfix, - int offset, - int flagOffset, - bool optional -) { - // TODO: remove in release - auto& param = addParamImpl( - id, - parser, - name, - type, - enumNameOrPostfix ? enumNameOrPostfix : "", - {}, - offset, - flagOffset, - optional, - type == CommandParameterDataType::Enum ? CommandParameterOption::EnumAutocompleteExpansion - : CommandParameterOption::None - ); - if (id == Bedrock::type_id() - || id == Bedrock::type_id()) { - param.addOptions(CommandParameterOption::HasSemanticConstraint); - } - return param; -} - CommandParameterData& OverloadData::addParamImpl( Bedrock::typeid_t id, CommandRegistry::ParseFunction parser, @@ -116,9 +85,11 @@ CommandParameterData& OverloadData::addTextImpl(std::string_view text, int offse text, CommandParameterDataType::Enum, impl->handle.addText(text), + {}, offset, -1, - false + false, + CommandParameterOption::EnumAutocompleteExpansion ); } void OverloadData::setFactory(std::function()>&& fn) { diff --git a/src/ll/api/command/OverloadData.h b/src/ll/api/command/OverloadData.h index ed22e8d414..5e01fedb9b 100644 --- a/src/ll/api/command/OverloadData.h +++ b/src/ll/api/command/OverloadData.h @@ -39,17 +39,6 @@ class OverloadData { LLNDAPI CommandParameterData& back(); - LLAPI CommandParameterData& addParamImpl( - Bedrock::typeid_t id, - CommandRegistry::ParseFunction parser, - std::string_view name, - CommandParameterDataType type, - char const* enumNameOrPostfix, - int offset, - int flagOffset, - bool optional - ); - LLAPI CommandParameterData& addParamImpl( Bedrock::typeid_t id, CommandRegistry::ParseFunction parser, diff --git a/src/ll/api/data/KeyValueDB.cpp b/src/ll/api/data/KeyValueDB.cpp index 57984ec0f3..f8fa00c568 100644 --- a/src/ll/api/data/KeyValueDB.cpp +++ b/src/ll/api/data/KeyValueDB.cpp @@ -103,17 +103,6 @@ bool KeyValueDB::del(std::string_view key) { return impl->db->Delete(impl->writeOptions, leveldb::Slice(key.data(), key.size())).ok(); } -void KeyValueDB::iter(std::function const& fn) const { - std::unique_ptr it(impl->db->NewIterator(impl->readOptions)); - for (it->SeekToFirst(); it->Valid(); it->Next()) { - auto k = it->key(); - auto v = it->value(); - if (!fn({k.data(), k.size()}, {v.data(), v.size()})) { - break; - } - } -} - coro::Generator> KeyValueDB::iter() const { std::unique_ptr it(impl->db->NewIterator(impl->readOptions)); for (it->SeekToFirst(); it->Valid(); it->Next()) { diff --git a/src/ll/api/data/KeyValueDB.h b/src/ll/api/data/KeyValueDB.h index 3a5e897ada..906ecc1a1d 100644 --- a/src/ll/api/data/KeyValueDB.h +++ b/src/ll/api/data/KeyValueDB.h @@ -48,8 +48,6 @@ class KeyValueDB { LLAPI bool del(std::string_view key); - [[deprecated]] LLAPI void iter(std::function const& fn) const; - LLNDAPI coro::Generator> iter() const; }; diff --git a/src/ll/api/event/Cancellable.h b/src/ll/api/event/Cancellable.h index b9f29701f4..df78c1278f 100644 --- a/src/ll/api/event/Cancellable.h +++ b/src/ll/api/event/Cancellable.h @@ -4,11 +4,13 @@ #include "ll/api/event/Event.h" namespace ll::event { -template T> +template class Cancellable : public T { protected: using T::T; + static_assert(std::derived_from); + static_assert( !traits::is_derived_from_specialization_of_v, "can't be derived from Cancellable twice" diff --git a/src/ll/api/event/Event.cpp b/src/ll/api/event/Event.cpp index e1c3e0bce5..80dce0d523 100644 --- a/src/ll/api/event/Event.cpp +++ b/src/ll/api/event/Event.cpp @@ -11,7 +11,9 @@ void Event::serializeWithCancel(CompoundTag& nbt) const { nbt["cancelled"] = mCa void Event::deserialize(CompoundTag const&) {} -EventId Event::getId() const { return EventId{reflection::removeTypePrefix(reflection::getDynamicRawName(*this))}; } +EventId Event::getId() const { + return EventId{reflection::removeTypePrefix(reflection::getDynamicRawName(*this))}; +} void Event::deserializeWithCancel(CompoundTag const& nbt) { mCancelled = nbt["cancelled"]; } diff --git a/src/ll/api/event/Event.h b/src/ll/api/event/Event.h index 238132b6b0..e81b2fed0d 100644 --- a/src/ll/api/event/Event.h +++ b/src/ll/api/event/Event.h @@ -8,13 +8,12 @@ class CompoundTag; namespace ll::event { -class Event; -template T> +template class Cancellable; class Event { private: - template T> + template friend class ::ll::event::Cancellable; bool mCancelled{false}; @@ -33,6 +32,6 @@ class Event { LLAPI virtual EventId getId() const; - static constexpr EventId CustomEventId{EmptyEventId}; + static constexpr EventIdView CustomEventId{EmptyEventId}; }; } // namespace ll::event diff --git a/src/ll/api/event/EventBus.cpp b/src/ll/api/event/EventBus.cpp index 7f3c4e7138..7ddf88ade2 100644 --- a/src/ll/api/event/EventBus.cpp +++ b/src/ll/api/event/EventBus.cpp @@ -124,7 +124,7 @@ class EventBus::EventBusImpl { DenseMap modInfos; DenseMap listenerInfos; - bool removeListenerImpl(ListenerPtr const& listener, EventId eventId) { + bool removeListenerImpl(ListenerPtr const& listener, EventIdView const& eventId) { bool result{false}; events.modify_if(eventId, [&](auto& pair) { if (pair.second.getStream() @@ -154,14 +154,7 @@ EventBus& EventBus::getInstance() { static EventBus instance; return instance; } -void EventBus::setEventEmitter( - std::function(ListenerBase&)> fn, - EventId eventId, - std::weak_ptr mod -) { - setEventEmitter([fn = std::move(fn)]() { return fn(*(ListenerBase*)(nullptr)); }, eventId, std::move(mod)); -} -bool EventBus::setEventEmitter(FactoryFn fn, EventId eventId, std::weak_ptr weakMod) { +bool EventBus::setEventEmitter(FactoryFn fn, EventIdView const& eventId, std::weak_ptr weakMod) { if (auto mod = weakMod.lock(); mod) { std::lock_guard lock(impl->infoMutex); return impl->events.lazy_emplace_l( @@ -175,21 +168,21 @@ bool EventBus::setEventEmitter(FactoryFn fn, EventId eventId, std::weak_ptr stream; impl->events.if_contains(eventId, [&](auto& pair) { stream = pair.second.getSharedStream(); }); if (stream) { stream->publish(event); } } -void EventBus::publish(std::string_view modName, Event& event, EventId eventId) { +void EventBus::publish(std::string_view modName, Event& event, EventIdView const& eventId) { std::shared_ptr stream; impl->events.if_contains(eventId, [&](auto& pair) { stream = pair.second.getSharedStream(); }); if (stream) { stream->publish(modName, event); } } -size_t EventBus::getListenerCount(EventId eventId) { +size_t EventBus::getListenerCount(EventIdView const& eventId) { if (eventId == EmptyEventId) { return impl->listenerInfos.size(); } @@ -202,7 +195,7 @@ size_t EventBus::getListenerCount(EventId eventId) { }); return result; } -bool EventBus::addListener(ListenerPtr const& listener, EventId eventId) { +bool EventBus::addListener(ListenerPtr const& listener, EventIdView const& eventId) { if (!listener || eventId == EmptyEventId) { return false; } @@ -225,7 +218,7 @@ bool EventBus::addListener(ListenerPtr const& listener, EventId eventId) { } return result; } -bool EventBus::removeListener(ListenerPtr const& listener, EventId eventId) { +bool EventBus::removeListener(ListenerPtr const& listener, EventIdView const& eventId) { if (!listener) { return false; } @@ -261,7 +254,7 @@ ListenerPtr EventBus::getListener(ListenerId id) const { impl->listenerInfos.if_contains(id, [&](auto& pair) { result = pair.second.weak.lock(); }); return result; } -bool EventBus::hasListener(ListenerId id, EventId eventId) const { +bool EventBus::hasListener(ListenerId id, EventIdView const& eventId) const { std::lock_guard lock(impl->infoMutex); if (!impl->listenerInfos.contains(id)) { return false; diff --git a/src/ll/api/event/EventBus.h b/src/ll/api/event/EventBus.h index 687f32f55d..3b4f19019e 100644 --- a/src/ll/api/event/EventBus.h +++ b/src/ll/api/event/EventBus.h @@ -35,23 +35,18 @@ class EventBus { LLNDAPI static EventBus& getInstance(); - LLAPI void publish(Event&, EventId); + LLAPI void publish(Event&, EventIdView const&); - LLAPI void publish(std::string_view modName, Event&, EventId); + LLAPI void publish(std::string_view modName, Event&, EventIdView const&); - LLAPI bool setEventEmitter(FactoryFn fn, EventId eventId, std::weak_ptr mod = mod::NativeMod::current()); + LLAPI bool + setEventEmitter(FactoryFn fn, EventIdView const& eventId, std::weak_ptr mod = mod::NativeMod::current()); template T> bool setEventEmitter(FactoryFn fn, std::weak_ptr mod = mod::NativeMod::current()) { return setEventEmitter(std::move(fn), getEventId, std::move(mod)); } - [[deprecated]] LLAPI void setEventEmitter( - std::function(ListenerBase&)> fn, - EventId eventId, - std::weak_ptr mod = mod::NativeMod::current() - ); - template requires(std::derived_from, Event>) void publish(T&& event) { @@ -66,7 +61,7 @@ class EventBus { publish(modName, event, getEventId); } - LLNDAPI size_t getListenerCount(EventId); + LLNDAPI size_t getListenerCount(EventIdView const&); template T> [[nodiscard]] size_t getListenerCount() { @@ -74,7 +69,7 @@ class EventBus { return getListenerCount(getEventId); } - LLAPI bool addListener(ListenerPtr const&, EventId); + LLAPI bool addListener(ListenerPtr const&, EventIdView const&); template class L, class... LT> requires((std::derived_from || ...) && std::derived_from, ListenerBase>) @@ -96,7 +91,7 @@ class EventBus { return res; } - LLAPI bool removeListener(ListenerPtr const&, EventId); + LLAPI bool removeListener(ListenerPtr const&, EventIdView const&); bool removeListener(ListenerPtr const& listener) { return removeListener(listener, EmptyEventId); } template T> @@ -130,7 +125,7 @@ class EventBus { return false; } - LLNDAPI bool hasListener(ListenerId, EventId) const; + LLNDAPI bool hasListener(ListenerId, EventIdView const&) const; [[nodiscard]] bool hasListener(ListenerId id) const { return hasListener(id, EmptyEventId); } diff --git a/src/ll/api/event/EventId.h b/src/ll/api/event/EventId.h index 264a145727..9d39d63dae 100644 --- a/src/ll/api/event/EventId.h +++ b/src/ll/api/event/EventId.h @@ -4,44 +4,37 @@ #include "ll/api/utils/HashUtils.h" namespace ll::event { -class EventId { +class EventIdView; +class EventId : public hash_utils::HashedIdBase { public: - std::string_view const name; - size_t const hash; + std::string name; - [[nodiscard]] constexpr explicit EventId(std::string_view name) noexcept - : name(name), - hash(ll::hash_utils::doHash(name)) {} - - [[nodiscard]] constexpr bool operator==(EventId other) const noexcept { - return hash == other.hash && name == other.name; - } + [[nodiscard]] constexpr explicit EventId(std::string_view id) noexcept + : HashedIdBase(hash_utils::doHash(id)), + name(id) {} + [[nodiscard]] constexpr EventId(EventIdView const& id) noexcept; +}; +class EventIdView : public hash_utils::HashedIdBase { +public: + std::string_view name; - [[nodiscard]] constexpr std::strong_ordering operator<=>(EventId other) const noexcept { - if (hash != other.hash) { - return hash <=> other.hash; - } - return name <=> other.name; - } + [[nodiscard]] constexpr explicit EventIdView(std::string_view id) noexcept + : HashedIdBase(hash_utils::doHash(id)), + name(id) {} + [[nodiscard]] constexpr EventIdView(EventId const& id) noexcept : HashedIdBase(id.hash), name(id.name) {} }; +[[nodiscard]] constexpr EventId::EventId(EventIdView const& id) noexcept : HashedIdBase(id.hash), name(id.name) {} -static constexpr inline EventId EmptyEventId{{}}; +static constexpr inline EventIdView EmptyEventId{{}}; template -constexpr EventId getEventId = []() -> EventId { +constexpr EventIdView getEventId = []() -> EventIdView { using self = std::remove_cvref_t; if constexpr (self::CustomEventId != EmptyEventId) { return self::CustomEventId; } else { static_assert(std::is_final_v, "Only final classes can use getEventId"); - return EventId{ll::reflection::type_unprefix_name_v}; + return EventIdView{ll::reflection::type_unprefix_name_v}; } }(); } // namespace ll::event - -namespace std { -template <> -struct hash { - size_t operator()(ll::event::EventId const& id) const noexcept { return id.hash; } -}; -} // namespace std diff --git a/src/ll/api/event/MultiListener.h b/src/ll/api/event/MultiListener.h index f58bc98d15..6d56078da7 100644 --- a/src/ll/api/event/MultiListener.h +++ b/src/ll/api/event/MultiListener.h @@ -37,6 +37,6 @@ class MultiListener : public ListenerBase { } private: - SmallDenseMap callback; + SmallDenseMap callback; }; } // namespace ll::event diff --git a/src/ll/api/mod/ModManager.cpp b/src/ll/api/mod/ModManager.cpp index 76afb879b3..d8ea5c649c 100644 --- a/src/ll/api/mod/ModManager.cpp +++ b/src/ll/api/mod/ModManager.cpp @@ -57,15 +57,6 @@ Expected<> ModManager::disable(std::string_view name) { return impl->mods.size(); } -void ModManager::forEachMod(std::function const& fn) { - auto l(lock()); - for (auto& [name, mod] : impl->mods) { - if (!fn(name, *mod)) { - return; - } - } -} - coro::Generator ModManager::mods() const { auto l(lock()); for (auto& p : impl->mods) { diff --git a/src/ll/api/mod/ModManager.h b/src/ll/api/mod/ModManager.h index 649e7ebba7..b5bf9b9a64 100644 --- a/src/ll/api/mod/ModManager.h +++ b/src/ll/api/mod/ModManager.h @@ -30,8 +30,6 @@ class ModManager { LLNDAPI size_t getModCount() const; - [[deprecated]] LLAPI void forEachMod(std::function const& fn); - LLNDAPI coro::Generator mods() const; protected: diff --git a/src/ll/api/mod/ModManagerRegistry.cpp b/src/ll/api/mod/ModManagerRegistry.cpp index 0e02f56072..1ea9854cbf 100644 --- a/src/ll/api/mod/ModManagerRegistry.cpp +++ b/src/ll/api/mod/ModManagerRegistry.cpp @@ -143,24 +143,6 @@ coro::Generator ModManagerRegistry::mods() const { } } -void ModManagerRegistry::forEachManager(std::function const& fn) const { - for (auto& manager : managers()) { - if (!fn(manager.getType(), manager)) { - return; - } - } -} - -void ModManagerRegistry::forEachModWithType( - std::function const& fn -) const { - for (auto& mod : mods()) { - if (!fn(mod.getType(), mod.getName(), mod)) { - return; - } - } -} - bool ModManagerRegistry::hasMod(std::string_view name) const { std::lock_guard lock(impl->modMtx); return impl->loadedMods.contains(name) && hasManager(impl->loadedMods.find(name)->second); diff --git a/src/ll/api/mod/ModManagerRegistry.h b/src/ll/api/mod/ModManagerRegistry.h index 4c2cf5526a..68645292b0 100644 --- a/src/ll/api/mod/ModManagerRegistry.h +++ b/src/ll/api/mod/ModManagerRegistry.h @@ -48,11 +48,6 @@ class ModManagerRegistry { LLNDAPI std::shared_ptr getManagerForMod(std::string_view name) const; - [[deprecated]] LLAPI void forEachManager(std::function const& fn) const; - - [[deprecated]] LLAPI void - forEachModWithType(std::function const& fn) const; - LLNDAPI coro::Generator managers() const; LLNDAPI coro::Generator mods() const; diff --git a/src/ll/api/reflection/TypeName.h b/src/ll/api/reflection/TypeName.h index d3c8756626..9bccfb0571 100644 --- a/src/ll/api/reflection/TypeName.h +++ b/src/ll/api/reflection/TypeName.h @@ -44,16 +44,16 @@ consteval std::string_view getRawName() noexcept { constexpr std::string_view removeTypePrefix(std::string_view s) noexcept { if (s.starts_with("enum ")) { - s.remove_prefix(sizeof("enum ") - 1); + s.remove_prefix(sizeof("enum")); } if (s.starts_with("class ")) { - s.remove_prefix(sizeof("class ") - 1); + s.remove_prefix(sizeof("class")); } if (s.starts_with("union ")) { - s.remove_prefix(sizeof("union ") - 1); + s.remove_prefix(sizeof("union")); } if (s.starts_with("struct ")) { - s.remove_prefix(sizeof("struct ") - 1); + s.remove_prefix(sizeof("struct")); } return s; } diff --git a/src/ll/api/service/Service.h b/src/ll/api/service/Service.h index d91afaaee4..6e1141712f 100644 --- a/src/ll/api/service/Service.h +++ b/src/ll/api/service/Service.h @@ -13,7 +13,7 @@ class Service : public std::enable_shared_from_this { // this is called when the service is removed from the service manager virtual void invalidate() = 0; - static constexpr ServiceId ServiceId{EmptyServiceId}; + static constexpr ServiceIdView ServiceId{EmptyServiceId}; Service() = default; Service(Service const&) = delete; @@ -25,7 +25,7 @@ class Service : public std::enable_shared_from_this { template concept IsService = std::is_base_of_v && requires { T::ServiceId; - requires std::same_as, ServiceId>; + requires(std::same_as, ServiceId> || std::same_as, ServiceIdView>); }; template @@ -33,7 +33,7 @@ class ServiceImpl : public Service { public: [[nodiscard]] class ServiceId getServiceId() const noexcept override { return T::ServiceId; } - static constexpr class ServiceId ServiceId { + static constexpr class ServiceIdView ServiceId { auto_name_t{}, version }; }; diff --git a/src/ll/api/service/ServiceId.h b/src/ll/api/service/ServiceId.h index f3e5973f82..3841fae8f7 100644 --- a/src/ll/api/service/ServiceId.h +++ b/src/ll/api/service/ServiceId.h @@ -8,42 +8,46 @@ namespace ll::service { template struct auto_name_t {}; -class ServiceId { +class ServiceIdView; +class ServiceId : public hash_utils::HashedIdBase { public: - std::string_view name; - size_t version{}; - size_t hash{}; - - [[nodiscard]] constexpr ServiceId(std::string_view name, size_t version) noexcept - : name(name), - version(version), - hash(ll::hash_utils::doHash(name)) { - ll::hash_utils::hashCombine(version, hash); - } + size_t version; + std::string name; - template - [[nodiscard]] constexpr ServiceId(auto_name_t, size_t version) noexcept - : ServiceId{ll::reflection::type_raw_name_v, version} {} + [[nodiscard]] constexpr explicit ServiceId(std::string_view id, size_t ver) noexcept + : HashedIdBase(hash_utils::hashCombineTo(ver, hash_utils::doHash(id))), + name(id), + version(ver) {} - [[nodiscard]] constexpr bool operator==(ServiceId const& other) const noexcept { - return hash == other.hash && version == other.version && name == other.name; - } + [[nodiscard]] constexpr ServiceId(ServiceIdView const& id) noexcept; +}; +class ServiceIdView : public hash_utils::HashedIdBase { +public: + size_t version; + std::string_view name; - [[nodiscard]] constexpr std::strong_ordering operator<=>(ServiceId const& other) const noexcept { - if (hash != other.hash) { - return hash <=> other.hash; - } - if (version != other.version) { - return version <=> other.version; - } - return name <=> other.name; - } + [[nodiscard]] constexpr explicit ServiceIdView(std::string_view id, size_t ver) noexcept + : HashedIdBase(hash_utils::hashCombineTo(ver, hash_utils::doHash(id))), + name(id), + version(ver) {} + [[nodiscard]] constexpr ServiceIdView(ServiceId const& id) noexcept + : HashedIdBase(id.hash), + name(id.name), + version(id.version) {} + + template + [[nodiscard]] constexpr ServiceIdView(auto_name_t, size_t version) noexcept + : ServiceIdView{ll::reflection::type_unprefix_name_v, version} {} }; +[[nodiscard]] constexpr ServiceId::ServiceId(ServiceIdView const& id) noexcept +: HashedIdBase(id.hash), + name(id.name), + version(id.version) {} -constexpr ServiceId EmptyServiceId{{}, 0}; +constexpr ServiceIdView EmptyServiceId{{}, 0}; template -constexpr ServiceId getServiceId = []() -> ServiceId { +constexpr ServiceIdView getServiceId = []() -> ServiceIdView { using self = std::remove_cvref_t; if constexpr (requires { self::ServiceId; } && self::ServiceId != EmptyServiceId) { return self::ServiceId; @@ -52,10 +56,3 @@ constexpr ServiceId getServiceId = []() -> ServiceId { } }(); } // namespace ll::service - -namespace std { -template <> -struct hash { - size_t operator()(ll::service::ServiceId const& id) const noexcept { return id.hash; } -}; -} // namespace std diff --git a/src/ll/api/service/ServiceManager.cpp b/src/ll/api/service/ServiceManager.cpp index 682830ad03..8f2f598fae 100644 --- a/src/ll/api/service/ServiceManager.cpp +++ b/src/ll/api/service/ServiceManager.cpp @@ -18,25 +18,18 @@ std::string GetServiceError::message() const noexcept { // to avoid a lifetime dependency on external Mod struct ServiceInfo { - std::string name; - size_t version; + ServiceId id; std::string modName; std::shared_ptr service; - ServiceInfo(std::string name, size_t version, std::string modName, std::shared_ptr const& service) - : name(std::move(name)), - version(version), + ServiceInfo(ServiceIdView const& id, std::string modName, std::shared_ptr const& service) + : id(id), modName(std::move(modName)), service(service) {} - ServiceInfo(ServiceId const& id, std::string modName, std::shared_ptr const& service) - : ServiceInfo(std::string{id.name}, id.version, std::move(modName), service) {} + bool operator==(ServiceInfo const& other) const noexcept { return id == other && modName == other.modName; } - bool operator==(ServiceInfo const& other) const noexcept { - return name == other.name && version == other.version && modName == other.modName; - } - - bool operator==(ServiceId const& other) const noexcept { return name == other.name && version == other.version; } + bool operator==(ServiceIdView const& other) const noexcept { return id == other; } }; } // namespace ll::service @@ -44,10 +37,7 @@ namespace std { template <> struct hash { size_t operator()(ll::service::ServiceInfo const& info) const noexcept { - size_t hash = std::hash{}(info.name); - ll::hash_utils::hashCombine(std::hash{}(info.version), hash); - ll::hash_utils::hashCombine(std::hash{}(info.modName), hash); - return hash; + return ll::hash_utils::hashCombineTo(std::hash{}(info.modName), info.id.hash); } }; } // namespace std @@ -58,9 +48,9 @@ class ServiceManager::Impl { public: std::recursive_mutex mutex; - DenseMap> services; + DenseMap> services; - DenseMap> modServices; // mod name -> services + DenseMap> modServices; // mod name -> services bool addService(std::shared_ptr const& service, std::shared_ptr const& mod) { std::lock_guard lock(mutex); @@ -71,7 +61,7 @@ class ServiceManager::Impl { auto info = std::make_unique(id, mod ? mod->getName() : "", service); modServices[info->modName].insert(info.get()); - services.emplace(info->name, std::move(info)); + services.emplace(info->id.name, std::move(info)); // notify the service that it has been registered or updated event::EventBus::getInstance().publish(event::ServiceRegisterEvent{service}); @@ -79,7 +69,7 @@ class ServiceManager::Impl { return true; } - bool removeService(ServiceId const& id) { + bool removeService(ServiceIdView const& id) { std::lock_guard lock(mutex); auto it = services.find(id.name); @@ -103,21 +93,21 @@ class ServiceManager::Impl { std::lock_guard lock(mutex); if (auto it = modServices.find(modName); it != modServices.end()) { for (auto& info : it->second) { - services.erase(info->name); + services.erase(info->id.name); } modServices.erase(it); } } }; -Expected> ServiceManager::getService(ServiceId const& id) { +Expected> ServiceManager::getService(ServiceIdView const& id) { std::lock_guard lock(impl->mutex); if (!impl->services.contains(id.name)) { return makeError(GetServiceError::NotExist); } auto& info = impl->services[id.name]; - if (info->version != id.version) { - return makeError(GetServiceError::VersionMismatch, info->version); + if (info->id.version != id.version) { + return makeError(GetServiceError::VersionMismatch, info->id.version); } return info->service; } @@ -125,12 +115,12 @@ Expected> ServiceManager::getService(ServiceId const& i std::optional ServiceManager::queryService(std::string_view name) { std::lock_guard lock(impl->mutex); if (auto it = impl->services.find(name); it != impl->services.end()) { - return QueryServiceResult{it->second->name, it->second->version, it->second->modName, it->second->service}; + return QueryServiceResult{it->second->id.name, it->second->id.version, it->second->modName, it->second->service}; } return std::nullopt; } -bool ServiceManager::unregisterService(ServiceId const& id) { +bool ServiceManager::unregisterService(ServiceIdView const& id) { std::lock_guard lock(impl->mutex); return impl->removeService(id); } diff --git a/src/ll/api/service/ServiceManager.h b/src/ll/api/service/ServiceManager.h index 1b823f365b..d5120d458c 100644 --- a/src/ll/api/service/ServiceManager.h +++ b/src/ll/api/service/ServiceManager.h @@ -71,7 +71,7 @@ class ServiceManager { return std::static_pointer_cast(*res); } - LLNDAPI Expected> getService(ServiceId const& id); + LLNDAPI Expected> getService(ServiceIdView const& id); LLNDAPI std::optional queryService(std::string_view name); @@ -80,7 +80,7 @@ class ServiceManager { std::shared_ptr const& mod = mod::NativeMod::current() ); - LLAPI bool unregisterService(ServiceId const& id); + LLAPI bool unregisterService(ServiceIdView const& id); LLAPI void unregisterService(mod::Mod const& mod); diff --git a/src/ll/api/utils/HashUtils.h b/src/ll/api/utils/HashUtils.h index 459f4a545b..d448be54d6 100644 --- a/src/ll/api/utils/HashUtils.h +++ b/src/ll/api/utils/HashUtils.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -9,11 +10,31 @@ namespace ll::inline utils::hash_utils { +class HashedIdBase { +protected: + [[nodiscard]] constexpr explicit HashedIdBase(size_t hash) noexcept : hash(hash) {} + +public: + size_t hash; + + [[nodiscard]] constexpr bool operator==(HashedIdBase const& other) const noexcept { return hash == other.hash; } + + [[nodiscard]] constexpr std::strong_ordering operator<=>(HashedIdBase const& other) const noexcept { + return hash <=> other.hash; + } +}; + template constexpr void hashCombine(T const& v, size_t& seed) { seed ^= v + 0x9e3779b9ull + (seed << 6ull) + (seed >> 2ull); } +template +constexpr size_t hashCombineTo(T const& v, size_t seed) { + seed ^= v + 0x9e3779b9ull + (seed << 6ull) + (seed >> 2ull); + return seed; +} + [[nodiscard]] constexpr uint64 doHash(std::string_view x) { // hash_64_fnv1a uint64 hash = 0xcbf29ce484222325; @@ -54,3 +75,11 @@ template namespace ll::inline literals::inline hash_literals { [[nodiscard]] consteval uint64 operator""_h(char const* x, size_t len) { return ll::hash_utils::doHash({x, len}); } } // namespace ll::inline literals::inline hash_literals + +namespace std { +template + requires(std::is_base_of_v) +struct hash { + size_t operator()(T const& id) const noexcept { return id.hash; } +}; +} // namespace std diff --git a/src/ll/core/mod/NativeModManager.cpp b/src/ll/core/mod/NativeModManager.cpp index 72ff8876a0..06a7a7fde1 100644 --- a/src/ll/core/mod/NativeModManager.cpp +++ b/src/ll/core/mod/NativeModManager.cpp @@ -107,18 +107,11 @@ Expected<> NativeModManager::load(Manifest manifest) { ) ); } - // TODO: remove in release - if (auto addr = lib.getAddress("ll_plugin_load"); addr) { - currentLoadingMod->onLoad(addr); - currentLoadingMod->onUnload(lib.getAddress("ll_plugin_unload")); - currentLoadingMod->onEnable(lib.getAddress("ll_plugin_enable")); - currentLoadingMod->onDisable(lib.getAddress("ll_plugin_disable")); - } else { - currentLoadingMod->onLoad(lib.getAddress("ll_mod_load")); - currentLoadingMod->onUnload(lib.getAddress("ll_mod_unload")); - currentLoadingMod->onEnable(lib.getAddress("ll_mod_enable")); - currentLoadingMod->onDisable(lib.getAddress("ll_mod_disable")); - } + currentLoadingMod->onLoad(lib.getAddress("ll_mod_load")); + currentLoadingMod->onUnload(lib.getAddress("ll_mod_unload")); + currentLoadingMod->onEnable(lib.getAddress("ll_mod_enable")); + currentLoadingMod->onDisable(lib.getAddress("ll_mod_disable")); + return currentLoadingMod->onLoad().transform([&, this] { addMod(currentLoadingMod->getName(), currentLoadingMod); handleMap[lib.handle()] = currentLoadingMod;