Android: Split GameFileCacheService broadcasts into two types

This commit is contained in:
JosJuice 2021-02-20 19:41:41 +01:00
parent 3a8793f93f
commit dbcdead04d
5 changed files with 46 additions and 22 deletions

View File

@ -67,8 +67,7 @@ public class AppLinkActivity extends FragmentActivity
mAfterDirectoryInitializationRunner = new AfterDirectoryInitializationRunner(); mAfterDirectoryInitializationRunner = new AfterDirectoryInitializationRunner();
mAfterDirectoryInitializationRunner.run(this, true, () -> tryPlay(playAction)); mAfterDirectoryInitializationRunner.run(this, true, () -> tryPlay(playAction));
IntentFilter gameFileCacheIntentFilter = new IntentFilter( IntentFilter gameFileCacheIntentFilter = new IntentFilter(GameFileCacheService.DONE_LOADING);
GameFileCacheService.BROADCAST_ACTION);
BroadcastReceiver gameFileCacheReceiver = new BroadcastReceiver() BroadcastReceiver gameFileCacheReceiver = new BroadcastReceiver()
{ {
@ -109,7 +108,7 @@ public class AppLinkActivity extends FragmentActivity
// If game == null and the load isn't done, wait for the next GameFileCacheService broadcast. // If game == null and the load isn't done, wait for the next GameFileCacheService broadcast.
// If game == null and the load is done, call play with a null game, making us exit in failure. // If game == null and the load is done, call play with a null game, making us exit in failure.
if (game != null || GameFileCacheService.hasLoadedCache()) if (game != null || !GameFileCacheService.isLoading())
{ {
play(action, game); play(action, game);
} }

View File

@ -116,6 +116,8 @@ public class GameFileCache
return cacheChanged; return cacheChanged;
} }
public native int getSize();
public native GameFile[] getAllGames(); public native GameFile[] getAllGames();
public native GameFile addOrGet(String gamePath); public native GameFile addOrGet(String gamePath);

View File

