Skip to content

Commit

Permalink
Feat: Sort instances by last played
Browse files Browse the repository at this point in the history
Cleanup: Rename some Modpack classes to Instance
  • Loading branch information
0ffz committed Mar 13, 2024
1 parent ef8c560 commit 20f7012
Show file tree
Hide file tree
Showing 25 changed files with 76 additions and 70 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
group=com.mineinabyss
version=2.0.0-alpha.13
version=2.0.0-alpha.14
idofrontVersion=0.22.3
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ data class Config(
val useRecommendedJvmArguments: Boolean = true,
val preferHue: Float? = null,
val startInFullscreen: Boolean = false,
val lastPlayedMap: Map<String, Long> = mapOf(),
) {
fun save() {
Dirs.configFile.writeText(Formats.yaml.encodeToString(this))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.mineinabyss.launchy.logic.UpdateResult
import com.mineinabyss.launchy.logic.showDialogOnError
import com.mineinabyss.launchy.state.InProgressTask
import com.mineinabyss.launchy.state.LaunchyState
import com.mineinabyss.launchy.state.modpack.ModpackState
import com.mineinabyss.launchy.state.modpack.GameInstanceState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -40,8 +40,8 @@ class GameInstance(
var updatesAvailable by mutableStateOf(false)
var enabled: Boolean by mutableStateOf(true)

suspend fun createModpackState(state: LaunchyState): ModpackState? {
val userConfig = ModpackUserConfig.load(userConfigFile).getOrNull() ?: ModpackUserConfig()
suspend fun createModpackState(state: LaunchyState): GameInstanceState? {
val userConfig = InstanceUserConfig.load(userConfigFile).getOrNull() ?: InstanceUserConfig()

val modpack = state.runTask("loadingModpack ${config.name}", InProgressTask("Loading modpack ${config.name}")) {
config.source.loadInstance(this)
Expand All @@ -59,7 +59,7 @@ class GameInstance(
updatesAvailable = true
}
}
return ModpackState(this, modpack, userConfig)
return GameInstanceState(this, modpack, userConfig)
}

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ data class DownloadInfo(
}

@Serializable
data class ModpackUserConfig(
data class InstanceUserConfig(
val userAgreedDeps: InstanceModLoaders? = null,
val fullEnabledGroups: Set<GroupName> = setOf(),
val fullDisabledGroups: Set<GroupName> = setOf(),
Expand All @@ -56,13 +56,13 @@ data class ModpackUserConfig(
) {
fun save(file: Path) {
file.createParentDirectories().deleteIfExists()
file.writeText(Formats.yaml.encodeToString<ModpackUserConfig>(this))
file.writeText(Formats.yaml.encodeToString<InstanceUserConfig>(this))
}

companion object {
fun load(file: Path): Result<ModpackUserConfig> = runCatching {
return@runCatching if (file.exists()) Formats.yaml.decodeFromStream<ModpackUserConfig>(file.inputStream())
else ModpackUserConfig()
fun load(file: Path): Result<InstanceUserConfig> = runCatching {
return@runCatching if (file.exists()) Formats.yaml.decodeFromStream<InstanceUserConfig>(file.inputStream())
else InstanceUserConfig()
}.onFailure { it.printStackTrace() }
}
}
5 changes: 3 additions & 2 deletions src/main/kotlin/com/mineinabyss/launchy/logic/Launcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.mineinabyss.launchy.logic
import com.mineinabyss.launchy.data.modpacks.InstanceModLoaders
import com.mineinabyss.launchy.state.LaunchyState
import com.mineinabyss.launchy.state.ProfileState
import com.mineinabyss.launchy.state.modpack.ModpackState
import com.mineinabyss.launchy.state.modpack.GameInstanceState
import com.mineinabyss.launchy.ui.screens.Dialog
import com.mineinabyss.launchy.ui.screens.dialog
import kotlinx.coroutines.Job
Expand All @@ -30,14 +30,15 @@ import kotlin.io.path.notExists


object Launcher {
suspend fun launch(state: LaunchyState, pack: ModpackState, profile: ProfileState): Unit = coroutineScope {
suspend fun launch(state: LaunchyState, pack: GameInstanceState, profile: ProfileState): Unit = coroutineScope {
val dir = MinecraftDirectory(pack.instance.minecraftDir.toFile())
val launcher = LauncherBuilder.buildDefault()
val javaPath = state.jvm.javaPath
if (javaPath == null || javaPath.notExists()) {
dialog = Dialog.ChooseJVMPath
return@coroutineScope
}
state.lastPlayed[pack.instance.config.name] = Date().time
// Auth or show dialog
when (val session = profile.currentSession) {
null -> Auth.authOrShowDialog(state, profile) {
Expand Down
16 changes: 8 additions & 8 deletions src/main/kotlin/com/mineinabyss/launchy/logic/ModDownloader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import com.mineinabyss.launchy.data.modpacks.InstanceModLoaders
import com.mineinabyss.launchy.data.modpacks.Mod
import com.mineinabyss.launchy.state.InProgressTask
import com.mineinabyss.launchy.state.LaunchyState
import com.mineinabyss.launchy.state.modpack.ModpackState
import com.mineinabyss.launchy.state.modpack.GameInstanceState
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
Expand All @@ -16,7 +16,7 @@ import kotlin.io.path.*

object ModDownloader {

suspend fun ModpackState.installMCAndModLoaders(state: LaunchyState, modLoaders: InstanceModLoaders) {
suspend fun GameInstanceState.installMCAndModLoaders(state: LaunchyState, modLoaders: InstanceModLoaders) {
state.runTask(Tasks.installModLoadersId, InProgressTask("Installing ${modLoaders.fabricLoader}")) {
Launcher.download(
modLoaders,
Expand All @@ -35,7 +35,7 @@ object ModDownloader {
data object Failed : DownloadResult
}

suspend fun ModpackState.download(mod: Mod, ignoreCachedCheck: Boolean): DownloadResult {
suspend fun GameInstanceState.download(mod: Mod, ignoreCachedCheck: Boolean): DownloadResult {
val name = mod.info.name
try {
println("Starting download of $name")
Expand Down Expand Up @@ -91,15 +91,15 @@ object ModDownloader {
* does not install any mod updates or new dep versions if they changed in the modpack.
* Primarily the mod loader/minecraft version.
*/
suspend fun ModpackState.ensureDependenciesReady(state: LaunchyState) = coroutineScope {
suspend fun GameInstanceState.ensureDependenciesReady(state: LaunchyState) = coroutineScope {
val currentDeps = userAgreedDeps
if (currentDeps == null) {
userAgreedDeps = modpack.modLoaders
}
installMCAndModLoaders(state, currentDeps ?: modpack.modLoaders)
}

fun ModpackState.copyMods() {
fun GameInstanceState.copyMods() {
// Clear mods folder
val existingEntries = instance.modsDir.useDirectoryEntries { files ->
files.filter { !it.isDirectory() }.toList()
Expand All @@ -122,13 +122,13 @@ object ModDownloader {
(existingEntries - linked).forEach { it.deleteIfExists() }
}

suspend fun ModpackState.prepareWithoutChangingInstalledMods(state: LaunchyState) {
suspend fun GameInstanceState.prepareWithoutChangingInstalledMods(state: LaunchyState) {
ensureDependenciesReady(state)
copyMods()
}

@OptIn(ExperimentalPathApi::class)
fun ModpackState.copyOverrides(state: LaunchyState) {
fun GameInstanceState.copyOverrides(state: LaunchyState) {
state.runTask(Tasks.copyOverridesId, InProgressTask("Copying overrides")) {
modpack.overridesPaths.forEach {
it.copyToRecursively(
Expand All @@ -143,7 +143,7 @@ object ModDownloader {
/**
* Updates mod loader versions and mods to latest modpack definition.
*/
suspend fun ModpackState.startInstall(state: LaunchyState, ignoreCachedCheck: Boolean = false): Result<*> =
suspend fun GameInstanceState.startInstall(state: LaunchyState, ignoreCachedCheck: Boolean = false): Result<*> =
coroutineScope {
userAgreedDeps = modpack.modLoaders
ensureDependenciesReady(state)
Expand Down
10 changes: 7 additions & 3 deletions src/main/kotlin/com/mineinabyss/launchy/state/LaunchyState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.mineinabyss.launchy.state
import androidx.compose.runtime.*
import com.mineinabyss.launchy.data.config.Config
import com.mineinabyss.launchy.data.config.GameInstance
import com.mineinabyss.launchy.state.modpack.ModpackState
import com.mineinabyss.launchy.state.modpack.GameInstanceState
import java.util.*

class LaunchyState(
Expand All @@ -12,10 +12,13 @@ class LaunchyState(
private val instances: List<GameInstance>
) {
val profile = ProfileState(config)
var modpackState: ModpackState? by mutableStateOf(null)
var instanceState: GameInstanceState? by mutableStateOf(null)
private val launchedProcesses = mutableStateMapOf<String, Process>()
val jvm = JvmState(config)
val ui = UIState(config)
val lastPlayed = mutableStateMapOf<String, Long>().apply {
putAll(config.lastPlayedMap)
}

val gameInstances = mutableStateListOf<GameInstance>().apply {
addAll(instances)
Expand Down Expand Up @@ -46,7 +49,8 @@ class LaunchyState(
memoryAllocation = jvm.userMemoryAllocation,
useRecommendedJvmArguments = jvm.useRecommendedJvmArgs,
preferHue = ui.preferHue,
startInFullscreen = ui.fullscreen
startInFullscreen = ui.fullscreen,
lastPlayedMap = lastPlayed
).save()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
import com.mineinabyss.launchy.data.ModID
import com.mineinabyss.launchy.data.config.DownloadInfo
import com.mineinabyss.launchy.data.config.ModpackUserConfig
import com.mineinabyss.launchy.data.config.InstanceUserConfig
import com.mineinabyss.launchy.data.modpacks.Modpack

class DownloadQueueState(
private val userConfig: ModpackUserConfig,
private val userConfig: InstanceUserConfig,
val modpack: Modpack,
val toggles: ModTogglesState
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.mineinabyss.launchy.data.config.GameInstance
import com.mineinabyss.launchy.data.config.ModpackUserConfig
import com.mineinabyss.launchy.data.config.InstanceUserConfig
import com.mineinabyss.launchy.data.modpacks.Modpack

class ModpackState(
class GameInstanceState(
val instance: GameInstance,
val modpack: Modpack,
private val userConfig: ModpackUserConfig
private val userConfig: InstanceUserConfig
) {
val toggles: ModTogglesState = ModTogglesState(modpack, userConfig)
val queued = DownloadQueueState(userConfig, modpack, toggles)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package com.mineinabyss.launchy.state.modpack

import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import com.mineinabyss.launchy.data.config.ModpackUserConfig
import com.mineinabyss.launchy.data.config.InstanceUserConfig
import com.mineinabyss.launchy.data.modpacks.Mod
import com.mineinabyss.launchy.data.modpacks.Modpack
import com.mineinabyss.launchy.logic.ToggleMods.setModEnabled
import com.mineinabyss.launchy.state.mutableStateSetOf

class ModTogglesState(
val modpack: Modpack,
val modpackConfig: ModpackUserConfig
val modpackConfig: InstanceUserConfig
) {
val enabledMods = mutableStateSetOf<Mod>().apply {
addAll(modpackConfig.toggledMods.mapNotNull { modpack.mods.getMod(it) })
Expand Down
12 changes: 6 additions & 6 deletions src/main/kotlin/com/mineinabyss/launchy/ui/screens/Screens.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.mineinabyss.launchy.LocalLaunchyState
import com.mineinabyss.launchy.state.InProgressTask
import com.mineinabyss.launchy.state.modpack.ModpackState
import com.mineinabyss.launchy.state.modpack.GameInstanceState
import com.mineinabyss.launchy.ui.AppTopBar
import com.mineinabyss.launchy.ui.colors.currentHue
import com.mineinabyss.launchy.ui.dialogs.AuthDialog
Expand All @@ -22,7 +22,7 @@ import com.mineinabyss.launchy.ui.elements.LaunchyDialog
import com.mineinabyss.launchy.ui.screens.home.HomeScreen
import com.mineinabyss.launchy.ui.screens.home.newinstance.NewInstance
import com.mineinabyss.launchy.ui.screens.home.settings.SettingsScreen
import com.mineinabyss.launchy.ui.screens.modpack.main.ModpackScreen
import com.mineinabyss.launchy.ui.screens.modpack.main.InstanceScreen
import com.mineinabyss.launchy.ui.screens.modpack.main.SlightBackgroundTint
import com.mineinabyss.launchy.ui.screens.modpack.settings.InfoBarProperties
import com.mineinabyss.launchy.ui.screens.modpack.settings.InstanceSettingsScreen
Expand All @@ -32,22 +32,22 @@ var screen: Screen by mutableStateOf(Screen.Default)

var dialog: Dialog by mutableStateOf(Dialog.None)

private val ModpackStateProvider = compositionLocalOf<ModpackState> { error("No local modpack provided") }
private val ModpackStateProvider = compositionLocalOf<GameInstanceState> { error("No local modpack provided") }

val snackbarHostState = SnackbarHostState()

val LocalModpackState: ModpackState
val LocalGameInstanceState: GameInstanceState
@Composable get() = ModpackStateProvider.current

@Composable
fun Screens() = Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) }
) {
val state = LocalLaunchyState
val packState = state.modpackState
val packState = state.instanceState

if (packState != null) CompositionLocalProvider(ModpackStateProvider provides packState) {
Screen(Screen.Instance) { ModpackScreen() }
Screen(Screen.Instance) { InstanceScreen() }
Screen(Screen.InstanceSettings, transition = Transitions.SlideUp) { InstanceSettingsScreen() }
}
Screen(Screen.Default) { HomeScreen() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fun HomeScreen() {
Spacer(Modifier.height(16.dp))
}
item {
ModpackGroup("Instances", state.gameInstances)
InstanceList("Instances", state.gameInstances)
}
// item {
// ModpackGroup("Find more", state.downloadedModpacks)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fun InstanceCard(
onClick = {
instance ?: return@Card
coroutineScope.launch {
state.modpackState = instance.createModpackState(state)
state.instanceState = instance.createModpackState(state)
currentHue = instance.config.hue
screen = Screen.Instance
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.mineinabyss.launchy.LocalLaunchyState
import com.mineinabyss.launchy.data.config.GameInstance

@Composable
fun ModpackGroup(title: String, packs: List<GameInstance>) {
fun InstanceList(title: String, packs: List<GameInstance>) {
val state = LocalLaunchyState
Column {
// var showAll by remember { mutableStateOf(false) }
val visiblePacks = packs//.take(6)
Expand All @@ -38,7 +40,7 @@ fun ModpackGroup(title: String, packs: List<GameInstance>) {
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
items(visiblePacks) { pack ->
items(visiblePacks.sortedByDescending { state.lastPlayed[it.config.name] }) { pack ->
InstanceCard(pack.config, pack)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.mineinabyss.launchy.LocalLaunchyState
import com.mineinabyss.launchy.ui.screens.LocalModpackState
import com.mineinabyss.launchy.ui.screens.LocalGameInstanceState
import com.mineinabyss.launchy.ui.screens.modpack.main.buttons.PlayButton
import com.mineinabyss.launchy.ui.screens.modpack.main.buttons.SettingsButton
import com.mineinabyss.launchy.ui.screens.modpack.main.buttons.UpdateButton
Expand All @@ -18,9 +17,8 @@ import com.mineinabyss.launchy.ui.state.windowScope
@ExperimentalComposeUiApi
@Preview
@Composable
fun ModpackScreen() {
val state = LocalLaunchyState
val packState = LocalModpackState
fun InstanceScreen() {
val packState = LocalGameInstanceState

Box {
BackgroundImage(windowScope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.WindowScope
import com.mineinabyss.launchy.LocalLaunchyState
import com.mineinabyss.launchy.ui.screens.LocalModpackState
import com.mineinabyss.launchy.ui.screens.LocalGameInstanceState

@Composable
fun BoxScope.BackgroundImage(windowScope: WindowScope) {
val pack = LocalModpackState
val pack = LocalGameInstanceState
val background by pack.instance.config.getBackground()
AnimatedVisibility(background != null, enter = fadeIn(), exit = fadeOut()) {
if (background == null) return@AnimatedVisibility
Expand Down Expand Up @@ -76,7 +76,7 @@ fun BoxScope.SlightBackgroundTint(modifier: Modifier = Modifier) {
@Composable
fun LogoLarge(modifier: Modifier) {
val state = LocalLaunchyState
val pack = LocalModpackState
val pack = LocalGameInstanceState
val painter by pack.instance.config.getLogo()
AnimatedVisibility(
painter != null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
import com.mineinabyss.launchy.LocalLaunchyState
import com.mineinabyss.launchy.ui.screens.LocalModpackState
import com.mineinabyss.launchy.ui.screens.LocalGameInstanceState

@Composable
fun UpdateInfoButton() {
val state = LocalLaunchyState
val packState = LocalModpackState
val packState = LocalGameInstanceState
var toggled by remember { mutableStateOf(false) }
Button(onClick = { toggled = !toggled }, shape = RoundedCornerShape(20.dp)) {
Column {
Expand Down
Loading

0 comments on commit 20f7012

Please sign in to comment.