Load old games

This commit is contained in:
Lucas Lima 2020-04-03 19:00:24 -03:00 committed by Lucas Lima
parent 40ae21102f
commit 18f0f498e1
7 changed files with 87 additions and 38 deletions

View file

@ -81,6 +81,10 @@
<data
android:host="new-game"
android:scheme="antimine" />
<data
android:host="load-game"
android:scheme="antimine" />
</intent-filter>
<intent-filter

View file

@ -1,17 +1,17 @@
package dev.lucasnlm.antimine.history.views
import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.database.models.Save
import dev.lucasnlm.antimine.common.level.models.Difficulty
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import java.text.DateFormat
class HistoryAdapter(
private val saveHistory: List<Save>,
private val gameViewModel: GameViewModel
private val saveHistory: List<Save>
) : RecyclerView.Adapter<HistoryViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryViewHolder {
val view = LayoutInflater
@ -36,7 +36,11 @@ class HistoryAdapter(
holder.date.text = DateFormat.getDateInstance().format(startDate)
holder.itemView.setOnClickListener {
gameViewModel.resumeGameFromSave(this)
val intent = Intent(Intent.ACTION_VIEW).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
data = Uri.parse("antimine://load-game/$uid")
}
it.context.startActivity(intent)
}
}
}

View file

@ -11,8 +11,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import dagger.android.support.DaggerFragment
import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.repository.ISavesRepository
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModel
import dev.lucasnlm.antimine.common.level.viewmodel.GameViewModelFactory
import dev.lucasnlm.antimine.history.viewmodel.HistoryViewModel
import kotlinx.android.synthetic.main.fragment_history.*
import kotlinx.coroutines.GlobalScope
@ -23,11 +21,7 @@ class HistoryFragment : DaggerFragment() {
@Inject
lateinit var savesRepository: ISavesRepository
@Inject
lateinit var viewModelFactory: GameViewModelFactory
private var historyViewModel: HistoryViewModel? = null
private lateinit var gameViewModel: GameViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -35,8 +29,6 @@ class HistoryFragment : DaggerFragment() {
historyViewModel = ViewModelProviders.of(this).get(HistoryViewModel::class.java)
}
gameViewModel = ViewModelProviders.of(this, viewModelFactory).get(GameViewModel::class.java)
GlobalScope.launch {
historyViewModel?.loadAllSaves(savesRepository)
}
@ -59,7 +51,7 @@ class HistoryFragment : DaggerFragment() {
layoutManager = LinearLayoutManager(view.context)
historyViewModel?.saves?.observe(viewLifecycleOwner, Observer {
adapter = HistoryAdapter(it, gameViewModel)
adapter = HistoryAdapter(it)
})
}
}

View file

