diff --git a/Source/Android/app/build.gradle b/Source/Android/app/build.gradle
index 62588307e0..dacc7d6ff5 100644
--- a/Source/Android/app/build.gradle
+++ b/Source/Android/app/build.gradle
@@ -89,6 +89,9 @@ dependencies {
// For loading huge screenshots from the disk.
compile 'com.squareup.picasso:picasso:2.5.2'
+
+ // Allows FRP-style asynchronous operations in Android.
+ compile 'io.reactivex:rxandroid:1.1.0'
}
task setupCMake(type: Exec) {
diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml
index e08b2dd0a8..adfda3d0ce 100644
--- a/Source/Android/app/src/main/AndroidManifest.xml
+++ b/Source/Android/app/src/main/AndroidManifest.xml
@@ -18,6 +18,7 @@
+public final class MainActivity extends AppCompatActivity
{
public static final int REQUEST_ADD_DIRECTORY = 1;
public static final int REQUEST_EMULATE_GAME = 2;
- /**
- * It is important to keep track of loader ID separately from platform ID (see Game.java)
- * because we could potentially have Loaders that load things other than Games.
- */
- public static final int LOADER_ID_ALL = 100; // TODO
- public static final int LOADER_ID_GAMECUBE = 0;
- public static final int LOADER_ID_WII = 1;
- public static final int LOADER_ID_WIIWARE = 2;
-
private ViewPager mViewPager;
private PlatformPagerAdapter mPlatformPagerAdapter;
@@ -175,132 +163,6 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
}
}
-
- /**
- * Callback that's invoked when the system has initialized the Loader and
- * is ready to start the query. This usually happens when initLoader() is
- * called. Here, we use it to make a DB query for games.
- *
- * @param id The ID value passed to the initLoader() call that triggered this.
- * @param args The args bundle supplied by the caller.
- * @return A new Loader instance that is ready to start loading.
- */
- @Override
- public Loader onCreateLoader(int id, Bundle args)
- {
- Log.d("DolphinEmu", "Creating loader with id: " + id);
-
- // Take action based on the ID of the Loader that's being created.
- switch (id)
- {
- case LOADER_ID_ALL:
- // TODO Play some sort of load-starting animation; maybe fade the list out.
-
- return new CursorLoader(
- this, // Parent activity context
- GameProvider.URI_GAME, // URI of table to query
- null, // Return all columns
- null, // No selection clause
- null, // No selection arguments
- GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
- );
-
- case LOADER_ID_GAMECUBE:
- case LOADER_ID_WII:
- case LOADER_ID_WIIWARE:
- // TODO Play some sort of load-starting animation; maybe fade the list out.
-
- return new CursorLoader(
- this, // Parent activity context
- GameProvider.URI_GAME, // URI of table to query
- null, // Return all columns
- GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform
- new String[]{Integer.toString(id)}, // Platform id is Loader id
- GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
- );
-
- default:
- Log.e("DolphinEmu", "Bad ID passed in.");
- return null;
- }
- }
-
- /**
- * Callback that's invoked when the Loader returned in onCreateLoader is finished
- * with its task. In this case, the game DB query is finished, so we should put the results
- * on screen.
- *
- * @param loader The loader that finished.
- * @param data The data the Loader loaded.
- */
- @Override
- public void onLoadFinished(Loader loader, Cursor data)
- {
- int id = loader.getId();
- Log.d("DolphinEmu", "Loader finished with id: " + id);
-
- PlatformGamesFragment fragment = null;
- switch (id)
- {
- case LOADER_ID_GAMECUBE:
- fragment = getPlatformFragment(Game.PLATFORM_GC);
- break;
-
- case LOADER_ID_WII:
- fragment = getPlatformFragment(Game.PLATFORM_WII);
- break;
-
- case LOADER_ID_WIIWARE:
- fragment = getPlatformFragment(Game.PLATFORM_WII_WARE);
- break;
-
- // TODO case LOADER_ID_ALL:
-
- default:
- Log.e("DolphinEmu", "Bad ID passed in.");
- break;
- }
-
- if (fragment != null)
- {
- fragment.onLoadFinished(loader, data);
- }
- }
-
- @Override
- public void onLoaderReset(Loader loader)
- {
- int id = loader.getId();
- Log.e("DolphinEmu", "Loader resetting with id: " + id);
-
- PlatformGamesFragment fragment = null;
- switch (id)
- {
- case LOADER_ID_GAMECUBE:
- fragment = getPlatformFragment(Game.PLATFORM_GC);
- break;
-
- case LOADER_ID_WII:
- fragment = getPlatformFragment(Game.PLATFORM_WII);
- break;
-
- case LOADER_ID_WIIWARE:
- fragment = getPlatformFragment(Game.PLATFORM_WII_WARE);
- break;
-
- // TODO case LOADER_ID_ALL:
-
- default:
- Log.e("DolphinEmu", "Bad ID passed in.");
- break;
- }
-
- if (fragment != null)
- {
- fragment.onLoaderReset();
- }
- }
-
@Nullable
public PlatformGamesFragment getPlatformFragment(int platform)
{
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
index c1d1b1c8e7..8fff63bbcd 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java
@@ -1,8 +1,6 @@
package org.dolphinemu.dolphinemu.fragments;
import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
@@ -15,8 +13,14 @@ import android.view.View;
import android.view.ViewGroup;
import org.dolphinemu.dolphinemu.BuildConfig;
+import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameAdapter;
+import org.dolphinemu.dolphinemu.model.GameDatabase;
+
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Action1;
+import rx.schedulers.Schedulers;
public class PlatformGamesFragment extends Fragment
{
@@ -69,9 +73,7 @@ public class PlatformGamesFragment extends Fragment
recyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8));
- // Create an adapter that will relate the dataset to the views on-screen. +1 because of LOADER_ID_ALL
- getLoaderManager().initLoader(mPlatform, null,
- (LoaderManager.LoaderCallbacks) getActivity());
+ loadGames();
mAdapter = new GameAdapter();
recyclerView.setAdapter(mAdapter);
@@ -87,32 +89,35 @@ public class PlatformGamesFragment extends Fragment
public void refresh()
{
Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Refreshing...");
- // +1 because of LOADER_ID_ALL
- getLoaderManager().restartLoader(mPlatform, null, (LoaderManager.LoaderCallbacks) getActivity());
+ loadGames();
}
- public void onLoadFinished(Loader loader, Cursor data)
+ public void loadGames()
{
- // TODO Play some sort of load-finished animation; maybe fade the list in.
+ Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Loading games...");
- Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Load finished, swapping cursor...");
- Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Cursor size: " + data.getCount());
- if (mAdapter != null)
- {
- mAdapter.swapCursor(data);
- }
- else
- {
- Log.e("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": No adapter available.");
- }
- }
+ GameDatabase databaseHelper = DolphinApplication.databaseHelper;
- public void onLoaderReset()
- {
- Log.e("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Loader reset; clearing data from view.");
- if (mAdapter != null)
- {
- mAdapter.swapCursor(null);
- }
+ databaseHelper.getGamesForPlatform(mPlatform)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(new Action1()
+ {
+ @Override
+ public void call(Cursor data)
+ {
+ Log.d("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": Load finished, swapping cursor...");
+
+ if (mAdapter != null)
+ {
+ mAdapter.swapCursor(data);
+ }
+ else
+ {
+ Log.e("DolphinEmu", "[PlatformGamesFragment] " + mPlatform + ": No adapter available.");
+ }
+ }
+ }
+ );
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameDatabase.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameDatabase.java
index 6aaee3ae16..ae674c921f 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameDatabase.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameDatabase.java
@@ -14,6 +14,9 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import rx.Observable;
+import rx.Subscriber;
+
/**
* A helper class that provides several utilities simplifying interaction with
* the SQLite database.
@@ -252,4 +255,44 @@ public final class GameDatabase extends SQLiteOpenHelper
folderCursor.close();
database.close();
}
+
+ public Observable getGamesForPlatform(final int platform)
+ {
+ return Observable.create(new Observable.OnSubscribe()
+ {
+ @Override
+ public void call(Subscriber super Cursor> subscriber)
+ {
+ Log.i("DolphinEmu", "[GameDatabase] Reading games list...");
+
+ String whereClause = null;
+ String[] whereArgs = null;
+
+ // If -1 passed in, return all games. Else, return games for one platform only.
+ if (platform >= 0)
+ {
+ whereClause = KEY_GAME_PLATFORM + " = ?";
+ whereArgs = new String[]{Integer.toString(platform)};
+ }
+
+ SQLiteDatabase database = getReadableDatabase();
+
+ Cursor resultCursor = database.query(
+ TABLE_NAME_GAMES,
+ null,
+ whereClause,
+ whereArgs,
+ null,
+ null,
+ KEY_GAME_TITLE + " ASC"
+ );
+
+ // Pass the result cursor to the consumer.
+ subscriber.onNext(resultCursor);
+
+ // Tell the consumer we're done; it will unsubscribe implicitly.
+ subscriber.onCompleted();
+ }
+ });
+ }
}