mirror of
https://github.com/rafaelvcaetano/melonDS-android.git
synced 2025-02-17 04:08:26 +00:00
Use safer runCatching alternative
This commit is contained in:
parent
a24a99f05c
commit
8ec196032a
@ -113,6 +113,7 @@ dependencies {
|
||||
with(Dependencies.Modules) {
|
||||
implementation(project(masterSwitchPreference))
|
||||
implementation(project(rcheevosApi))
|
||||
implementation(project(common))
|
||||
}
|
||||
|
||||
with(Dependencies.Kotlin) {
|
||||
|
@ -5,6 +5,7 @@ import android.net.Uri
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.magnum.melonds.MelonDSiNand
|
||||
import me.magnum.melonds.common.suspendRunCatching
|
||||
import me.magnum.melonds.domain.model.ConfigurationDirResult
|
||||
import me.magnum.melonds.domain.model.DSiWareTitle
|
||||
import me.magnum.melonds.domain.model.dsinand.ImportDSiWareTitleResult
|
||||
@ -69,7 +70,7 @@ class AndroidDSiNandManager(
|
||||
return@withContext ImportDSiWareTitleResult.NOT_DSIWARE_TITLE
|
||||
}
|
||||
|
||||
val tmdMetadataResult = runCatching {
|
||||
val tmdMetadataResult = suspendRunCatching {
|
||||
dsiWareMetadataRepository.getDSiWareTitleMetadata(categoryId, titleId)
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,9 @@ import androidx.work.NetworkType
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.OutOfQuotaPolicy
|
||||
import androidx.work.WorkManager
|
||||
import me.magnum.melonds.common.suspendMapCatching
|
||||
import me.magnum.melonds.common.suspendRecoverCatching
|
||||
import me.magnum.melonds.common.suspendRunCatching
|
||||
import me.magnum.melonds.common.workers.RetroAchievementsSubmissionWorker
|
||||
import me.magnum.melonds.database.daos.RAAchievementsDao
|
||||
import me.magnum.melonds.database.entities.retroachievements.RAGameEntity
|
||||
@ -111,7 +114,7 @@ class AndroidRetroAchievementsRepository(
|
||||
}
|
||||
|
||||
override suspend fun getAchievement(achievementId: Long): Result<RAAchievement?> {
|
||||
return runCatching {
|
||||
return suspendRunCatching {
|
||||
achievementsDao.getAchievement(achievementId)
|
||||
}.map {
|
||||
it?.mapToModel()
|
||||
@ -184,13 +187,13 @@ class AndroidRetroAchievementsRepository(
|
||||
.map {
|
||||
it[gameHash]
|
||||
}
|
||||
.recoverCatching {
|
||||
.suspendRecoverCatching {
|
||||
achievementsDao.getGameHashEntity(gameHash)?.let {
|
||||
RAGameId(it.gameId)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
runCatching {
|
||||
suspendRunCatching {
|
||||
achievementsDao.getGameHashEntity(gameHash)?.let {
|
||||
RAGameId(it.gameId)
|
||||
}
|
||||
@ -200,7 +203,7 @@ class AndroidRetroAchievementsRepository(
|
||||
|
||||
private suspend fun fetchGameAchievements(gameId: RAGameId, gameSetMetadata: CurrentGameSetMetadata): Result<List<RAAchievement>> {
|
||||
return if (mustRefreshAchievementSet(gameSetMetadata.currentMetadata)) {
|
||||
raApi.getGameInfo(gameId).mapCatching { game ->
|
||||
raApi.getGameInfo(gameId).suspendMapCatching { game ->
|
||||
val achievementEntities = game.achievements.map {
|
||||
it.mapToEntity()
|
||||
}
|
||||
@ -210,7 +213,7 @@ class AndroidRetroAchievementsRepository(
|
||||
achievementsDao.updateGameData(gameEntity, achievementEntities)
|
||||
achievementsDao.updateGameSetMetadata(newMetadata)
|
||||
game.achievements
|
||||
}.recoverCatching { exception ->
|
||||
}.suspendRecoverCatching { exception ->
|
||||
if (gameSetMetadata.isGameAchievementDataKnown()) {
|
||||
// Load DB data because we know that it was previously loaded
|
||||
achievementsDao.getGameAchievements(gameId.id).map { it ->
|
||||
@ -222,7 +225,7 @@ class AndroidRetroAchievementsRepository(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
runCatching {
|
||||
suspendRunCatching {
|
||||
achievementsDao.getGameAchievements(gameId.id).map {
|
||||
it.mapToModel()
|
||||
}
|
||||
@ -247,7 +250,7 @@ class AndroidRetroAchievementsRepository(
|
||||
val newMetadata = gameSetMetadata.withNewUserAchievementsUpdate(forHardcoreMode)
|
||||
achievementsDao.updateGameUserUnlockedAchievements(gameId.id, userAchievementEntities)
|
||||
achievementsDao.updateGameSetMetadata(newMetadata)
|
||||
}.recoverCatching { exception ->
|
||||
}.suspendRecoverCatching { exception ->
|
||||
if (gameSetMetadata.isUserAchievementDataKnown(forHardcoreMode)) {
|
||||
// Load DB data because we know that it was previously loaded
|
||||
achievementsDao.getGameUserUnlockedAchievements(gameId.id, forHardcoreMode).map {
|
||||
@ -259,7 +262,7 @@ class AndroidRetroAchievementsRepository(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
runCatching {
|
||||
suspendRunCatching {
|
||||
achievementsDao.getGameUserUnlockedAchievements(gameId.id, forHardcoreMode).map {
|
||||
it.achievementId
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.rx2.await
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.magnum.melonds.MelonEmulator
|
||||
@ -57,7 +58,7 @@ class AndroidEmulatorManager(
|
||||
}
|
||||
|
||||
val loadResult = MelonEmulator.loadRom(romUri, sram, rom.config.mustLoadGbaCart(), rom.config.gbaCartPath, rom.config.gbaSavePath)
|
||||
if (loadResult.isTerminal) {
|
||||
if (loadResult.isTerminal || !isActive) {
|
||||
cameraManager.stopCurrentCameraSource()
|
||||
RomLaunchResult.LaunchFailed(loadResult)
|
||||
} else {
|
||||
|
@ -20,7 +20,7 @@ object Dependencies {
|
||||
const val Hilt = "2.47"
|
||||
const val Junit = "4.12"
|
||||
const val Kotlin = "1.9.0"
|
||||
const val KotlinxCoroutinesRx = "1.6.4"
|
||||
const val KotlinxCoroutines = "1.7.3"
|
||||
const val Ksp = "1.9.0-1.0.12"
|
||||
const val LifecycleViewModel = "2.6.1"
|
||||
const val Material = "1.7.0"
|
||||
@ -52,6 +52,7 @@ object Dependencies {
|
||||
|
||||
object Kotlin {
|
||||
const val kotlinStdlib = "org.jetbrains.kotlin:kotlin-stdlib:${Versions.Kotlin}"
|
||||
const val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.KotlinxCoroutines}"
|
||||
}
|
||||
|
||||
object AndroidX {
|
||||
@ -96,7 +97,7 @@ object Dependencies {
|
||||
const val flexbox = "com.google.android.flexbox:flexbox:${Versions.Flexbox}"
|
||||
const val gson = "com.google.code.gson:gson:${Versions.Gson}"
|
||||
const val hilt = "com.google.dagger:hilt-android:${Versions.Hilt}"
|
||||
const val kotlinxCoroutinesRx = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:${Versions.KotlinxCoroutinesRx}"
|
||||
const val kotlinxCoroutinesRx = "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:${Versions.KotlinxCoroutines}"
|
||||
const val picasso = "com.squareup.picasso:picasso:${Versions.Picasso}"
|
||||
const val markwon = "io.noties.markwon:core:${Versions.Markwon}"
|
||||
const val markwonImagePicasso = "io.noties.markwon:image-picasso:${Versions.Markwon}"
|
||||
@ -123,6 +124,7 @@ object Dependencies {
|
||||
object Modules {
|
||||
const val masterSwitchPreference = ":masterswitch"
|
||||
const val rcheevosApi = ":rcheevos-api"
|
||||
const val common = ":common"
|
||||
}
|
||||
|
||||
object Testing {
|
||||
|
1
common/.gitignore
vendored
Normal file
1
common/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
13
common/build.gradle.kts
Normal file
13
common/build.gradle.kts
Normal file
@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
with(Dependencies.Kotlin) {
|
||||
implementation(coroutines)
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package me.magnum.melonds.common
|
||||
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
suspend inline fun <R> suspendRunCatching(block: () -> R): Result<R> {
|
||||
return try {
|
||||
Result.success(block())
|
||||
} catch (e: Throwable) {
|
||||
coroutineContext.ensureActive()
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend inline fun <R, T : R> Result<T>.suspendRecoverCatching(transform: (exception: Throwable) -> R): Result<R> {
|
||||
return when (val exception = exceptionOrNull()) {
|
||||
null -> this
|
||||
else -> suspendRunCatching { transform(exception) }
|
||||
}
|
||||
}
|
||||
|
||||
suspend inline fun <R, T> Result<T>.suspendMapCatching(transform: (value: T) -> R): Result<R> {
|
||||
return when {
|
||||
isSuccess -> suspendRunCatching { transform(getOrThrow()) }
|
||||
else -> Result.failure(exceptionOrNull()!!)
|
||||
}
|
||||
}
|
@ -7,6 +7,10 @@ kotlin {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
with(Dependencies.Modules) {
|
||||
implementation(project(common))
|
||||
}
|
||||
|
||||
with(Dependencies.ThirdParty) {
|
||||
implementation(gson)
|
||||
implementation(okHttp)
|
||||
|
@ -2,6 +2,8 @@ package me.magnum.rcheevosapi
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonParser
|
||||
import me.magnum.melonds.common.suspendMapCatching
|
||||
import me.magnum.melonds.common.suspendRunCatching
|
||||
import me.magnum.rcheevosapi.dto.*
|
||||
import me.magnum.rcheevosapi.dto.mapper.mapToModel
|
||||
import me.magnum.rcheevosapi.exception.UnsuccessfulRequestException
|
||||
@ -104,7 +106,7 @@ class RAApi(
|
||||
PARAMETER_TOKEN to userAuth.token,
|
||||
PARAMETER_GAME_ID to gameId.id.toString(),
|
||||
)
|
||||
).mapCatching {
|
||||
).suspendMapCatching {
|
||||
it.game.mapToModel()
|
||||
}
|
||||
}
|
||||
@ -171,9 +173,9 @@ class RAApi(
|
||||
errorHandler: (String?) -> Unit = { throw UnsuccessfulRequestException(it ?: "Unknown reason") }
|
||||
): Result<T> {
|
||||
val request = buildGetRequest(parameters)
|
||||
return runCatching {
|
||||
return suspendRunCatching {
|
||||
executeRequest(request)
|
||||
}.mapCatching { response ->
|
||||
}.suspendMapCatching { response ->
|
||||
if (response.isSuccessful) {
|
||||
val json = JsonParser.parseReader(response.body?.charStream())
|
||||
val isSuccessful = json.asJsonObject["Success"].asBoolean
|
||||
@ -201,9 +203,9 @@ class RAApi(
|
||||
errorHandler: (String?) -> Unit = { throw UnsuccessfulRequestException(it ?: "Unknown reason") }
|
||||
): Result<T> {
|
||||
val request = buildPostRequest(parameters)
|
||||
return runCatching {
|
||||
return suspendRunCatching {
|
||||
executeRequest(request)
|
||||
}.mapCatching { response ->
|
||||
}.suspendMapCatching { response ->
|
||||
if (response.isSuccessful) {
|
||||
val json = JsonParser.parseReader(response.body?.charStream())
|
||||
val isSuccessful = json.asJsonObject["Success"].asBoolean
|
||||
|
@ -1 +1 @@
|
||||
include ':app', ':masterswitch', ':rcheevos-api'
|
||||
include ':app', ':masterswitch', ':rcheevos-api', ':common'
|
||||
|
Loading…
x
Reference in New Issue
Block a user