@ -65,7 +65,14 @@ open class LevelFragment : DaggerFragment() {
recyclerGrid = view.findViewById(R.id.recyclerGrid)
GlobalScope.launch {
val levelSetup = viewModel.onCreate(handleNewGameDeeplink())
val loadGameUid = checkLoadGameDeepLink()
val newGameDeepLink = checkNewGameDeepLink()
val levelSetup = when {
loadGameUid != null -> viewModel.loadGame(loadGameUid)
newGameDeepLink != null -> viewModel.startNewGame(newGameDeepLink)
else -> viewModel.loadLastGame()
}
withContext(Dispatchers.Main) {
recyclerGrid.apply {
@ -113,22 +120,26 @@ open class LevelFragment : DaggerFragment() {
}
}
private fun handleNewGameDeeplink(): Difficulty? {
var result: Difficulty? = null
activity?.intent?.data?.let { uri ->
if (uri.scheme == DEFAULT_SCHEME) {
result = when (uri.schemeSpecificPart.removePrefix("//new-game/")) {
"beginner" -> Difficulty.Beginner
"intermediate" -> Difficulty.Intermediate
"expert" -> Difficulty.Expert
"standard" -> Difficulty.Standard
else -> null
}
private fun checkNewGameDeepLink(): Difficulty? = activity?.intent?.data?.let { uri ->
if (uri.scheme == DEFAULT_SCHEME) {
when (uri.schemeSpecificPart.removePrefix(DEEP_LINK_NEW_GAME_HOST)) {
DEEP_LINK_BEGINNER -> Difficulty.Beginner
DEEP_LINK_INTERMEDIATE -> Difficulty.Intermediate
DEEP_LINK_EXPERT -> Difficulty.Expert
DEEP_LINK_STANDARD -> Difficulty.Standard
else -> null
}
} else {
null
}
}
return result
private fun checkLoadGameDeepLink(): Int? = activity?.intent?.data?.let { uri ->
if (uri.scheme == DEFAULT_SCHEME) {
uri.schemeSpecificPart.removePrefix(DEEP_LINK_LOAD_GAME_HOST).toIntOrNull()
} else {
null
}
}
private fun makeNewLayoutManager(boardWidth: Int, boardHeight: Int) =
@ -146,5 +157,12 @@ open class LevelFragment : DaggerFragment() {
companion object {
const val DEFAULT_SCHEME = "antimine"
const val DEEP_LINK_NEW_GAME_HOST = "//new-game/"
const val DEEP_LINK_LOAD_GAME_HOST = "//load-game/"
const val DEEP_LINK_BEGINNER = "beginner"
const val DEEP_LINK_INTERMEDIATE = "intermediate"
const val DEEP_LINK_EXPERT = "expert"
const val DEEP_LINK_STANDARD = "standard"
}
}

View file

@ -16,7 +16,7 @@ interface SaveDao {
suspend fun loadAllByIds(gameIds: IntArray): List<Save>
@Query("SELECT * FROM save WHERE uid = :gameId LIMIT 1")
suspend fun loadById(gameId: Int): Save
suspend fun loadFromId(gameId: Int): Save
@Query("SELECT * FROM save ORDER BY uid DESC LIMIT 1")
suspend fun loadCurrent(): Save?

View file

@ -7,6 +7,7 @@ import javax.inject.Inject
interface ISavesRepository {
suspend fun getAllSaves(): List<Save>
suspend fun fetchCurrentSave(): Save?
suspend fun loadFromId(id: Int): Save?
suspend fun saveGame(save: Save): Long?
fun setLimit(maxSavesStorage: Int)
}
@ -19,6 +20,8 @@ class SavesRepository @Inject constructor(
override suspend fun fetchCurrentSave(): Save? = savesDao.loadCurrent()
override suspend fun loadFromId(id: Int): Save? = savesDao.loadFromId(id)
override suspend fun saveGame(save: Save): Long? = with(savesDao) {
if (getSaveCounts() >= maxSavesStorage) {
deleteOldSaves(maxSavesStorage)

View file

@ -75,7 +75,7 @@ class GameViewModel(
return minefield
}
fun resumeGameFromSave(save: Save): Minefield {
private fun resumeGameFromSave(save: Save): Minefield {
clock.reset(save.duration)
elapsedTimeSeconds.postValue(save.duration)
@ -97,24 +97,52 @@ class GameViewModel(
return setup
}
suspend fun onCreate(newGame: Difficulty? = null): Minefield = withContext(Dispatchers.IO) {
val lastGame = if (newGame == null) savesRepository.fetchCurrentSave() else null
suspend fun loadGame(uid: Int): Minefield = withContext(Dispatchers.IO) {
val lastGame = savesRepository.loadFromId(uid)
if (lastGame != null) {
currentDifficulty = lastGame.difficulty
} else if (newGame != null) {
currentDifficulty = newGame
}
if (lastGame == null) {
startNewGame(currentDifficulty)
} else {
resumeGameFromSave(lastGame)
} else {
// Fail to load
startNewGame()
}.also {
initialized = true
}
}
suspend fun loadLastGame(): Minefield = withContext(Dispatchers.IO) {
val lastGame = savesRepository.fetchCurrentSave()
if (lastGame != null) {
currentDifficulty = lastGame.difficulty
resumeGameFromSave(lastGame)
} else {
// Fail to load
startNewGame()
}.also {
initialized = true
}
}
// suspend fun onCreate(newGame: Difficulty? = null): Minefield = withContext(Dispatchers.IO) {
// val lastGame = if (newGame == null) savesRepository.fetchCurrentSave() else null
//
// if (lastGame != null) {
// currentDifficulty = lastGame.difficulty
// } else if (newGame != null) {
// currentDifficulty = newGame
// }
//
// if (lastGame == null) {
// startNewGame(currentDifficulty)
// } else {
// resumeGameFromSave(lastGame)
// }.also {
// initialized = true
// }
// }
fun pauseGame() {
if (initialized) {
if (levelFacade.hasMines) {