diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt index 3813427f269e..9435ead4f4b4 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.kt @@ -102,10 +102,7 @@ class UserDataActivity : AppCompatActivity() { dialog.show(supportFragmentManager, UserDataImportWarningDialog.TAG) } else if (requestCode == REQUEST_CODE_EXPORT && resultCode == RESULT_OK) { taskViewModel.clear() - taskViewModel.task = { - val resultResource = exportUserData(data!!.data!!) - taskViewModel.setResult(resultResource) - } + taskViewModel.task = { exportUserData(data!!.data!!) } val arguments = Bundle() arguments.putInt(TaskDialog.KEY_TITLE, R.string.export_in_progress) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/TaskDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/TaskDialog.kt index f28ff70884bf..4fa262e2f3c2 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/TaskDialog.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/TaskDialog.kt @@ -34,14 +34,11 @@ class TaskDialog : DialogFragment() { val progressMessage = requireArguments().getInt(KEY_MESSAGE) if (progressMessage != 0) dialog.setMessage(resources.getString(progressMessage)) - viewModel.isComplete.observe(this) { complete: Boolean -> - if (complete && viewModel.result.value != null) { + viewModel.result.observe(this) { result: Int? -> + if (result != null) { dialog.dismiss() val notificationArguments = Bundle() - notificationArguments.putInt( - TaskCompleteDialog.KEY_MESSAGE, - viewModel.result.value!! - ) + notificationArguments.putInt(TaskCompleteDialog.KEY_MESSAGE, result) val taskCompleteDialog = TaskCompleteDialog() taskCompleteDialog.arguments = notificationArguments diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/UserDataImportWarningDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/UserDataImportWarningDialog.kt index 4ae469bb17e0..0648b7075ac2 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/UserDataImportWarningDialog.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/UserDataImportWarningDialog.kt @@ -32,10 +32,8 @@ class UserDataImportWarningDialog : DialogFragment() { taskArguments.putBoolean(TaskDialog.KEY_CANCELLABLE, false) taskViewModel.task = { - taskViewModel.setResult( - (requireActivity() as UserDataActivity).importUserData( - requireArguments().getString(KEY_URI_RESULT)!!.toUri() - ) + (requireActivity() as UserDataActivity).importUserData( + requireArguments().getString(KEY_URI_RESULT)!!.toUri() ) } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TaskViewModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TaskViewModel.kt index 084ee0d512bb..2ebc641b83b1 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TaskViewModel.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TaskViewModel.kt @@ -5,23 +5,49 @@ package org.dolphinemu.dolphinemu.model import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.map import androidx.lifecycle.viewModelScope import kotlinx.coroutines.* +/** + * A [ViewModel] associated with a task that runs on [Dispatchers.IO] and yields an integer result. + */ class TaskViewModel : ViewModel() { + /** Represents the execution state of the task associated with this [TaskViewModel]. */ + private interface State { + /** Returns true if the task has started running and false otherwise. */ + fun hasStarted() : Boolean + + /** Returns the task's result if it has completed or null otherwise. */ + fun result() : Int? + } + + private class NotStartedState : State { + override fun hasStarted() : Boolean { return false; } + override fun result() : Int? { return null; } + } + + private class RunningState : State { + override fun hasStarted() : Boolean { return true; } + override fun result() : Int? { return null; } + } + + private class CompletedState(private val result: Int) : State { + override fun hasStarted() : Boolean { return true; } + override fun result() : Int { return result; } + } + var cancelled = false var mustRestartApp = false - private val _result = MutableLiveData() - val result: LiveData get() = _result + private val state = MutableLiveData(NotStartedState()) - private val _isComplete = MutableLiveData() - val isComplete: LiveData get() = _isComplete - - private val _isRunning = MutableLiveData() - val isRunning: LiveData get() = _isRunning + /** Yields the result of [task] if it has completed or null otherwise. */ + val result: LiveData get() = state.map { + state -> state.result() + } - lateinit var task: () -> Unit + lateinit var task: () -> Int var onResultDismiss: (() -> Unit)? = null init { @@ -29,28 +55,23 @@ class TaskViewModel : ViewModel() { } fun clear() { - _result.value = 0 - _isComplete.value = false + state.value = NotStartedState() cancelled = false mustRestartApp = false onResultDismiss = null - _isRunning.value = false } fun runTask() { - if (isRunning.value == true) return - _isRunning.value = true + if (state.value!!.hasStarted()) { + return + } + state.value = RunningState() viewModelScope.launch { withContext(Dispatchers.IO) { - task.invoke() - _isRunning.postValue(false) - _isComplete.postValue(true) + val result = task.invoke() + state.postValue(CompletedState(result)) } } } - - fun setResult(result: Int) { - _result.postValue(result) - } }