Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #10008 from JosJuice/android-remove-emulationstate
Android: Remove the EmulationState class
  • Loading branch information
leoetlino committed Sep 22, 2021
2 parents cc84799 + 53d7d59 commit 0d8ad5f
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 153 deletions.
Expand Up @@ -393,6 +393,8 @@ public static native void SetMotionSensorsEnabled(boolean accelerometerEnabled,

public static native void SurfaceDestroyed();

public static native boolean HasSurface();

/**
* Unpauses emulation from a paused state.
*/
Expand All @@ -408,13 +410,22 @@ public static native void SetMotionSensorsEnabled(boolean accelerometerEnabled,
*/
public static native void StopEmulation();

/**
* Ensures that IsRunning will return true from now on until emulation exits.
* (If this is not called, IsRunning will start returning true at some point
* after calling Run.)
*/
public static native void SetIsBooting();

/**
* Returns true if emulation is running (or is paused).
*/
public static native boolean IsRunning();

public static native boolean IsRunningAndStarted();

public static native boolean IsRunningAndUnpaused();

/**
* Enables or disables CPU block profiling
*
Expand Down
Expand Up @@ -32,7 +32,9 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C

private InputOverlay mInputOverlay;

private EmulationState mEmulationState;
private String[] mGamePaths;
private boolean mRunWhenSurfaceIsValid;
private boolean mLoadPreviousTemporaryState;

private EmulationActivity activity;

Expand Down Expand Up @@ -73,8 +75,7 @@ public void onCreate(Bundle savedInstanceState)
// So this fragment doesn't restart on configuration changes; i.e. rotation.
setRetainInstance(true);

String[] gamePaths = getArguments().getStringArray(KEY_GAMEPATHS);
mEmulationState = new EmulationState(gamePaths, getTemporaryStateFilePath());
mGamePaths = getArguments().getStringArray(KEY_GAMEPATHS);
}

/**
Expand Down Expand Up @@ -117,14 +118,18 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
public void onResume()
{
super.onResume();
mEmulationState.run(activity.isActivityRecreated());
run(activity.isActivityRecreated());
}

@Override
public void onPause()
{
if (mEmulationState.isRunning() && !NativeLibrary.IsShowingAlertMessage())
mEmulationState.pause();
if (NativeLibrary.IsRunningAndUnpaused() && !NativeLibrary.IsShowingAlertMessage())
{
Log.debug("[EmulationFragment] Pausing emulation.");
NativeLibrary.PauseEmulation();
}

super.onPause();
}

Expand Down Expand Up @@ -173,18 +178,25 @@ public void surfaceCreated(@NonNull SurfaceHolder holder)
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.debug("[EmulationFragment] Surface changed. Resolution: " + width + "x" + height);
mEmulationState.newSurface(holder.getSurface());
NativeLibrary.SurfaceChanged(holder.getSurface());
if (mRunWhenSurfaceIsValid)
{
runWithValidSurface();
}
}

@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder)
{
mEmulationState.clearSurface();
Log.debug("[EmulationFragment] Surface destroyed.");
NativeLibrary.SurfaceDestroyed();
mRunWhenSurfaceIsValid = true;
}

public void stopEmulation()
{
mEmulationState.stop();
Log.debug("[EmulationFragment] Stopping emulation.");
NativeLibrary.StopEmulation();
}

public void startConfiguringControls()
Expand All @@ -210,172 +222,69 @@ public boolean isConfiguringControls()
return mInputOverlay != null && mInputOverlay.isInEditMode();
}

private static class EmulationState
private void run(boolean isActivityRecreated)
{
private enum State
{
STOPPED, RUNNING, PAUSED
}

private final String[] mGamePaths;
private State state;
private Surface mSurface;
private boolean mRunWhenSurfaceIsValid;
private boolean loadPreviousTemporaryState;
private final String temporaryStatePath;

EmulationState(String[] gamePaths, String temporaryStatePath)
if (isActivityRecreated)
{
mGamePaths = gamePaths;
this.temporaryStatePath = temporaryStatePath;
// Starting state is stopped.
state = State.STOPPED;
}

// Getters for the current state

public synchronized boolean isStopped()
{
return state == State.STOPPED;
}

public synchronized boolean isPaused()
{
return state == State.PAUSED;
}

public synchronized boolean isRunning()
{
return state == State.RUNNING;
}

// State changing methods

public synchronized void stop()
{
if (state != State.STOPPED)
if (NativeLibrary.IsRunning())
{
Log.debug("[EmulationFragment] Stopping emulation.");
state = State.STOPPED;
NativeLibrary.StopEmulation();
mLoadPreviousTemporaryState = false;
deleteFile(getTemporaryStateFilePath());
}
else
{
Log.warning("[EmulationFragment] Stop called while already stopped.");
mLoadPreviousTemporaryState = true;
}
}

public synchronized void pause()
else
{
if (state != State.PAUSED)
{
state = State.PAUSED;
Log.debug("[EmulationFragment] Pausing emulation.");

NativeLibrary.PauseEmulation();
}
else
{
Log.warning("[EmulationFragment] Pause called while already paused.");
}
Log.debug("[EmulationFragment] activity resumed or fresh start");
mLoadPreviousTemporaryState = false;
// activity resumed without being killed or this is the first run
deleteFile(getTemporaryStateFilePath());
}

public synchronized void run(boolean isActivityRecreated)
// If the surface is set, run now. Otherwise, wait for it to get set.
if (NativeLibrary.HasSurface())
{
if (isActivityRecreated)
{
if (NativeLibrary.IsRunning())
{
loadPreviousTemporaryState = false;
state = State.PAUSED;
deleteFile(temporaryStatePath);
}
else
{
loadPreviousTemporaryState = true;
}
}
else
{
Log.debug("[EmulationFragment] activity resumed or fresh start");
loadPreviousTemporaryState = false;
// activity resumed without being killed or this is the first run
deleteFile(temporaryStatePath);
}

// If the surface is set, run now. Otherwise, wait for it to get set.
if (mSurface != null)
{
runWithValidSurface();
}
else
{
mRunWhenSurfaceIsValid = true;
}
runWithValidSurface();
}

// Surface callbacks
public synchronized void newSurface(Surface surface)
else
{
mSurface = surface;
if (mRunWhenSurfaceIsValid)
{
runWithValidSurface();
}
mRunWhenSurfaceIsValid = true;
}
}

public synchronized void clearSurface()
private void runWithValidSurface()
{
mRunWhenSurfaceIsValid = false;
if (!NativeLibrary.IsRunning())
{
if (mSurface == null)
{
Log.warning("[EmulationFragment] clearSurface called, but surface already null.");
}
else
{
mSurface = null;
Log.debug("[EmulationFragment] Surface destroyed.");
NativeLibrary.SetIsBooting();

NativeLibrary.SurfaceDestroyed();
}
}

private void runWithValidSurface()
{
mRunWhenSurfaceIsValid = false;
if (state == State.STOPPED)
Thread emulationThread = new Thread(() ->
{
Thread emulationThread = new Thread(() ->
if (mLoadPreviousTemporaryState)
{
NativeLibrary.SurfaceChanged(mSurface);
if (loadPreviousTemporaryState)
{
Log.debug("[EmulationFragment] Starting emulation thread from previous state.");
NativeLibrary.Run(mGamePaths, temporaryStatePath, true);
}
else
{
Log.debug("[EmulationFragment] Starting emulation thread.");
NativeLibrary.Run(mGamePaths);
}
EmulationActivity.stopIgnoringLaunchRequests();
}, "NativeEmulation");
emulationThread.start();
}
else if (state == State.PAUSED)
{
NativeLibrary.SurfaceChanged(mSurface);
if (!EmulationActivity.getHasUserPausedEmulation() &&
!NativeLibrary.IsShowingAlertMessage())
Log.debug("[EmulationFragment] Starting emulation thread from previous state.");
NativeLibrary.Run(mGamePaths, getTemporaryStateFilePath(), true);
}
else
{
Log.debug("[EmulationFragment] Resuming emulation.");
NativeLibrary.UnPauseEmulation();
Log.debug("[EmulationFragment] Starting emulation thread.");
NativeLibrary.Run(mGamePaths);
}
}
else
EmulationActivity.stopIgnoringLaunchRequests();
}, "NativeEmulation");
emulationThread.start();
}
else
{
if (!EmulationActivity.getHasUserPausedEmulation() && !NativeLibrary.IsShowingAlertMessage())
{
Log.debug("[EmulationFragment] Bug, run called while already running.");
Log.debug("[EmulationFragment] Resuming emulation.");
NativeLibrary.UnPauseEmulation();
}
state = State.RUNNING;
}
}

Expand Down

0 comments on commit 0d8ad5f

Please sign in to comment.