mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 23:59:27 +01:00
Merge pull request #12681 from nlebeck/taskviewmodel-refactor
Refactor `TaskViewModel` to track task-related state in a single `MutableLiveData` instance
This commit is contained in:
commit
3a0720dd1f
@ -102,10 +102,7 @@ class UserDataActivity : AppCompatActivity() {
|
|||||||
dialog.show(supportFragmentManager, UserDataImportWarningDialog.TAG)
|
dialog.show(supportFragmentManager, UserDataImportWarningDialog.TAG)
|
||||||
} else if (requestCode == REQUEST_CODE_EXPORT && resultCode == RESULT_OK) {
|
} else if (requestCode == REQUEST_CODE_EXPORT && resultCode == RESULT_OK) {
|
||||||
taskViewModel.clear()
|
taskViewModel.clear()
|
||||||
taskViewModel.task = {
|
taskViewModel.task = { exportUserData(data!!.data!!) }
|
||||||
val resultResource = exportUserData(data!!.data!!)
|
|
||||||
taskViewModel.setResult(resultResource)
|
|
||||||
}
|
|
||||||
|
|
||||||
val arguments = Bundle()
|
val arguments = Bundle()
|
||||||
arguments.putInt(TaskDialog.KEY_TITLE, R.string.export_in_progress)
|
arguments.putInt(TaskDialog.KEY_TITLE, R.string.export_in_progress)
|
||||||
|
@ -34,14 +34,11 @@ class TaskDialog : DialogFragment() {
|
|||||||
val progressMessage = requireArguments().getInt(KEY_MESSAGE)
|
val progressMessage = requireArguments().getInt(KEY_MESSAGE)
|
||||||
if (progressMessage != 0) dialog.setMessage(resources.getString(progressMessage))
|
if (progressMessage != 0) dialog.setMessage(resources.getString(progressMessage))
|
||||||
|
|
||||||
viewModel.isComplete.observe(this) { complete: Boolean ->
|
viewModel.result.observe(this) { result: Int? ->
|
||||||
if (complete && viewModel.result.value != null) {
|
if (result != null) {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
val notificationArguments = Bundle()
|
val notificationArguments = Bundle()
|
||||||
notificationArguments.putInt(
|
notificationArguments.putInt(TaskCompleteDialog.KEY_MESSAGE, result)
|
||||||
TaskCompleteDialog.KEY_MESSAGE,
|
|
||||||
viewModel.result.value!!
|
|
||||||
)
|
|
||||||
|
|
||||||
val taskCompleteDialog = TaskCompleteDialog()
|
val taskCompleteDialog = TaskCompleteDialog()
|
||||||
taskCompleteDialog.arguments = notificationArguments
|
taskCompleteDialog.arguments = notificationArguments
|
||||||
|
@ -32,10 +32,8 @@ class UserDataImportWarningDialog : DialogFragment() {
|
|||||||
taskArguments.putBoolean(TaskDialog.KEY_CANCELLABLE, false)
|
taskArguments.putBoolean(TaskDialog.KEY_CANCELLABLE, false)
|
||||||
|
|
||||||
taskViewModel.task = {
|
taskViewModel.task = {
|
||||||
taskViewModel.setResult(
|
(requireActivity() as UserDataActivity).importUserData(
|
||||||
(requireActivity() as UserDataActivity).importUserData(
|
requireArguments().getString(KEY_URI_RESULT)!!.toUri()
|
||||||
requireArguments().getString(KEY_URI_RESULT)!!.toUri()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,23 +5,49 @@ package org.dolphinemu.dolphinemu.model
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.map
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [ViewModel] associated with a task that runs on [Dispatchers.IO] and yields an integer result.
|
||||||
|
*/
|
||||||
class TaskViewModel : ViewModel() {
|
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 cancelled = false
|
||||||
var mustRestartApp = false
|
var mustRestartApp = false
|
||||||
|
|
||||||
private val _result = MutableLiveData<Int>()
|
private val state = MutableLiveData<State>(NotStartedState())
|
||||||
val result: LiveData<Int> get() = _result
|
|
||||||
|
|
||||||
private val _isComplete = MutableLiveData<Boolean>()
|
/** Yields the result of [task] if it has completed or null otherwise. */
|
||||||
val isComplete: LiveData<Boolean> get() = _isComplete
|
val result: LiveData<Int?> get() = state.map {
|
||||||
|
state -> state.result()
|
||||||
|
}
|
||||||
|
|
||||||
private val _isRunning = MutableLiveData<Boolean>()
|
lateinit var task: () -> Int
|
||||||
val isRunning: LiveData<Boolean> get() = _isRunning
|
|
||||||
|
|
||||||
lateinit var task: () -> Unit
|
|
||||||
var onResultDismiss: (() -> Unit)? = null
|
var onResultDismiss: (() -> Unit)? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -29,28 +55,23 @@ class TaskViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
_result.value = 0
|
state.value = NotStartedState()
|
||||||
_isComplete.value = false
|
|
||||||
cancelled = false
|
cancelled = false
|
||||||
mustRestartApp = false
|
mustRestartApp = false
|
||||||
onResultDismiss = null
|
onResultDismiss = null
|
||||||
_isRunning.value = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runTask() {
|
fun runTask() {
|
||||||
if (isRunning.value == true) return
|
if (state.value!!.hasStarted()) {
|
||||||
_isRunning.value = true
|
return
|
||||||
|
}
|
||||||
|
state.value = RunningState()
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
task.invoke()
|
val result = task.invoke()
|
||||||
_isRunning.postValue(false)
|
state.postValue(CompletedState(result))
|
||||||
_isComplete.postValue(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setResult(result: Int) {
|
|
||||||
_result.postValue(result)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user