From ea7928b3cda5749ba1dcc8e534b1474a28efb28a Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 15 Jun 2024 20:02:10 +0200 Subject: [PATCH] Android: Replace log type names map with array Storing the log type names in a map results in them getting re-sorted by their keys, which doesn't quite give us the sorting we want. In particular, the Achievements category ended up being sorted at R (for RetroAchivements) instead of at A. Every use of the map is just iterating through it, so there's no real reason why it has to be a map anyway. --- .../dolphinemu/dolphinemu/NativeLibrary.java | 4 +-- .../settings/ui/SettingsFragmentPresenter.kt | 8 ++--- Source/Android/jni/AndroidCommon/IDCache.cpp | 31 +++++++---------- Source/Android/jni/AndroidCommon/IDCache.h | 5 ++- Source/Android/jni/MainAndroid.cpp | 33 +++++++++---------- Source/Core/Common/Logging/LogManager.cpp | 7 ++-- Source/Core/Common/Logging/LogManager.h | 18 +++++----- 7 files changed, 49 insertions(+), 57 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index 43880bd0ba..aa90056141 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -12,6 +12,7 @@ import android.view.Surface; import android.widget.Toast; import androidx.annotation.Keep; +import androidx.core.util.Pair; import androidx.fragment.app.FragmentManager; import org.dolphinemu.dolphinemu.activities.EmulationActivity; @@ -20,7 +21,6 @@ import org.dolphinemu.dolphinemu.utils.CompressCallback; import org.dolphinemu.dolphinemu.utils.Log; import java.lang.ref.WeakReference; -import java.util.LinkedHashMap; import java.util.concurrent.Semaphore; /** @@ -400,7 +400,7 @@ public final class NativeLibrary */ public static native void RefreshWiimotes(); - public static native LinkedHashMap GetLogTypeNames(); + public static native Pair[] GetLogTypeNames(); public static native void ReloadLoggerConfig(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index 6de39ed1e9..eba71c42fa 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -1946,8 +1946,8 @@ class SettingsFragmentPresenter( ) { SettingsAdapter.clearLog() }) sl.add(HeaderSetting(context, R.string.log_types, 0)) - for ((key, value) in LOG_TYPE_NAMES) { - sl.add(LogSwitchSetting(key, value, "")) + for (logType in LOG_TYPE_NAMES) { + sl.add(LogSwitchSetting(logType.first, logType.second, "")) } } @@ -2468,11 +2468,11 @@ class SettingsFragmentPresenter( fun setAllLogTypes(value: Boolean) { val settings = fragmentView.settings - for ((key) in LOG_TYPE_NAMES) { + for (logType in LOG_TYPE_NAMES) { AdHocBooleanSetting( Settings.FILE_LOGGER, Settings.SECTION_LOGGER_LOGS, - key, + logType.first, false ).setBoolean(settings!!, value) } diff --git a/Source/Android/jni/AndroidCommon/IDCache.cpp b/Source/Android/jni/AndroidCommon/IDCache.cpp index 5fe151278f..eba20ead91 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.cpp +++ b/Source/Android/jni/AndroidCommon/IDCache.cpp @@ -29,9 +29,8 @@ static jclass s_analytics_class; static jmethodID s_send_analytics_report; static jmethodID s_get_analytics_value; -static jclass s_linked_hash_map_class; -static jmethodID s_linked_hash_map_init; -static jmethodID s_linked_hash_map_put; +static jclass s_pair_class; +static jmethodID s_pair_constructor; static jclass s_hash_map_class; static jmethodID s_hash_map_init; @@ -212,19 +211,14 @@ jfieldID GetGameFileCachePointer() return s_game_file_cache_pointer; } -jclass GetLinkedHashMapClass() +jclass GetPairClass() { - return s_linked_hash_map_class; + return s_pair_class; } -jmethodID GetLinkedHashMapInit() +jmethodID GetPairConstructor() { - return s_linked_hash_map_init; -} - -jmethodID GetLinkedHashMapPut() -{ - return s_linked_hash_map_put; + return s_pair_constructor; } jclass GetHashMapClass() @@ -565,12 +559,11 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) "(Ljava/lang/String;)Ljava/lang/String;"); env->DeleteLocalRef(analytics_class); - const jclass linked_hash_map_class = env->FindClass("java/util/LinkedHashMap"); - s_linked_hash_map_class = reinterpret_cast(env->NewGlobalRef(linked_hash_map_class)); - s_linked_hash_map_init = env->GetMethodID(s_linked_hash_map_class, "", "(I)V"); - s_linked_hash_map_put = env->GetMethodID( - s_linked_hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - env->DeleteLocalRef(linked_hash_map_class); + const jclass pair_class = env->FindClass("androidx/core/util/Pair"); + s_pair_class = reinterpret_cast(env->NewGlobalRef(pair_class)); + s_pair_constructor = + env->GetMethodID(s_pair_class, "", "(Ljava/lang/Object;Ljava/lang/Object;)V"); + env->DeleteLocalRef(pair_class); const jclass hash_map_class = env->FindClass("java/util/HashMap"); s_hash_map_class = reinterpret_cast(env->NewGlobalRef(hash_map_class)); @@ -741,7 +734,7 @@ JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved) env->DeleteGlobalRef(s_game_file_class); env->DeleteGlobalRef(s_game_file_cache_class); env->DeleteGlobalRef(s_analytics_class); - env->DeleteGlobalRef(s_linked_hash_map_class); + env->DeleteGlobalRef(s_pair_class); env->DeleteGlobalRef(s_hash_map_class); env->DeleteGlobalRef(s_compress_cb_class); env->DeleteGlobalRef(s_content_handler_class); diff --git a/Source/Android/jni/AndroidCommon/IDCache.h b/Source/Android/jni/AndroidCommon/IDCache.h index c324b6cb19..c31f598441 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.h +++ b/Source/Android/jni/AndroidCommon/IDCache.h @@ -29,9 +29,8 @@ jmethodID GetGameFileConstructor(); jclass GetGameFileCacheClass(); jfieldID GetGameFileCachePointer(); -jclass GetLinkedHashMapClass(); -jmethodID GetLinkedHashMapInit(); -jmethodID GetLinkedHashMapPut(); +jclass GetPairClass(); +jmethodID GetPairConstructor(); jclass GetHashMapClass(); jmethodID GetHashMapInit(); diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 9fcf1b33a3..d1f23383fa 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "Common/AndroidAnalytics.h" #include "Common/Assert.h" @@ -648,27 +649,25 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ChangeDisc(J system.GetDVDInterface().ChangeDisc(Core::CPUThreadGuard{system}, path); } -JNIEXPORT jobject JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetLogTypeNames(JNIEnv* env, - jclass) +JNIEXPORT jobjectArray JNICALL +Java_org_dolphinemu_dolphinemu_NativeLibrary_GetLogTypeNames(JNIEnv* env, jclass) { - std::map map = Common::Log::LogManager::GetInstance()->GetLogTypes(); + using LogManager = Common::Log::LogManager; - auto map_size = static_cast(map.size()); - jobject linked_hash_map = - env->NewObject(IDCache::GetLinkedHashMapClass(), IDCache::GetLinkedHashMapInit(), map_size); - for (const auto& entry : map) - { - jstring key = ToJString(env, entry.first); - jstring value = ToJString(env, entry.second); + return VectorToJObjectArray( + env, LogManager::GetInstance()->GetLogTypes(), IDCache::GetPairClass(), + [](JNIEnv* env_, const LogManager::LogContainer& log_container) { + jstring short_name = ToJString(env_, log_container.m_short_name); + jstring full_name = ToJString(env_, log_container.m_full_name); - jobject result = - env->CallObjectMethod(linked_hash_map, IDCache::GetLinkedHashMapPut(), key, value); + jobject pair = env_->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(), + short_name, full_name); - env->DeleteLocalRef(key); - env->DeleteLocalRef(value); - env->DeleteLocalRef(result); - } - return linked_hash_map; + env_->DeleteLocalRef(short_name); + env_->DeleteLocalRef(full_name); + + return pair; + }); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ReloadLoggerConfig(JNIEnv*, diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index 749117bc74..283bd436e0 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -252,12 +252,13 @@ bool LogManager::IsEnabled(LogType type, LogLevel level) const return m_log[type].m_enable && GetLogLevel() >= level; } -std::map LogManager::GetLogTypes() +std::vector LogManager::GetLogTypes() { - std::map log_types; + std::vector log_types; + log_types.reserve(m_log.size()); for (const auto& container : m_log) - log_types.emplace(container.m_short_name, container.m_full_name); + log_types.emplace_back(container); return log_types; } diff --git a/Source/Core/Common/Logging/LogManager.h b/Source/Core/Common/Logging/LogManager.h index 093d31e01d..265c294465 100644 --- a/Source/Core/Common/Logging/LogManager.h +++ b/Source/Core/Common/Logging/LogManager.h @@ -5,8 +5,8 @@ #include #include -#include #include +#include #include "Common/BitSet.h" #include "Common/EnumMap.h" @@ -34,6 +34,13 @@ public: class LogManager { public: + struct LogContainer + { + const char* m_short_name; + const char* m_full_name; + bool m_enable = false; + }; + static LogManager* GetInstance(); static void Init(); static void Shutdown(); @@ -48,7 +55,7 @@ public: void SetEnable(LogType type, bool enable); bool IsEnabled(LogType type, LogLevel level = LogLevel::LNOTICE) const; - std::map GetLogTypes(); + std::vector GetLogTypes(); const char* GetShortName(LogType type) const; const char* GetFullName(LogType type) const; @@ -60,13 +67,6 @@ public: void SaveSettings(); private: - struct LogContainer - { - const char* m_short_name; - const char* m_full_name; - bool m_enable = false; - }; - LogManager(); ~LogManager();