android: Remove LocalBroadcastManager
This causes a couple of minor changes to directory initialization. We don't have a lengthy initialization step so we could spend less time creating state receivers and just run initialization on the main thread. We also don't have a situation where external storage will be a concern so checks are removed in favor of a binary check to see if initialization is ready. This additionally removes the unused DoFrame callback.
This commit is contained in:
parent
9d7a60346f
commit
a827486391
|
@ -142,7 +142,6 @@ dependencies {
|
|||
implementation 'androidx.window:window:1.0.0'
|
||||
implementation 'org.ini4j:ini4j:0.5.4'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
}
|
||||
|
||||
|
|
|
@ -218,8 +218,6 @@ public final class NativeLibrary {
|
|||
|
||||
public static native void SurfaceDestroyed();
|
||||
|
||||
public static native void DoFrame();
|
||||
|
||||
/**
|
||||
* Unpauses emulation from a paused state.
|
||||
*/
|
||||
|
|
|
@ -5,31 +5,25 @@ package org.yuzu.yuzu_emu.features.settings.ui
|
|||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding
|
||||
import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel
|
||||
import org.yuzu.yuzu_emu.utils.*
|
||||
|
||||
class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||
private val presenter = SettingsActivityPresenter(this)
|
||||
private var dialog: AlertDialog? = null
|
||||
|
||||
private lateinit var binding: ActivitySettingsBinding
|
||||
|
||||
|
@ -134,47 +128,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
|||
return duration != 0f && transition != 0f
|
||||
}
|
||||
|
||||
override fun startDirectoryInitializationService(
|
||||
receiver: DirectoryStateReceiver?,
|
||||
filter: IntentFilter
|
||||
) {
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(
|
||||
receiver!!,
|
||||
filter
|
||||
)
|
||||
DirectoryInitialization.start(this)
|
||||
}
|
||||
|
||||
override fun stopListeningToDirectoryInitializationService(receiver: DirectoryStateReceiver) {
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
|
||||
}
|
||||
|
||||
override fun showLoading() {
|
||||
if (dialog == null) {
|
||||
val loadingBinding = DialogProgressBarBinding.inflate(layoutInflater)
|
||||
loadingBinding.progressBar.isIndeterminate = true
|
||||
|
||||
dialog = MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.load_settings)
|
||||
.setView(loadingBinding.root)
|
||||
.setCancelable(false)
|
||||
.create()
|
||||
}
|
||||
dialog!!.show()
|
||||
}
|
||||
|
||||
override fun hideLoading() {
|
||||
dialog!!.dismiss()
|
||||
}
|
||||
|
||||
override fun showExternalStorageNotMountedHint() {
|
||||
Toast.makeText(
|
||||
this,
|
||||
R.string.external_storage_not_mounted,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onSettingsFileLoaded() {
|
||||
val fragment: SettingsFragmentView? = settingsFragment
|
||||
fragment?.loadSettingsList()
|
||||
|
|
|
@ -3,15 +3,13 @@
|
|||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui
|
||||
|
||||
import android.content.IntentFilter
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver
|
||||
import org.yuzu.yuzu_emu.utils.Log
|
||||
import java.io.File
|
||||
|
||||
|
@ -19,7 +17,6 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView)
|
|||
val settings: Settings get() = activityView.settings
|
||||
|
||||
private var shouldSave = false
|
||||
private var directoryStateReceiver: DirectoryStateReceiver? = null
|
||||
private lateinit var menuTag: String
|
||||
private lateinit var gameId: String
|
||||
|
||||
|
@ -54,33 +51,14 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView)
|
|||
Log.error(DirectoryInitialization.userDirectory + "/config/" + SettingsFile.FILE_NAME_CONFIG + ".ini")
|
||||
Log.error("yuzu config file could not be found!")
|
||||
}
|
||||
if (DirectoryInitialization.areDirectoriesReady()) {
|
||||
loadSettingsUI()
|
||||
} else {
|
||||
activityView.showLoading()
|
||||
val statusIntentFilter = IntentFilter(DirectoryInitialization.BROADCAST_ACTION)
|
||||
directoryStateReceiver =
|
||||
DirectoryStateReceiver { directoryInitializationState: DirectoryInitializationState ->
|
||||
if (directoryInitializationState == DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED) {
|
||||
activityView.hideLoading()
|
||||
loadSettingsUI()
|
||||
} else if (directoryInitializationState == DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE) {
|
||||
activityView.showExternalStorageNotMountedHint()
|
||||
activityView.hideLoading()
|
||||
}
|
||||
}
|
||||
activityView.startDirectoryInitializationService(
|
||||
directoryStateReceiver,
|
||||
statusIntentFilter
|
||||
)
|
||||
|
||||
if (!DirectoryInitialization.areDirectoriesReady) {
|
||||
DirectoryInitialization.start(activityView as Context)
|
||||
}
|
||||
loadSettingsUI()
|
||||
}
|
||||
|
||||
fun onStop(finishing: Boolean) {
|
||||
if (directoryStateReceiver != null) {
|
||||
activityView.stopListeningToDirectoryInitializationService(directoryStateReceiver!!)
|
||||
directoryStateReceiver = null
|
||||
}
|
||||
if (finishing && shouldSave) {
|
||||
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...")
|
||||
settings.saveSettings(activityView)
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui
|
||||
|
||||
import android.content.IntentFilter
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver
|
||||
|
||||
/**
|
||||
* Abstraction for the Activity that manages SettingsFragments.
|
||||
|
@ -56,37 +54,4 @@ interface SettingsActivityView {
|
|||
* unless this has been called, the Activity will not save to disk.
|
||||
*/
|
||||
fun onSettingChanged()
|
||||
|
||||
/**
|
||||
* Show loading dialog while loading the settings
|
||||
*/
|
||||
fun showLoading()
|
||||
|
||||
/**
|
||||
* Hide the loading the dialog
|
||||
*/
|
||||
fun hideLoading()
|
||||
|
||||
/**
|
||||
* Show a hint to the user that the app needs the external storage to be mounted
|
||||
*/
|
||||
fun showExternalStorageNotMountedHint()
|
||||
|
||||
/**
|
||||
* Start the DirectoryInitialization and listen for the result.
|
||||
*
|
||||
* @param receiver the broadcast receiver for the DirectoryInitialization
|
||||
* @param filter the Intent broadcasts to be received.
|
||||
*/
|
||||
fun startDirectoryInitializationService(
|
||||
receiver: DirectoryStateReceiver?,
|
||||
filter: IntentFilter
|
||||
)
|
||||
|
||||
/**
|
||||
* Stop listening to the DirectoryInitialization.
|
||||
*
|
||||
* @param receiver The broadcast receiver to unregister.
|
||||
*/
|
||||
fun stopListeningToDirectoryInitializationService(receiver: DirectoryStateReceiver)
|
||||
}
|
||||
|
|
|
@ -4,14 +4,13 @@
|
|||
package org.yuzu.yuzu_emu.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.*
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
|
@ -19,7 +18,6 @@ import androidx.core.graphics.Insets
|
|||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
|
@ -32,13 +30,11 @@ import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
|
|||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
import org.yuzu.yuzu_emu.model.Game
|
||||
import org.yuzu.yuzu_emu.utils.*
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState
|
||||
import org.yuzu.yuzu_emu.utils.SerializableHelper.parcelable
|
||||
|
||||
class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback {
|
||||
class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
private lateinit var preferences: SharedPreferences
|
||||
private lateinit var emulationState: EmulationState
|
||||
private var directoryStateReceiver: DirectoryStateReceiver? = null
|
||||
private var emulationActivity: EmulationActivity? = null
|
||||
private var perfStatsUpdater: (() -> Unit)? = null
|
||||
|
||||
|
@ -144,25 +140,16 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
Choreographer.getInstance().postFrameCallback(this)
|
||||
if (DirectoryInitialization.areDirectoriesReady()) {
|
||||
emulationState.run(emulationActivity!!.isActivityRecreated)
|
||||
} else {
|
||||
setupDirectoriesThenStartEmulation()
|
||||
if (!DirectoryInitialization.areDirectoriesReady) {
|
||||
DirectoryInitialization.start(requireContext())
|
||||
}
|
||||
emulationState.run(emulationActivity!!.isActivityRecreated)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
if (directoryStateReceiver != null) {
|
||||
LocalBroadcastManager.getInstance(requireActivity()).unregisterReceiver(
|
||||
directoryStateReceiver!!
|
||||
)
|
||||
directoryStateReceiver = null
|
||||
}
|
||||
if (emulationState.isRunning) {
|
||||
emulationState.pause()
|
||||
}
|
||||
Choreographer.getInstance().removeFrameCallback(this)
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
|
@ -176,36 +163,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
super.onDetach()
|
||||
}
|
||||
|
||||
private fun setupDirectoriesThenStartEmulation() {
|
||||
val statusIntentFilter = IntentFilter(
|
||||
DirectoryInitialization.BROADCAST_ACTION
|
||||
)
|
||||
directoryStateReceiver =
|
||||
DirectoryStateReceiver { directoryInitializationState: DirectoryInitializationState ->
|
||||
if (directoryInitializationState ==
|
||||
DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED
|
||||
) {
|
||||
emulationState.run(emulationActivity!!.isActivityRecreated)
|
||||
} else if (directoryInitializationState ==
|
||||
DirectoryInitializationState.CANT_FIND_EXTERNAL_STORAGE
|
||||
) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
R.string.external_storage_not_mounted,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
// Registers the DirectoryStateReceiver and its intent filters
|
||||
LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(
|
||||
directoryStateReceiver!!,
|
||||
statusIntentFilter
|
||||
)
|
||||
DirectoryInitialization.start(requireContext())
|
||||
}
|
||||
|
||||
fun refreshInputOverlay() {
|
||||
binding.surfaceInputOverlay.refreshControls()
|
||||
}
|
||||
|
@ -259,11 +216,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
emulationState.clearSurface()
|
||||
}
|
||||
|
||||
override fun doFrame(frameTimeNanos: Long) {
|
||||
Choreographer.getInstance().postFrameCallback(this)
|
||||
NativeLibrary.DoFrame()
|
||||
}
|
||||
|
||||
private fun showOverlayOptions() {
|
||||
val anchor = binding.inGameMenu.findViewById<View>(R.id.menu_overlay_controls)
|
||||
val popup = PopupMenu(requireContext(), anchor)
|
||||
|
@ -474,7 +426,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||
}
|
||||
|
||||
companion object {
|
||||
private val perfStatsUpdateHandler = Handler()
|
||||
private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!)
|
||||
|
||||
fun newInstance(game: Game): EmulationFragment {
|
||||
val args = Bundle()
|
||||
|
|
|
@ -41,7 +41,7 @@ class MainActivity : AppCompatActivity(), MainView {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val splashScreen = installSplashScreen()
|
||||
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady() }
|
||||
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
|
||||
|
||||
ThemeHelper.setTheme(this)
|
||||
|
||||
|
|
|
@ -4,46 +4,26 @@
|
|||
package org.yuzu.yuzu_emu.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
object DirectoryInitialization {
|
||||
const val BROADCAST_ACTION = "org.yuzu.yuzu_emu.BROADCAST"
|
||||
const val EXTRA_STATE = "directoryState"
|
||||
|
||||
@Volatile
|
||||
private var directoryState: DirectoryInitializationState? = null
|
||||
private var userPath: String? = null
|
||||
private val isDirectoryInitializationRunning = AtomicBoolean(false)
|
||||
|
||||
var areDirectoriesReady: Boolean = false
|
||||
|
||||
@JvmStatic
|
||||
fun start(context: Context) {
|
||||
// Can take a few seconds to run, so don't block UI thread.
|
||||
Runnable { init(context) }.run()
|
||||
}
|
||||
|
||||
private fun init(context: Context) {
|
||||
if (!isDirectoryInitializationRunning.compareAndSet(false, true)) return
|
||||
if (directoryState != DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED) {
|
||||
if (!areDirectoriesReady) {
|
||||
initializeInternalStorage(context)
|
||||
NativeLibrary.InitializeEmulation()
|
||||
directoryState = DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED
|
||||
areDirectoriesReady = true
|
||||
}
|
||||
isDirectoryInitializationRunning.set(false)
|
||||
sendBroadcastState(directoryState, context)
|
||||
}
|
||||
|
||||
fun areDirectoriesReady(): Boolean {
|
||||
return directoryState == DirectoryInitializationState.YUZU_DIRECTORIES_INITIALIZED
|
||||
}
|
||||
|
||||
val userDirectory: String?
|
||||
get() {
|
||||
checkNotNull(directoryState) { "DirectoryInitialization has to run at least once!" }
|
||||
check(!isDirectoryInitializationRunning.get()) { "DirectoryInitialization has to finish running first!" }
|
||||
check(areDirectoriesReady) { "Directory initialization is not ready!" }
|
||||
return userPath
|
||||
}
|
||||
|
||||
|
@ -55,15 +35,4 @@ object DirectoryInitialization {
|
|||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendBroadcastState(state: DirectoryInitializationState?, context: Context) {
|
||||
val localIntent = Intent(BROADCAST_ACTION)
|
||||
.putExtra(EXTRA_STATE, state)
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(localIntent)
|
||||
}
|
||||
|
||||
enum class DirectoryInitializationState {
|
||||
YUZU_DIRECTORIES_INITIALIZED,
|
||||
CANT_FIND_EXTERNAL_STORAGE
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.utils
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState
|
||||
|
||||
class DirectoryStateReceiver(var callback: (DirectoryInitializationState) -> Unit) :
|
||||
BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val state = intent
|
||||
.getSerializableExtra(DirectoryInitialization.EXTRA_STATE) as DirectoryInitializationState
|
||||
callback.invoke(state)
|
||||
}
|
||||
}
|
|
@ -367,8 +367,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
|
|||
EmulationSession::GetInstance().SurfaceChanged();
|
||||
}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_DoFrame(JNIEnv* env, [[maybe_unused]] jclass clazz) {}
|
||||
|
||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_NotifyOrientationChange(JNIEnv* env,
|
||||
[[maybe_unused]] jclass clazz,
|
||||
jint layout_option,
|
||||
|
|
|
@ -98,8 +98,6 @@
|
|||
|
||||
<string name="load_settings">Loading Settings…</string>
|
||||
|
||||
<string name="external_storage_not_mounted">The external storage needs to be available in order to use yuzu</string>
|
||||
|
||||
<string name="empty_gamelist">No files were found or no game directory has been selected yet.</string>
|
||||
|
||||
<!-- Software keyboard -->
|
||||
|
|
Reference in New Issue