From 405b37deaa4b59659906d709dbe7a220cc875b74 Mon Sep 17 00:00:00 2001 From: zackhow Date: Mon, 24 Sep 2018 21:07:56 -0400 Subject: [PATCH] Android: Speed up game settings saving Previously would take several seconds to save, sometimes causing ANRs, which was made worse when adding all the controller values. Now we only load/save each section instead of doing it for each setting. Also added a method to save an individual setting. --- .../dolphinemu/dolphinemu/NativeLibrary.java | 4 ++ .../features/settings/utils/SettingsFile.java | 48 ++++++++++++++----- Source/Android/jni/MainAndroid.cpp | 30 ++++++++---- 3 files changed, 62 insertions(+), 20 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 933ba04285..425a749d75 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 @@ -244,6 +244,10 @@ public final class NativeLibrary Rumble.checkRumble(padID, state); } + public static native void LoadGameIniFile(String gameId); + + public static native void SaveGameIniFile(String gameId); + public static native String GetUserSetting(String gameID, String Section, String Key); public static native void SetUserSetting(String gameID, String Section, String Key, String Value); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java index 4592011443..04b36cb84f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java @@ -443,13 +443,27 @@ public final class SettingsFile HashMap settings = section.getSettings(); Set sortedKeySet = new TreeSet<>(settings.keySet()); + // Profile options(wii extension) are not saved, only used to properly display values + if (sectionKey.contains(Settings.SECTION_PROFILE)) + { + continue; + } + else + { + NativeLibrary.LoadGameIniFile(gameId); + } for (String settingKey : sortedKeySet) { Setting setting = settings.get(settingKey); // Special case. Extension gets saved into a controller profile if (settingKey.contains(SettingsFile.KEY_WIIMOTE_EXTENSION)) { - saveCustomWiimoteSetting(gameId, setting); + String padId = + setting.getKey() + .substring(setting.getKey().length() - 1, setting.getKey().length()); + + saveCustomWiimoteSetting(gameId, KEY_WIIMOTE_EXTENSION, setting.getValueAsString(), + padId); } else { @@ -457,30 +471,42 @@ public final class SettingsFile setting.getKey(), setting.getValueAsString()); } } + NativeLibrary.SaveGameIniFile(gameId); } } + public static void saveSingleCustomSetting(final String gameId, final String section, + final String key, + final String value) + { + NativeLibrary.LoadGameIniFile(gameId); + NativeLibrary.SetUserSetting(gameId, section, + key, value); + NativeLibrary.SaveGameIniFile(gameId); + } + /** - * Saves the extension value in a profile and enables that profile. Extension is the only - * controller setting that is not saved in the main config. + * Saves the wiimote setting in a profile and enables that profile. * * @param gameId - * @param setting + * @param key + * @param value + * @param padId */ - public static void saveCustomWiimoteSetting(final String gameId, final Setting setting) + public static void saveCustomWiimoteSetting(final String gameId, final String key, + final String value, + final String padId) { - if (setting.getSection().equals(Settings.SECTION_PROFILE)) - return; - String padId = - setting.getKey().substring(setting.getKey().length() - 1, setting.getKey().length()); String profile = gameId + "_Wii" + padId; - NativeLibrary.SetProfileSetting(profile, Settings.SECTION_PROFILE, KEY_WIIMOTE_EXTENSION, - setting.getValueAsString()); + NativeLibrary.SetProfileSetting(profile, Settings.SECTION_PROFILE, key, + value); // Enable the profile + NativeLibrary.LoadGameIniFile(gameId); NativeLibrary.SetUserSetting(gameId, Settings.SECTION_CONTROLS, KEY_WIIMOTE_PROFILE + (Integer.valueOf(padId) + 1), profile); + NativeLibrary.SaveGameIniFile(gameId); } private static String mapSectionNameFromIni(String generalSectionName) diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index f74ae67788..f4692af117 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include #include #include @@ -15,7 +16,6 @@ #include #include #include -#include #include "Common/AndroidAnalytics.h" #include "Common/CPUDetect.h" @@ -61,6 +61,7 @@ namespace static constexpr char DOLPHIN_TAG[] = "DolphinEmuNative"; ANativeWindow* s_surf; +IniFile s_ini; // The Core only supports using a single Host thread. // If multiple threads want to call host functions then they need to queue @@ -361,27 +362,38 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserSe return ToJString(env, value.c_str()); } +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadGameIniFile(JNIEnv* env, + jobject obj, + jstring jGameID) +{ + std::string gameid = GetJString(env, jGameID); + s_ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini"); +} + +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveGameIniFile(JNIEnv* env, + jobject obj, + jstring jGameID) +{ + std::string gameid = GetJString(env, jGameID); + s_ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini"); +} + JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserSetting( JNIEnv* env, jobject obj, jstring jGameID, jstring jSection, jstring jKey, jstring jValue) { - IniFile ini; std::string gameid = GetJString(env, jGameID); std::string section = GetJString(env, jSection); std::string key = GetJString(env, jKey); std::string val = GetJString(env, jValue); - ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini"); - if (val != "-1") { - ini.GetOrCreateSection(section)->Set(key, val); + s_ini.GetOrCreateSection(section)->Set(key, val); } else { - ini.GetOrCreateSection(section)->Delete(key); + s_ini.GetOrCreateSection(section)->Delete(key); } - - ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini"); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfileSetting( @@ -404,7 +416,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfileSe ini.GetOrCreateSection(section)->Delete(key); } - ini.Save(File::GetUserPath(D_CONFIG_IDX) + "Profiles/Wiimote/" + profile + ".ini"); + ini.Save(File::GetUserPath(D_CONFIG_IDX) + "Profiles/Wiimote/" + profile + ".ini"); } JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(