Load old games
This commit is contained in:
parent
40ae21102f
commit
18f0f498e1
7 changed files with 87 additions and 38 deletions
|
@ -81,6 +81,10 @@
|
|||
<data
|
||||
android:host="new-game"
|
||||
android:scheme="antimine" />
|
||||
|
||||
<data
|
||||
android:host="load-game"
|
||||
android:scheme="antimine" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue