forked from suyu/suyu
android: Rework driver fragment
Applies settings upon selection and uses a new Driver model to represent the information in-view. Also switches from an async diff list to a plain one.
This commit is contained in:
parent
93239f191a
commit
6bfc3c530c
4 changed files with 86 additions and 112 deletions
|
@ -13,16 +13,16 @@ import androidx.core.view.WindowInsetsCompat
|
|||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.adapters.DriverAdapter
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentDriverManagerBinding
|
||||
import org.yuzu.yuzu_emu.model.Driver.Companion.toDriver
|
||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||
import org.yuzu.yuzu_emu.model.HomeViewModel
|
||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||
|
@ -85,25 +85,6 @@ class DriverManagerFragment : Fragment() {
|
|||
adapter = DriverAdapter(driverViewModel)
|
||||
}
|
||||
|
||||
viewLifecycleOwner.lifecycleScope.apply {
|
||||
launch {
|
||||
driverViewModel.driverList.collectLatest {
|
||||
(binding.listDrivers.adapter as DriverAdapter).submitList(it)
|
||||
}
|
||||
}
|
||||
launch {
|
||||
driverViewModel.newDriverInstalled.collect {
|
||||
if (_binding != null && it) {
|
||||
(binding.listDrivers.adapter as DriverAdapter).apply {
|
||||
notifyItemChanged(driverViewModel.previouslySelectedDriver)
|
||||
notifyItemChanged(driverViewModel.selectedDriver)
|
||||
driverViewModel.setNewDriverInstalled(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setInsets()
|
||||
}
|
||||
|
||||
|
@ -177,12 +158,20 @@ class DriverManagerFragment : Fragment() {
|
|||
|
||||
val driverData = GpuDriverHelper.getMetadataFromZip(driverFile)
|
||||
val driverInList =
|
||||
driverViewModel.driverList.value.firstOrNull { it.second == driverData }
|
||||
driverViewModel.driverData.firstOrNull { it.second == driverData }
|
||||
if (driverInList != null) {
|
||||
return@newInstance getString(R.string.driver_already_installed)
|
||||
} else {
|
||||
driverViewModel.addDriver(Pair(driverPath, driverData))
|
||||
driverViewModel.setNewDriverInstalled(true)
|
||||
driverViewModel.onDriverAdded(Pair(driverPath, driverData))
|
||||
withContext(Dispatchers.Main) {
|
||||
if (_binding != null) {
|
||||
val adapter = binding.listDrivers.adapter as DriverAdapter
|
||||
adapter.addItem(driverData.toDriver())
|
||||
adapter.selectItem(adapter.currentList.indices.last)
|
||||
binding.listDrivers
|
||||
.smoothScrollToPosition(adapter.currentList.indices.last)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@newInstance Any()
|
||||
}.show(childFragmentManager, IndeterminateProgressDialogFragment.TAG)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-FileCopyrightText: 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.model
|
||||
|
||||
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
||||
|
||||
data class Driver(
|
||||
override var selected: Boolean,
|
||||
val title: String,
|
||||
val version: String = "",
|
||||
val description: String = ""
|
||||
) : SelectableItem {
|
||||
override fun onSelectionStateChanged(selected: Boolean) {
|
||||
this.selected = selected
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun GpuDriverMetadata.toDriver(selected: Boolean = false): Driver =
|
||||
Driver(
|
||||
selected,
|
||||
this.name ?: "",
|
||||
this.version ?: "",
|
||||
this.description ?: ""
|
||||
)
|
||||
}
|
||||
}
|
|
@ -17,11 +17,10 @@ import org.yuzu.yuzu_emu.R
|
|||
import org.yuzu.yuzu_emu.YuzuApplication
|
||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||
import org.yuzu.yuzu_emu.model.Driver.Companion.toDriver
|
||||
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
|
||||
import org.yuzu.yuzu_emu.utils.GpuDriverMetadata
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
|
||||
class DriverViewModel : ViewModel() {
|
||||
|
@ -38,97 +37,74 @@ class DriverViewModel : ViewModel() {
|
|||
!loading && ready && !deleting
|
||||
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), initialValue = false)
|
||||
|
||||
private val _driverList = MutableStateFlow(GpuDriverHelper.getDrivers())
|
||||
val driverList: StateFlow<MutableList<Pair<String, GpuDriverMetadata>>> get() = _driverList
|
||||
var driverData = GpuDriverHelper.getDrivers()
|
||||
|
||||
var previouslySelectedDriver = 0
|
||||
var selectedDriver = -1
|
||||
private val _driverList = MutableStateFlow(emptyList<Driver>())
|
||||
val driverList: StateFlow<List<Driver>> get() = _driverList
|
||||
|
||||
// Used for showing which driver is currently installed within the driver manager card
|
||||
private val _selectedDriverTitle = MutableStateFlow("")
|
||||
val selectedDriverTitle: StateFlow<String> get() = _selectedDriverTitle
|
||||
|
||||
private val _newDriverInstalled = MutableStateFlow(false)
|
||||
val newDriverInstalled: StateFlow<Boolean> get() = _newDriverInstalled
|
||||
|
||||
val driversToDelete = mutableListOf<String>()
|
||||
private val driversToDelete = mutableListOf<String>()
|
||||
|
||||
init {
|
||||
val currentDriverMetadata = GpuDriverHelper.installedCustomDriverData
|
||||
findSelectedDriver(currentDriverMetadata)
|
||||
|
||||
// If a user had installed a driver before the manager was implemented, this zips
|
||||
// the installed driver to UserData/gpu_drivers/CustomDriver.zip so that it can
|
||||
// be indexed and exported as expected.
|
||||
if (selectedDriver == -1) {
|
||||
val driverToSave =
|
||||
File(GpuDriverHelper.driverStoragePath, "CustomDriver.zip")
|
||||
driverToSave.createNewFile()
|
||||
FileUtil.zipFromInternalStorage(
|
||||
File(GpuDriverHelper.driverInstallationPath!!),
|
||||
GpuDriverHelper.driverInstallationPath!!,
|
||||
BufferedOutputStream(driverToSave.outputStream())
|
||||
)
|
||||
_driverList.value.add(Pair(driverToSave.path, currentDriverMetadata))
|
||||
setSelectedDriverIndex(_driverList.value.size - 1)
|
||||
}
|
||||
|
||||
// If a user had installed a driver before the config was reworked to be multiplatform,
|
||||
// we have save the path of the previously selected driver to the new setting.
|
||||
if (StringSetting.DRIVER_PATH.getString(true).isEmpty() && selectedDriver > 0 &&
|
||||
StringSetting.DRIVER_PATH.global
|
||||
) {
|
||||
StringSetting.DRIVER_PATH.setString(_driverList.value[selectedDriver].first)
|
||||
NativeConfig.saveGlobalConfig()
|
||||
} else {
|
||||
findSelectedDriver(GpuDriverHelper.customDriverSettingData)
|
||||
}
|
||||
updateDriverList()
|
||||
updateDriverNameForGame(null)
|
||||
}
|
||||
|
||||
fun setSelectedDriverIndex(value: Int) {
|
||||
if (selectedDriver != -1) {
|
||||
previouslySelectedDriver = selectedDriver
|
||||
fun reloadDriverData() {
|
||||
_areDriversLoading.value = true
|
||||
driverData = GpuDriverHelper.getDrivers()
|
||||
updateDriverList()
|
||||
_areDriversLoading.value = false
|
||||
}
|
||||
|
||||
private fun updateDriverList() {
|
||||
val selectedDriver = GpuDriverHelper.customDriverSettingData
|
||||
val newDriverList = mutableListOf(
|
||||
Driver(
|
||||
selectedDriver == GpuDriverMetadata(),
|
||||
YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
||||
)
|
||||
)
|
||||
driverData.forEach {
|
||||
newDriverList.add(it.second.toDriver(it.second == selectedDriver))
|
||||
}
|
||||
selectedDriver = value
|
||||
}
|
||||
|
||||
fun setNewDriverInstalled(value: Boolean) {
|
||||
_newDriverInstalled.value = value
|
||||
}
|
||||
|
||||
fun addDriver(driverData: Pair<String, GpuDriverMetadata>) {
|
||||
val driverIndex = _driverList.value.indexOfFirst { it == driverData }
|
||||
if (driverIndex == -1) {
|
||||
_driverList.value.add(driverData)
|
||||
setSelectedDriverIndex(_driverList.value.size - 1)
|
||||
_selectedDriverTitle.value = driverData.second.name
|
||||
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
||||
} else {
|
||||
setSelectedDriverIndex(driverIndex)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeDriver(driverData: Pair<String, GpuDriverMetadata>) {
|
||||
_driverList.value.remove(driverData)
|
||||
_driverList.value = newDriverList
|
||||
}
|
||||
|
||||
fun onOpenDriverManager(game: Game?) {
|
||||
if (game != null) {
|
||||
SettingsFile.loadCustomConfig(game)
|
||||
}
|
||||
updateDriverList()
|
||||
}
|
||||
|
||||
val driverPath = StringSetting.DRIVER_PATH.getString()
|
||||
if (driverPath.isEmpty()) {
|
||||
setSelectedDriverIndex(0)
|
||||
fun onDriverSelected(position: Int) {
|
||||
if (position == 0) {
|
||||
StringSetting.DRIVER_PATH.setString("")
|
||||
} else {
|
||||
findSelectedDriver(GpuDriverHelper.getMetadataFromZip(File(driverPath)))
|
||||
StringSetting.DRIVER_PATH.setString(driverData[position - 1].first)
|
||||
}
|
||||
}
|
||||
|
||||
fun onDriverRemoved(removedPosition: Int, selectedPosition: Int) {
|
||||
driversToDelete.add(driverData[removedPosition - 1].first)
|
||||
driverData.removeAt(removedPosition - 1)
|
||||
onDriverSelected(selectedPosition)
|
||||
}
|
||||
|
||||
fun onDriverAdded(driver: Pair<String, GpuDriverMetadata>) {
|
||||
if (driversToDelete.contains(driver.first)) {
|
||||
driversToDelete.remove(driver.first)
|
||||
}
|
||||
driverData.add(driver)
|
||||
onDriverSelected(driverData.size)
|
||||
}
|
||||
|
||||
fun onCloseDriverManager(game: Game?) {
|
||||
_isDeletingDrivers.value = true
|
||||
StringSetting.DRIVER_PATH.setString(driverList.value[selectedDriver].first)
|
||||
updateDriverNameForGame(game)
|
||||
if (game == null) {
|
||||
NativeConfig.saveGlobalConfig()
|
||||
|
@ -181,20 +157,6 @@ class DriverViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun findSelectedDriver(currentDriverMetadata: GpuDriverMetadata) {
|
||||
if (driverList.value.size == 1) {
|
||||
setSelectedDriverIndex(0)
|
||||
return
|
||||
}
|
||||
|
||||
driverList.value.forEachIndexed { i: Int, driver: Pair<String, GpuDriverMetadata> ->
|
||||
if (driver.second == currentDriverMetadata) {
|
||||
setSelectedDriverIndex(i)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDriverNameForGame(game: Game?) {
|
||||
if (!GpuDriverHelper.supportsCustomDriverLoading()) {
|
||||
return
|
||||
|
@ -217,7 +179,6 @@ class DriverViewModel : ViewModel() {
|
|||
|
||||
private fun setDriverReady() {
|
||||
_isDriverReady.value = true
|
||||
_selectedDriverTitle.value = GpuDriverHelper.customDriverSettingData.name
|
||||
?: YuzuApplication.appContext.getString(R.string.system_gpu_driver)
|
||||
updateName()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,6 @@ object GpuDriverHelper {
|
|||
?.sortedByDescending { it: Pair<String, GpuDriverMetadata> -> it.second.name }
|
||||
?.distinct()
|
||||
?.toMutableList() ?: mutableListOf()
|
||||
|
||||
// TODO: Get system driver information
|
||||
drivers.add(0, Pair("", GpuDriverMetadata()))
|
||||
return drivers
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue