mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-09 20:06:39 -04:00
Try to asynchronize some time-costly tasks
This commit is contained in:
parent
008f07cacc
commit
c775e8368e
@ -42,15 +42,19 @@ fun i18n(key: String): String {
|
|||||||
class Main : Application() {
|
class Main : Application() {
|
||||||
|
|
||||||
override fun start(stage: Stage) {
|
override fun start(stage: Stage) {
|
||||||
|
println(System.currentTimeMillis())
|
||||||
// When launcher visibility is set to "hide and reopen" without [Platform.implicitExit] = false,
|
// When launcher visibility is set to "hide and reopen" without [Platform.implicitExit] = false,
|
||||||
// Stage.show() cannot work again because JavaFX Toolkit have already shut down.
|
// Stage.show() cannot work again because JavaFX Toolkit have already shut down.
|
||||||
Platform.setImplicitExit(false)
|
Platform.setImplicitExit(false)
|
||||||
|
|
||||||
Controllers.initialize(stage)
|
Controllers.initialize(stage)
|
||||||
|
|
||||||
|
println("Showing stage: " + System.currentTimeMillis())
|
||||||
|
|
||||||
stage.isResizable = false
|
stage.isResizable = false
|
||||||
stage.scene = Controllers.scene
|
stage.scene = Controllers.scene
|
||||||
stage.show()
|
stage.show()
|
||||||
|
println("Showed stage: " + System.currentTimeMillis())
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -23,6 +23,7 @@ import org.jackhuang.hmcl.setting.EnumGameDirectory
|
|||||||
import org.jackhuang.hmcl.setting.Profile
|
import org.jackhuang.hmcl.setting.Profile
|
||||||
import org.jackhuang.hmcl.setting.Settings
|
import org.jackhuang.hmcl.setting.Settings
|
||||||
import org.jackhuang.hmcl.setting.VersionSetting
|
import org.jackhuang.hmcl.setting.VersionSetting
|
||||||
|
import org.jackhuang.hmcl.task.Scheduler
|
||||||
import org.jackhuang.hmcl.util.LOG
|
import org.jackhuang.hmcl.util.LOG
|
||||||
import org.jackhuang.hmcl.util.fromJson
|
import org.jackhuang.hmcl.util.fromJson
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -68,30 +69,29 @@ class HMCLGameRepository(val profile: Profile, baseDirectory: File)
|
|||||||
return File(Settings.commonPath).resolve("libraries/${lib.path}")
|
return File(Settings.commonPath).resolve("libraries/${lib.path}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
override fun refreshVersionsImpl() {
|
override fun refreshVersionsImpl() {
|
||||||
versionSettings.clear()
|
Scheduler.NEW_THREAD.schedule {
|
||||||
|
versionSettings.clear()
|
||||||
|
|
||||||
super.refreshVersionsImpl()
|
super.refreshVersionsImpl()
|
||||||
|
|
||||||
versions.keys.forEach(this::loadVersionSetting)
|
versions.keys.forEach(this::loadVersionSetting)
|
||||||
|
|
||||||
checkModpack()
|
checkModpack()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val file = baseDirectory.resolve("launcher_profiles.json")
|
val file = baseDirectory.resolve("launcher_profiles.json")
|
||||||
if (!file.exists() && versions.isNotEmpty())
|
if (!file.exists() && versions.isNotEmpty())
|
||||||
file.writeText(PROFILE)
|
file.writeText(PROFILE)
|
||||||
} catch (ex: IOException) {
|
} catch (ex: IOException) {
|
||||||
LOG.log(Level.WARNING, "Unable to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex)
|
LOG.log(Level.WARNING, "Unable to create launcher_profiles.json, Forge/LiteLoader installer will not work.", ex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeDirectory(newDir: File) {
|
fun changeDirectory(newDir: File) {
|
||||||
baseDirectory = newDir
|
baseDirectory = newDir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
refreshVersions()
|
refreshVersions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +47,7 @@ class Profile(name: String = "Default", initialGameDir: File = File(".minecraft"
|
|||||||
var modManager = ModManager(repository)
|
var modManager = ModManager(repository)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
gameDirProperty.onChange { newGameDir ->
|
gameDirProperty.onChange { repository.changeDirectory(it!!) }
|
||||||
repository.baseDirectory = newGameDir!!
|
|
||||||
repository.refreshVersions()
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedVersionProperty.addListener { _ -> verifySelectedVersion() }
|
selectedVersionProperty.addListener { _ -> verifySelectedVersion() }
|
||||||
EVENT_BUS.channel<RefreshedVersionsEvent>() += { event -> if (event.source == repository) verifySelectedVersion() }
|
EVENT_BUS.channel<RefreshedVersionsEvent>() += { event -> if (event.source == repository) verifySelectedVersion() }
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ class VersionSetting() {
|
|||||||
return null // Custom Java Directory not found,
|
return null // Custom Java Directory not found,
|
||||||
}
|
}
|
||||||
} else if (java.isNotBlank()) {
|
} else if (java.isNotBlank()) {
|
||||||
val c = JavaVersion.JAVAS[java]
|
val c = JavaVersion.getJREs()[java]
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
java = "Default"
|
java = "Default"
|
||||||
return JavaVersion.fromCurrentEnvironment()
|
return JavaVersion.fromCurrentEnvironment()
|
||||||
|
@ -25,14 +25,16 @@ import javafx.scene.layout.Region
|
|||||||
import javafx.stage.Stage
|
import javafx.stage.Stage
|
||||||
import org.jackhuang.hmcl.Main
|
import org.jackhuang.hmcl.Main
|
||||||
import org.jackhuang.hmcl.setting.Settings
|
import org.jackhuang.hmcl.setting.Settings
|
||||||
|
import org.jackhuang.hmcl.task.task
|
||||||
|
import org.jackhuang.hmcl.util.JavaVersion
|
||||||
|
|
||||||
object Controllers {
|
object Controllers {
|
||||||
lateinit var scene: Scene private set
|
lateinit var scene: Scene private set
|
||||||
lateinit var stage: Stage private set
|
lateinit var stage: Stage private set
|
||||||
|
|
||||||
val mainPane = MainPage()
|
val mainPane = MainPage()
|
||||||
val settingsPane = SettingsPage()
|
val settingsPane by lazy { SettingsPage() }
|
||||||
val versionPane = VersionPage()
|
val versionPane by lazy { VersionPage() }
|
||||||
|
|
||||||
lateinit var leftPaneController: LeftPaneController
|
lateinit var leftPaneController: LeftPaneController
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ object Controllers {
|
|||||||
leftPaneController = LeftPaneController(decorator.leftPane)
|
leftPaneController = LeftPaneController(decorator.leftPane)
|
||||||
|
|
||||||
Settings.onProfileLoading()
|
Settings.onProfileLoading()
|
||||||
|
task { JavaVersion.initialize() }.start()
|
||||||
|
|
||||||
decorator.isCustomMaximize = false
|
decorator.isCustomMaximize = false
|
||||||
|
|
||||||
|
@ -17,21 +17,38 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui
|
package org.jackhuang.hmcl.ui
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXButton
|
||||||
import com.jfoenix.controls.JFXCheckBox
|
import com.jfoenix.controls.JFXCheckBox
|
||||||
import com.jfoenix.effects.JFXDepthManager
|
import com.jfoenix.effects.JFXDepthManager
|
||||||
import javafx.fxml.FXML
|
import javafx.geometry.Pos
|
||||||
import javafx.scene.control.Label
|
import javafx.scene.control.Label
|
||||||
import javafx.scene.layout.BorderPane
|
import javafx.scene.layout.BorderPane
|
||||||
|
import javafx.scene.layout.VBox
|
||||||
import org.jackhuang.hmcl.mod.ModInfo
|
import org.jackhuang.hmcl.mod.ModInfo
|
||||||
import org.jackhuang.hmcl.util.onChange
|
import org.jackhuang.hmcl.util.onChange
|
||||||
|
|
||||||
class ModItem(info: ModInfo, private val deleteCallback: (ModItem) -> Unit) : BorderPane() {
|
class ModItem(info: ModInfo, private val deleteCallback: (ModItem) -> Unit) : BorderPane() {
|
||||||
@FXML lateinit var lblModFileName: Label
|
val lblModFileName = Label().apply { style = "-fx-font-size: 15;" }
|
||||||
@FXML lateinit var lblModAuthor: Label
|
val lblModAuthor = Label().apply { style = "-fx-font-size: 10;" }
|
||||||
@FXML lateinit var chkEnabled: JFXCheckBox
|
val chkEnabled = JFXCheckBox().apply { BorderPane.setAlignment(this, Pos.CENTER) }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
loadFXML("/assets/fxml/version/mod-item.fxml")
|
left = chkEnabled
|
||||||
|
|
||||||
|
center = VBox().apply {
|
||||||
|
BorderPane.setAlignment(this, Pos.CENTER)
|
||||||
|
|
||||||
|
children += lblModFileName
|
||||||
|
children += lblModAuthor
|
||||||
|
}
|
||||||
|
|
||||||
|
right = JFXButton().apply {
|
||||||
|
setOnMouseClicked { onDelete() }
|
||||||
|
styleClass += "toggle-icon4"
|
||||||
|
|
||||||
|
BorderPane.setAlignment(this, Pos.CENTER)
|
||||||
|
graphic = SVG.close("black", 15.0, 15.0)
|
||||||
|
}
|
||||||
|
|
||||||
style = "-fx-background-radius: 2; -fx-background-color: white; -fx-padding: 8;"
|
style = "-fx-background-radius: 2; -fx-background-color: white; -fx-padding: 8;"
|
||||||
JFXDepthManager.setDepth(this, 1)
|
JFXDepthManager.setDepth(this, 1)
|
||||||
|
@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui
|
|||||||
import com.jfoenix.controls.*
|
import com.jfoenix.controls.*
|
||||||
import javafx.beans.value.ChangeListener
|
import javafx.beans.value.ChangeListener
|
||||||
import javafx.fxml.FXML
|
import javafx.fxml.FXML
|
||||||
|
import javafx.scene.Node
|
||||||
import javafx.scene.control.Label
|
import javafx.scene.control.Label
|
||||||
import javafx.scene.control.ScrollPane
|
import javafx.scene.control.ScrollPane
|
||||||
import javafx.scene.control.Toggle
|
import javafx.scene.control.Toggle
|
||||||
@ -106,16 +107,22 @@ class VersionSettingsController {
|
|||||||
txtMetaspace.setValidators(validator(true))
|
txtMetaspace.setValidators(validator(true))
|
||||||
txtMetaspace.setValidateWhileTextChanged()
|
txtMetaspace.setValidateWhileTextChanged()
|
||||||
|
|
||||||
javaPane.children.clear()
|
|
||||||
javaPane.children += createJavaPane(JavaVersion.fromCurrentEnvironment(), javaGroup)
|
|
||||||
JavaVersion.JAVAS.values.forEach { javaVersion ->
|
|
||||||
javaPane.children += createJavaPane(javaVersion, javaGroup)
|
|
||||||
}
|
|
||||||
javaPane.children += javaPaneCustom
|
|
||||||
javaPaneCustom.limitHeight(20.0)
|
javaPaneCustom.limitHeight(20.0)
|
||||||
radioCustom.toggleGroup = javaGroup
|
radioCustom.toggleGroup = javaGroup
|
||||||
txtJavaDir.disableProperty().bind(radioCustom.selectedProperty().not())
|
txtJavaDir.disableProperty().bind(radioCustom.selectedProperty().not())
|
||||||
btnJavaSelect.disableProperty().bind(radioCustom.selectedProperty().not())
|
btnJavaSelect.disableProperty().bind(radioCustom.selectedProperty().not())
|
||||||
|
|
||||||
|
task {
|
||||||
|
val list = mutableListOf<Node>()
|
||||||
|
list += createJavaPane(JavaVersion.fromCurrentEnvironment(), javaGroup)
|
||||||
|
JavaVersion.getJREs().values.forEach { javaVersion ->
|
||||||
|
list += createJavaPane(javaVersion, javaGroup)
|
||||||
|
}
|
||||||
|
list += javaPaneCustom
|
||||||
|
it["list"] = list
|
||||||
|
}.subscribe(Scheduler.JAVAFX) {
|
||||||
|
javaPane.children.setAll(it.get<List<Node>>("list"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createJavaPane(java: JavaVersion, group: ToggleGroup): Pane {
|
private fun createJavaPane(java: JavaVersion, group: ToggleGroup): Pane {
|
||||||
|
@ -35,7 +35,7 @@ class InstallWizardProvider(val profile: Profile, val gameVersion: String, val v
|
|||||||
if (settings.containsKey("optifine"))
|
if (settings.containsKey("optifine"))
|
||||||
ret = ret with profile.dependency.installLibraryAsync(gameVersion, version, "optifine", settings["optifine"] as String)
|
ret = ret with profile.dependency.installLibraryAsync(gameVersion, version, "optifine", settings["optifine"] as String)
|
||||||
|
|
||||||
return ret with task(Scheduler.JAVAFX) { profile.repository.refreshVersions() }
|
return ret with task { profile.repository.refreshVersions() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createPage(controller: WizardController, step: Int, settings: MutableMap<String, Any>): Node {
|
override fun createPage(controller: WizardController, step: Int, settings: MutableMap<String, Any>): Node {
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import java.lang.*?>
|
|
||||||
<?import java.util.*?>
|
|
||||||
<?import javafx.scene.*?>
|
|
||||||
<?import javafx.scene.control.*?>
|
|
||||||
<?import javafx.scene.layout.*?>
|
|
||||||
|
|
||||||
<?import com.jfoenix.controls.JFXCheckBox?>
|
|
||||||
<?import com.jfoenix.controls.JFXButton?>
|
|
||||||
<fx:root xmlns="http://javafx.com/javafx"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
type="BorderPane">
|
|
||||||
<left>
|
|
||||||
<JFXCheckBox fx:id="chkEnabled" BorderPane.alignment="CENTER" />
|
|
||||||
</left>
|
|
||||||
<center>
|
|
||||||
<VBox BorderPane.alignment="CENTER">
|
|
||||||
<Label fx:id="lblModFileName" style="-fx-font-size: 15;" />
|
|
||||||
<Label fx:id="lblModAuthor" style="-fx-font-size: 10;" />
|
|
||||||
</VBox>
|
|
||||||
</center>
|
|
||||||
<right>
|
|
||||||
<JFXButton onMouseClicked="#onDelete" styleClass="toggle-icon4" BorderPane.alignment="CENTER">
|
|
||||||
<graphic>
|
|
||||||
<fx:include source="/assets/svg/close-black.fxml"/>
|
|
||||||
</graphic>
|
|
||||||
</JFXButton>
|
|
||||||
</right>
|
|
||||||
</fx:root>
|
|
@ -12,7 +12,7 @@
|
|||||||
<JFXSpinner style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
|
<JFXSpinner style="-fx-radius:16" styleClass="materialDesign-purple, first-spinner" />
|
||||||
<StackPane fx:id="contentPane">
|
<StackPane fx:id="contentPane">
|
||||||
<ScrollPane fx:id="scrollPane" fitToWidth="true" fitToHeight="true">
|
<ScrollPane fx:id="scrollPane" fitToWidth="true" fitToHeight="true">
|
||||||
<VBox fx:id="modPane" spacing="10" style="-fx-padding: 20;">
|
<VBox fx:id="modPane" spacing="10" style="-fx-padding: 20 20 70 20;">
|
||||||
|
|
||||||
</VBox>
|
</VBox>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
|
@ -140,7 +140,6 @@ open class DefaultGameRepository(var baseDirectory: File): GameRepository {
|
|||||||
isLoaded = true
|
isLoaded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
final override fun refreshVersions() {
|
final override fun refreshVersions() {
|
||||||
EVENT_BUS.fireEvent(RefreshingVersionsEvent(this))
|
EVENT_BUS.fireEvent(RefreshingVersionsEvent(this))
|
||||||
refreshVersionsImpl()
|
refreshVersionsImpl()
|
||||||
|
@ -18,10 +18,12 @@
|
|||||||
package org.jackhuang.hmcl.util
|
package org.jackhuang.hmcl.util
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import org.jackhuang.hmcl.game.Version
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,8 +51,6 @@ data class JavaVersion internal constructor(
|
|||||||
companion object {
|
companion object {
|
||||||
private val regex = Pattern.compile("java version \"(?<version>[1-9]*\\.[1-9]*\\.[0-9]*(.*?))\"")
|
private val regex = Pattern.compile("java version \"(?<version>[1-9]*\\.[1-9]*\\.[0-9]*(.*?))\"")
|
||||||
|
|
||||||
val JAVAS: Map<String, JavaVersion>
|
|
||||||
|
|
||||||
val UNKNOWN: Int = -1
|
val UNKNOWN: Int = -1
|
||||||
val JAVA_5: Int = 50
|
val JAVA_5: Int = 50
|
||||||
val JAVA_6: Int = 60
|
val JAVA_6: Int = 60
|
||||||
@ -132,7 +132,22 @@ data class JavaVersion internal constructor(
|
|||||||
}
|
}
|
||||||
fun fromCurrentEnvironment() = currentJava
|
fun fromCurrentEnvironment() = currentJava
|
||||||
|
|
||||||
init {
|
private var javas: Map<String, JavaVersion>? = null
|
||||||
|
private val await = CountDownLatch(1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will block until [initialize] succeeds.
|
||||||
|
*/
|
||||||
|
fun getJREs(): Map<String, JavaVersion> {
|
||||||
|
if (javas != null) return javas!!
|
||||||
|
await.await()
|
||||||
|
return javas!!
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
fun initialize() {
|
||||||
|
if (javas != null)
|
||||||
|
throw IllegalStateException("JavaVersions have already been initialized.")
|
||||||
val temp = mutableMapOf<String, JavaVersion>()
|
val temp = mutableMapOf<String, JavaVersion>()
|
||||||
(when (OS.CURRENT_OS) {
|
(when (OS.CURRENT_OS) {
|
||||||
OS.WINDOWS -> queryWindows()
|
OS.WINDOWS -> queryWindows()
|
||||||
@ -141,7 +156,8 @@ data class JavaVersion internal constructor(
|
|||||||
}).forEach { javaVersion ->
|
}).forEach { javaVersion ->
|
||||||
temp.put(javaVersion.longVersion, javaVersion)
|
temp.put(javaVersion.longVersion, javaVersion)
|
||||||
}
|
}
|
||||||
JAVAS = temp
|
javas = temp
|
||||||
|
await.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun queryMacintosh() = LinkedList<JavaVersion>().apply {
|
private fun queryMacintosh() = LinkedList<JavaVersion>().apply {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user