@ -15,7 +15,7 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
/** /**
@ -23,7 +23,17 @@ import java.util.concurrent.atomic.AtomicReference;
*/ */
public final class GameFileCacheService extends IntentService public final class GameFileCacheService extends IntentService
{ {
public static final String BROADCAST_ACTION = "org.dolphinemu.dolphinemu.GAME_FILE_CACHE_UPDATED"; /**
* This is broadcast when the contents of the cache change.
*/
public static final String CACHE_UPDATED = "org.dolphinemu.dolphinemu.GAME_FILE_CACHE_UPDATED";
/**
* This is broadcast when the service is done with all requested work, regardless of whether
* the contents of the cache actually changed. (Maybe the cache was already up to date.)
*/
public static final String DONE_LOADING =
"org.dolphinemu.dolphinemu.GAME_FILE_CACHE_DONE_LOADING";
private static final String ACTION_LOAD = "org.dolphinemu.dolphinemu.LOAD_GAME_FILE_CACHE"; private static final String ACTION_LOAD = "org.dolphinemu.dolphinemu.LOAD_GAME_FILE_CACHE";
private static final String ACTION_RESCAN = "org.dolphinemu.dolphinemu.RESCAN_GAME_FILE_CACHE"; private static final String ACTION_RESCAN = "org.dolphinemu.dolphinemu.RESCAN_GAME_FILE_CACHE";
@ -31,8 +41,7 @@ public final class GameFileCacheService extends IntentService
private static GameFileCache gameFileCache = null; private static GameFileCache gameFileCache = null;
private static final AtomicReference<GameFile[]> gameFiles = private static final AtomicReference<GameFile[]> gameFiles =
new AtomicReference<>(new GameFile[]{}); new AtomicReference<>(new GameFile[]{});
private static final AtomicBoolean hasLoadedCache = new AtomicBoolean(false); private static final AtomicInteger unhandledIntents = new AtomicInteger(0);
private static final AtomicBoolean hasScannedLibrary = new AtomicBoolean(false);
public GameFileCacheService() public GameFileCacheService()
{ {
@ -96,14 +105,9 @@ public final class GameFileCacheService extends IntentService
return new String[]{gameFile.getPath(), secondFile.getPath()}; return new String[]{gameFile.getPath(), secondFile.getPath()};
} }
public static boolean hasLoadedCache() public static boolean isLoading()
{ {
return hasLoadedCache.get(); return unhandledIntents.get() != 0;
}
public static boolean hasScannedLibrary()
{
return hasScannedLibrary.get();
} }
private static void startService(Context context, String action) private static void startService(Context context, String action)
@ -119,6 +123,8 @@ public final class GameFileCacheService extends IntentService
*/ */
public static void startLoad(Context context) public static void startLoad(Context context)
{ {
unhandledIntents.getAndIncrement();
new AfterDirectoryInitializationRunner().run(context, false, new AfterDirectoryInitializationRunner().run(context, false,
() -> startService(context, ACTION_LOAD)); () -> startService(context, ACTION_LOAD));
} }
@ -130,6 +136,8 @@ public final class GameFileCacheService extends IntentService
*/ */
public static void startRescan(Context context) public static void startRescan(Context context)
{ {
unhandledIntents.getAndIncrement();
new AfterDirectoryInitializationRunner().run(context, false, new AfterDirectoryInitializationRunner().run(context, false,
() -> startService(context, ACTION_RESCAN)); () -> startService(context, ACTION_RESCAN));
} }
@ -156,9 +164,11 @@ public final class GameFileCacheService extends IntentService
{ {
gameFileCache = temp; gameFileCache = temp;
gameFileCache.load(); gameFileCache.load();
if (gameFileCache.getSize() != 0)
{
updateGameFileArray(); updateGameFileArray();
hasLoadedCache.set(true); sendBroadcast(CACHE_UPDATED);
sendBroadcast(); }
} }
} }
@ -169,13 +179,20 @@ public final class GameFileCacheService extends IntentService
{ {
boolean changed = gameFileCache.scanLibrary(); boolean changed = gameFileCache.scanLibrary();
if (changed) if (changed)
{
updateGameFileArray(); updateGameFileArray();
hasScannedLibrary.set(true); sendBroadcast(CACHE_UPDATED);
sendBroadcast();
} }
} }
} }
int intentsLeft = unhandledIntents.decrementAndGet();
if (intentsLeft == 0)
{
sendBroadcast(DONE_LOADING);
}
}
private void updateGameFileArray() private void updateGameFileArray()
{ {
GameFile[] gameFilesTemp = gameFileCache.getAllGames(); GameFile[] gameFilesTemp = gameFileCache.getAllGames();
@ -183,8 +200,8 @@ public final class GameFileCacheService extends IntentService
gameFiles.set(gameFilesTemp); gameFiles.set(gameFilesTemp);
} }
private void sendBroadcast() private void sendBroadcast(String action)
{ {
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(BROADCAST_ACTION)); LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(action));
} }
} }

View File

@ -53,7 +53,7 @@ public final class MainPresenter
mView.setVersionString(versionName); mView.setVersionString(versionName);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(GameFileCacheService.BROADCAST_ACTION); filter.addAction(GameFileCacheService.CACHE_UPDATED);
mBroadcastReceiver = new BroadcastReceiver() mBroadcastReceiver = new BroadcastReceiver()
{ {
@Override @Override

View File

@ -39,6 +39,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_model_GameFileCache_finali
delete GetPointer(env, obj); delete GetPointer(env, obj);
} }
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFileCache_getSize(JNIEnv* env,
jobject obj)
{
return static_cast<jint>(GetPointer(env, obj)->GetSize());
}
JNIEXPORT jobjectArray JNICALL JNIEXPORT jobjectArray JNICALL
Java_org_dolphinemu_dolphinemu_model_GameFileCache_getAllGames(JNIEnv* env, jobject obj) Java_org_dolphinemu_dolphinemu_model_GameFileCache_getAllGames(JNIEnv* env, jobject obj)
{ {