diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java deleted file mode 100644 index 59c8893dcf..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java +++ /dev/null @@ -1,139 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.model; - -import androidx.annotation.Keep; - -import org.dolphinemu.dolphinemu.NativeLibrary; -import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; -import org.dolphinemu.dolphinemu.features.settings.model.Settings; -import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile; -import org.dolphinemu.dolphinemu.utils.ContentHandler; -import org.dolphinemu.dolphinemu.utils.IniFile; - -import java.io.File; -import java.util.LinkedHashSet; - -public class GameFileCache -{ - @Keep - private long mPointer; - - public GameFileCache() - { - mPointer = newGameFileCache(); - } - - private static native long newGameFileCache(); - - @Override - public native void finalize(); - - public static void addGameFolder(String path) - { - File dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN); - IniFile dolphinIni = new IniFile(dolphinFile); - LinkedHashSet pathSet = getPathSet(false); - int totalISOPaths = - dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0); - - if (!pathSet.contains(path)) - { - dolphinIni.setInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, - totalISOPaths + 1); - dolphinIni.setString(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATH_BASE + - totalISOPaths, path); - dolphinIni.save(dolphinFile); - NativeLibrary.ReloadConfig(); - } - } - - private static LinkedHashSet getPathSet(boolean removeNonExistentFolders) - { - File dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN); - IniFile dolphinIni = new IniFile(dolphinFile); - LinkedHashSet pathSet = new LinkedHashSet<>(); - int totalISOPaths = - dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0); - - for (int i = 0; i < totalISOPaths; i++) - { - String path = dolphinIni.getString(Settings.SECTION_INI_GENERAL, - SettingsFile.KEY_ISO_PATH_BASE + i, ""); - - if (ContentHandler.isContentUri(path) ? ContentHandler.exists(path) : new File(path).exists()) - { - pathSet.add(path); - } - } - - if (removeNonExistentFolders && totalISOPaths > pathSet.size()) - { - int setIndex = 0; - - dolphinIni.setInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, - pathSet.size()); - - // One or more folders have been removed. - for (String entry : pathSet) - { - dolphinIni.setString(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATH_BASE + - setIndex, entry); - - setIndex++; - } - - // Delete known unnecessary keys. Ignore i values beyond totalISOPaths. - for (int i = setIndex; i < totalISOPaths; i++) - { - dolphinIni.deleteKey(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATH_BASE + i); - } - - dolphinIni.save(dolphinFile); - NativeLibrary.ReloadConfig(); - } - - return pathSet; - } - - public static String[] getAllGamePaths() - { - boolean recursiveScan = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBoolean(); - - LinkedHashSet folderPathsSet = getPathSet(true); - - String[] folderPaths = folderPathsSet.toArray(new String[0]); - - return getAllGamePaths(folderPaths, recursiveScan); - } - - public static native String[] getAllGamePaths(String[] folderPaths, boolean recursiveScan); - - public synchronized native int getSize(); - - public synchronized native GameFile[] getAllGames(); - - public synchronized native GameFile addOrGet(String gamePath); - - /** - * Sets the list of games to cache. - * - * Games which are in the passed-in list but not in the cache are scanned and added to the cache, - * and games which are in the cache but not in the passed-in list are removed from the cache. - * - * @return true if the cache was modified - */ - public synchronized native boolean update(String[] gamePaths); - - /** - * For each game that already is in the cache, scans the folder that contains the game - * for additional metadata files (PNG/XML). - * - * @return true if the cache was modified - */ - public synchronized native boolean updateAdditionalMetadata(); - - public synchronized native boolean load(); - - public synchronized native boolean save(); -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.kt new file mode 100644 index 0000000000..74b1bd535a --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.kt @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.model + +import androidx.annotation.Keep +import org.dolphinemu.dolphinemu.NativeLibrary +import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting +import org.dolphinemu.dolphinemu.features.settings.model.Settings +import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile +import org.dolphinemu.dolphinemu.utils.ContentHandler +import org.dolphinemu.dolphinemu.utils.IniFile +import java.io.File + +class GameFileCache { + @Keep + private val pointer: Long = newGameFileCache() + + external fun finalize() + + @Synchronized + external fun getSize(): Int + + @Synchronized + external fun getAllGames(): Array + + @Synchronized + external fun addOrGet(gamePath: String): GameFile? + + /** + * Sets the list of games to cache. + * + * Games which are in the passed-in list but not in the cache are scanned and added to the cache, + * and games which are in the cache but not in the passed-in list are removed from the cache. + * + * @return true if the cache was modified + */ + @Synchronized + external fun update(gamePaths: Array): Boolean + + /** + * For each game that already is in the cache, scans the folder that contains the game + * for additional metadata files (PNG/XML). + * + * @return true if the cache was modified + */ + @Synchronized + external fun updateAdditionalMetadata(): Boolean + + @Synchronized + external fun load(): Boolean + + @Synchronized + external fun save(): Boolean + + companion object { + @JvmStatic + private external fun newGameFileCache(): Long + + fun addGameFolder(path: String) { + val dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN) + val dolphinIni = IniFile(dolphinFile) + val pathSet = getPathSet(false) + val totalISOPaths = + dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0) + + if (!pathSet.contains(path)) { + dolphinIni.setInt( + Settings.SECTION_INI_GENERAL, + SettingsFile.KEY_ISO_PATHS, + totalISOPaths + 1 + ) + dolphinIni.setString( + Settings.SECTION_INI_GENERAL, + SettingsFile.KEY_ISO_PATH_BASE + totalISOPaths, + path + ) + dolphinIni.save(dolphinFile) + NativeLibrary.ReloadConfig() + } + } + + private fun getPathSet(removeNonExistentFolders: Boolean): LinkedHashSet { + val dolphinFile = SettingsFile.getSettingsFile(Settings.FILE_DOLPHIN) + val dolphinIni = IniFile(dolphinFile) + val pathSet = LinkedHashSet() + val totalISOPaths = + dolphinIni.getInt(Settings.SECTION_INI_GENERAL, SettingsFile.KEY_ISO_PATHS, 0) + + for (i in 0 until totalISOPaths) { + val path = dolphinIni.getString( + Settings.SECTION_INI_GENERAL, + SettingsFile.KEY_ISO_PATH_BASE + i, + "" + ) + + val pathExists = if (ContentHandler.isContentUri(path)) + ContentHandler.exists(path) + else + File(path).exists() + if (pathExists) { + pathSet.add(path) + } + } + + if (removeNonExistentFolders && totalISOPaths > pathSet.size) { + var setIndex = 0 + + dolphinIni.setInt( + Settings.SECTION_INI_GENERAL, + SettingsFile.KEY_ISO_PATHS, + pathSet.size + ) + + // One or more folders have been removed. + for (entry in pathSet) { + dolphinIni.setString( + Settings.SECTION_INI_GENERAL, + SettingsFile.KEY_ISO_PATH_BASE + setIndex, + entry + ) + setIndex++ + } + + // Delete known unnecessary keys. Ignore i values beyond totalISOPaths. + for (i in setIndex until totalISOPaths) { + dolphinIni.deleteKey( + Settings.SECTION_INI_GENERAL, + SettingsFile.KEY_ISO_PATH_BASE + i + ) + } + + dolphinIni.save(dolphinFile) + NativeLibrary.ReloadConfig() + } + return pathSet + } + + @JvmStatic + fun getAllGamePaths(): Array { + val recursiveScan = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean + val folderPathsSet = getPathSet(true) + val folderPaths = folderPathsSet.toTypedArray() + return getAllGamePaths(folderPaths, recursiveScan) + } + + @JvmStatic + external fun getAllGamePaths( + folderPaths: Array, + recursiveScan: Boolean + ): Array + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt index 64695a0ace..e77b694096 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.kt @@ -123,7 +123,7 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme fun onResume() { if (dirToAdd != null) { - GameFileCache.addGameFolder(dirToAdd) + GameFileCache.addGameFolder(dirToAdd!!) dirToAdd = null } diff --git a/Source/Android/jni/AndroidCommon/IDCache.cpp b/Source/Android/jni/AndroidCommon/IDCache.cpp index 2396f0960b..f83707cebe 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.cpp +++ b/Source/Android/jni/AndroidCommon/IDCache.cpp @@ -570,7 +570,7 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) const jclass game_file_cache_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFileCache"); s_game_file_cache_class = reinterpret_cast(env->NewGlobalRef(game_file_cache_class)); - s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "mPointer", "J"); + s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "pointer", "J"); env->DeleteLocalRef(game_file_cache_class); const jclass analytics_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Analytics");