Merge pull request #11663 from JosJuice/android-config-change-callback
Android: Use config changed callback for tracking recursive scan setting
This commit is contained in:
commit
e0f4111561
|
@ -0,0 +1,33 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.dolphinemu.dolphinemu.features.settings.model
|
||||
|
||||
import androidx.annotation.Keep
|
||||
|
||||
/**
|
||||
* Calls the passed-in Runnable when Dolphin's config changes.
|
||||
*
|
||||
* Please note: The Runnable may be called from any thread.
|
||||
*/
|
||||
class ConfigChangedCallback(runnable: Runnable) {
|
||||
@Keep
|
||||
private var pointer: Long = initialize(runnable)
|
||||
|
||||
/**
|
||||
* Stops the callback from being called in the future.
|
||||
*/
|
||||
fun unregister() {
|
||||
if (pointer != 0L) {
|
||||
deinitialize(pointer)
|
||||
pointer = 0L
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
private external fun initialize(runnable: Runnable): Long
|
||||
|
||||
@JvmStatic
|
||||
private external fun deinitialize(pointer: Long)
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ import android.widget.Toast
|
|||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.features.input.model.MappingCommon
|
||||
import org.dolphinemu.dolphinemu.services.GameFileCacheManager
|
||||
import java.io.Closeable
|
||||
|
||||
class Settings : Closeable {
|
||||
|
@ -19,7 +18,6 @@ class Settings : Closeable {
|
|||
private set
|
||||
|
||||
private var settingsLoaded = false
|
||||
private var loadedRecursiveIsoPathsValue = false
|
||||
|
||||
private val isGameSpecific: Boolean
|
||||
get() = !TextUtils.isEmpty(gameId)
|
||||
|
@ -41,8 +39,6 @@ class Settings : Closeable {
|
|||
check(!NativeLibrary.IsRunning()) { "Attempted to load game INI while emulating" }
|
||||
NativeConfig.loadGameInis(gameId, revision)
|
||||
}
|
||||
|
||||
loadedRecursiveIsoPathsValue = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean
|
||||
}
|
||||
|
||||
fun loadSettings(gameId: String, revision: Int, isWii: Boolean) {
|
||||
|
@ -65,11 +61,6 @@ class Settings : Closeable {
|
|||
|
||||
NativeLibrary.ReloadLoggerConfig()
|
||||
NativeLibrary.UpdateGCAdapterScanThread()
|
||||
|
||||
if (loadedRecursiveIsoPathsValue != BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean) {
|
||||
// Refresh game library
|
||||
GameFileCacheManager.startRescan()
|
||||
}
|
||||
} else {
|
||||
// custom game settings
|
||||
if (context != null) {
|
||||
|
|
|
@ -2,9 +2,14 @@
|
|||
|
||||
package org.dolphinemu.dolphinemu.services;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.ConfigChangedCallback;
|
||||
import org.dolphinemu.dolphinemu.model.GameFile;
|
||||
import org.dolphinemu.dolphinemu.model.GameFileCache;
|
||||
import org.dolphinemu.dolphinemu.ui.platform.Platform;
|
||||
|
@ -26,6 +31,7 @@ public final class GameFileCacheManager
|
|||
new MutableLiveData<>(new GameFile[]{});
|
||||
private static boolean sFirstLoadDone = false;
|
||||
private static boolean sRunRescanAfterLoad = false;
|
||||
private static boolean sRecursiveScanEnabled;
|
||||
|
||||
private static final ExecutorService sExecutor = Executors.newFixedThreadPool(1);
|
||||
private static final MutableLiveData<Boolean> sLoadInProgress = new MutableLiveData<>(false);
|
||||
|
@ -154,8 +160,8 @@ public final class GameFileCacheManager
|
|||
|
||||
public static GameFile addOrGet(String gamePath)
|
||||
{
|
||||
// Common case: The game is in the cache, so just grab it from there.
|
||||
// (Actually, addOrGet already checks for this case, but we want to avoid calling it if possible
|
||||
// Common case: The game is in the cache, so just grab it from there. (GameFileCache.addOrGet
|
||||
// actually already checks for this case, but we want to avoid calling it if possible
|
||||
// because the executor thread may hold a lock on sGameFileCache for extended periods of time.)
|
||||
GameFile[] allGames = sGameFiles.getValue();
|
||||
for (GameFile game : allGames)
|
||||
|
@ -182,6 +188,7 @@ public final class GameFileCacheManager
|
|||
if (!sFirstLoadDone)
|
||||
{
|
||||
sFirstLoadDone = true;
|
||||
setUpAutomaticRescan();
|
||||
sGameFileCache.load();
|
||||
if (sGameFileCache.getSize() != 0)
|
||||
{
|
||||
|
@ -191,6 +198,8 @@ public final class GameFileCacheManager
|
|||
|
||||
if (sRunRescanAfterLoad)
|
||||
{
|
||||
// Without this, there will be a short blip where the loading indicator in the GUI disappears
|
||||
// because neither sLoadInProgress nor sRescanInProgress is true
|
||||
sRescanInProgress.postValue(true);
|
||||
}
|
||||
|
||||
|
@ -258,4 +267,19 @@ public final class GameFileCacheManager
|
|||
sGameFileCache = new GameFileCache();
|
||||
}
|
||||
}
|
||||
|
||||
private static void setUpAutomaticRescan()
|
||||
{
|
||||
sRecursiveScanEnabled = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBoolean();
|
||||
new ConfigChangedCallback(() ->
|
||||
new Handler(Looper.getMainLooper()).post(() ->
|
||||
{
|
||||
boolean recursiveScanEnabled = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.getBoolean();
|
||||
if (sRecursiveScanEnabled != recursiveScanEnabled)
|
||||
{
|
||||
sRecursiveScanEnabled = recursiveScanEnabled;
|
||||
startRescan();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,8 @@ static jclass s_core_device_control_class;
|
|||
static jfieldID s_core_device_control_pointer;
|
||||
static jmethodID s_core_device_control_constructor;
|
||||
|
||||
static jmethodID s_runnable_run;
|
||||
|
||||
namespace IDCache
|
||||
{
|
||||
JNIEnv* GetEnvForThread()
|
||||
|
@ -504,6 +506,11 @@ jmethodID GetCoreDeviceControlConstructor()
|
|||
return s_core_device_control_constructor;
|
||||
}
|
||||
|
||||
jmethodID GetRunnableRun()
|
||||
{
|
||||
return s_runnable_run;
|
||||
}
|
||||
|
||||
} // namespace IDCache
|
||||
|
||||
extern "C" {
|
||||
|
@ -709,6 +716,10 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
"(Lorg/dolphinemu/dolphinemu/features/input/model/CoreDevice;J)V");
|
||||
env->DeleteLocalRef(core_device_control_class);
|
||||
|
||||
const jclass runnable_class = env->FindClass("java/lang/Runnable");
|
||||
s_runnable_run = env->GetMethodID(runnable_class, "run", "()V");
|
||||
env->DeleteLocalRef(runnable_class);
|
||||
|
||||
return JNI_VERSION;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,4 +108,6 @@ jclass GetCoreDeviceControlClass();
|
|||
jfieldID GetCoreDeviceControlPointer();
|
||||
jmethodID GetCoreDeviceControlConstructor();
|
||||
|
||||
jmethodID GetRunnableRun();
|
||||
|
||||
} // namespace IDCache
|
||||
|
|
|
@ -5,6 +5,7 @@ add_library(main SHARED
|
|||
Cheats/GraphicsMod.cpp
|
||||
Cheats/GraphicsModGroup.cpp
|
||||
Cheats/PatchCheat.cpp
|
||||
Config/ConfigChangedCallback.cpp
|
||||
Config/NativeConfig.cpp
|
||||
Config/PostProcessing.cpp
|
||||
GameList/GameFile.cpp
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||
#include "jni/AndroidCommon/IDCache.h"
|
||||
|
||||
struct ConfigChangedCallbackContext
|
||||
{
|
||||
jobject runnable;
|
||||
Config::ConfigChangedCallbackID callback_id;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_settings_model_ConfigChangedCallback_initialize(
|
||||
JNIEnv* env, jclass, jobject runnable)
|
||||
{
|
||||
auto* context = new ConfigChangedCallbackContext;
|
||||
|
||||
jobject runnable_global = env->NewGlobalRef(runnable);
|
||||
context->runnable = runnable_global;
|
||||
context->callback_id = Config::AddConfigChangedCallback([runnable_global] {
|
||||
IDCache::GetEnvForThread()->CallVoidMethod(runnable_global, IDCache::GetRunnableRun());
|
||||
});
|
||||
|
||||
return reinterpret_cast<jlong>(context);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_settings_model_ConfigChangedCallback_deinitialize(
|
||||
JNIEnv* env, jclass, jlong pointer)
|
||||
{
|
||||
auto* context = reinterpret_cast<ConfigChangedCallbackContext*>(pointer);
|
||||
|
||||
Config::RemoveConfigChangedCallback(context->callback_id);
|
||||
env->DeleteGlobalRef(context->runnable);
|
||||
|
||||
delete context;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue