Skip to content

Commit 8fca69d

Browse files
committed
Revert some slow operations fixes in new project creator. Closes #2550
1 parent b7eca00 commit 8fca69d

File tree

11 files changed

+74
-125
lines changed

11 files changed

+74
-125
lines changed

src/main/kotlin/creator/JdkComboBoxWithPreference.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
package com.demonwav.mcdev.creator
2222

23-
import com.demonwav.mcdev.util.invokeLater
2423
import com.intellij.ide.util.PropertiesComponent
2524
import com.intellij.ide.util.projectWizard.ProjectWizardUtil
2625
import com.intellij.ide.util.projectWizard.WizardContext
@@ -43,7 +42,6 @@ import com.intellij.openapi.util.Disposer
4342
import com.intellij.ui.dsl.builder.Cell
4443
import com.intellij.ui.dsl.builder.Row
4544
import javax.swing.JComponent
46-
import org.jetbrains.concurrency.runAsync
4745

4846
internal class JdkPreferenceData(
4947
var jdk: JavaSdkVersion,
@@ -91,17 +89,15 @@ class JdkComboBoxWithPreference internal constructor(
9189
preferenceData.jdk = version
9290
reloadModel()
9391

94-
for (jdkVersion in version.ordinal until JavaSdkVersion.entries.size) {
95-
val jdk = JavaSdkVersion.entries[jdkVersion]
92+
for (jdkVersion in version.ordinal until JavaSdkVersion.values().size) {
93+
val jdk = JavaSdkVersion.values()[jdkVersion]
9694

9795
val preferredSdkPath = preferenceData.sdkPathByJdk[jdk]
9896
if (preferredSdkPath != null) {
9997
val sdk = model.sdks.firstOrNull { it.homePath == preferredSdkPath }
10098
?: suggestions.firstOrNull { it.homePath == preferredSdkPath }
10199
if (sdk != null) {
102-
runAsync {
103-
setSelectedItem(sdk)
104-
}
100+
setSelectedItem(sdk)
105101
return
106102
}
107103
}
@@ -149,7 +145,7 @@ fun Row.jdkComboBoxWithPreference(
149145
for (preferenceDataStr in preferenceDataStrs) {
150146
val parts = preferenceDataStr.split('=', limit = 2)
151147
val featureVersion = parts.firstOrNull()?.toIntOrNull() ?: continue
152-
val knownJdkVersions = JavaSdkVersion.entries
148+
val knownJdkVersions = JavaSdkVersion.values()
153149
if (featureVersion !in knownJdkVersions.indices) {
154150
continue
155151
}
@@ -180,9 +176,7 @@ fun Row.jdkComboBoxWithPreference(
180176
}
181177

182178
val lastUsedSdk = stateComponent.getValue(selectedJdkProperty)
183-
runAsync {
184-
ProjectWizardUtil.preselectJdkForNewModule(project, lastUsedSdk, comboBox) { true }
185-
}
179+
ProjectWizardUtil.preselectJdkForNewModule(project, lastUsedSdk, comboBox) { true }
186180

187181
val windowChild = context.getUserData(AbstractWizard.KEY)!!.contentPanel
188182
comboBox.loadSuggestions(windowChild, context.disposable)

src/main/kotlin/creator/custom/CreatorTemplateProcessor.kt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import com.intellij.codeInsight.actions.ReformatCodeProcessor
3434
import com.intellij.ide.projectView.ProjectView
3535
import com.intellij.ide.util.projectWizard.WizardContext
3636
import com.intellij.openapi.application.WriteAction
37-
import com.intellij.openapi.concurrency.awaitPromise
3837
import com.intellij.openapi.diagnostic.Attachment
3938
import com.intellij.openapi.diagnostic.ControlFlowException
4039
import com.intellij.openapi.diagnostic.thisLogger
@@ -54,15 +53,11 @@ import com.intellij.ui.dsl.builder.Panel
5453
import com.intellij.ui.dsl.builder.panel
5554
import com.intellij.util.application
5655
import java.nio.file.Path
57-
import java.time.Duration
58-
import java.util.concurrent.TimeUnit
5956
import java.util.function.Consumer
6057
import kotlin.io.path.createDirectories
6158
import kotlin.io.path.writeText
6259
import kotlinx.coroutines.CoroutineScope
6360
import kotlinx.coroutines.launch
64-
import org.jetbrains.concurrency.await
65-
import org.jetbrains.concurrency.runAsync
6661

6762
interface ExternalTemplatePropertyProvider {
6863

@@ -273,11 +268,7 @@ class CreatorTemplateProcessor(
273268
destPath.parent.createDirectories()
274269
destPath.writeText(processedContent)
275270

276-
val virtualFile = runCatching {
277-
runAsync {
278-
destPath.refreshAndFindVirtualFile()
279-
}.blockingGet(20, TimeUnit.MILLISECONDS)
280-
}.getOrNull()
271+
val virtualFile = destPath.refreshAndFindVirtualFile()
281272
if (virtualFile != null) {
282273
generatedFiles.add(file to virtualFile)
283274
} else {

src/main/kotlin/creator/custom/CustomPlatformStep.kt

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,12 @@ import com.demonwav.mcdev.creator.custom.providers.LoadedTemplate
2727
import com.demonwav.mcdev.creator.custom.providers.TemplateProvider
2828
import com.demonwav.mcdev.creator.modalityState
2929
import com.demonwav.mcdev.util.getOrLogException
30-
import com.demonwav.mcdev.util.invokeAndWait
31-
import com.demonwav.mcdev.util.runWriteTask
32-
import com.demonwav.mcdev.util.tryWriteSafeContext
3330
import com.intellij.ide.wizard.AbstractNewProjectWizardStep
3431
import com.intellij.ide.wizard.GitNewProjectWizardData
3532
import com.intellij.ide.wizard.NewProjectWizardBaseData
3633
import com.intellij.ide.wizard.NewProjectWizardStep
3734
import com.intellij.openapi.application.EDT
38-
import com.intellij.openapi.application.ModalityState
39-
import com.intellij.openapi.application.TransactionGuard
4035
import com.intellij.openapi.application.asContextElement
41-
import com.intellij.openapi.application.impl.ModalityStateEx
4236
import com.intellij.openapi.application.runWriteAction
4337
import com.intellij.openapi.diagnostic.logger
4438
import com.intellij.openapi.observable.properties.GraphProperty
@@ -57,12 +51,10 @@ import com.intellij.ui.dsl.builder.bindText
5751
import com.intellij.util.application
5852
import com.intellij.util.ui.AsyncProcessIcon
5953
import javax.swing.JLabel
60-
import javax.swing.SwingUtilities
6154
import kotlinx.coroutines.Dispatchers
6255
import kotlinx.coroutines.Job
6356
import kotlinx.coroutines.cancel
6457
import kotlinx.coroutines.launch
65-
import org.jetbrains.kotlin.descriptors.Modality
6658

6759
/**
6860
* The step to select a custom template repo.
@@ -75,7 +67,7 @@ class CustomPlatformStep(
7567
val creatorUiScope = TemplateService.instance.scope("MinecraftDev Creator UI")
7668
val templateRepos = MinecraftSettings.instance.creatorTemplateRepos
7769

78-
val templateRepoProperty = propertyGraph.property(
70+
val templateRepoProperty = propertyGraph.property<MinecraftSettings.TemplateRepo>(
7971
templateRepos.firstOrNull() ?: MinecraftSettings.TemplateRepo.makeBuiltinRepo()
8072
)
8173
var templateRepo by templateRepoProperty
@@ -87,19 +79,19 @@ class CustomPlatformStep(
8779
lateinit var availableGroupsSegmentedButton: SegmentedButton<String>
8880
lateinit var availableTemplatesSegmentedButton: SegmentedButton<LoadedTemplate>
8981

90-
val selectedGroupProperty = propertyGraph.property("")
82+
val selectedGroupProperty = propertyGraph.property<String>("")
9183
var selectedGroup by selectedGroupProperty
9284
val selectedTemplateProperty = propertyGraph.property<LoadedTemplate>(EmptyLoadedTemplate)
9385
var selectedTemplate by selectedTemplateProperty
9486

95-
val templateProvidersLoadingProperty = propertyGraph.property(true)
87+
val templateProvidersLoadingProperty = propertyGraph.property<Boolean>(true)
9688
val templateProvidersTextProperty = propertyGraph.property("")
9789
val templateProvidersText2Property = propertyGraph.property("")
9890
lateinit var templateProvidersProcessIcon: Cell<AsyncProcessIcon>
9991

100-
val templateLoadingProperty = propertyGraph.property(false)
101-
val templateLoadingTextProperty = propertyGraph.property("")
102-
val templateLoadingText2Property = propertyGraph.property("")
92+
val templateLoadingProperty = propertyGraph.property<Boolean>(false)
93+
val templateLoadingTextProperty = propertyGraph.property<String>("")
94+
val templateLoadingText2Property = propertyGraph.property<String>("")
10395
lateinit var templatePropertiesProcessIcon: Cell<AsyncProcessIcon>
10496
lateinit var noTemplatesAvailable: Cell<JLabel>
10597
var templateLoadingJob: Job? = null
@@ -256,9 +248,11 @@ class CustomPlatformStep(
256248
templateLoadingTextProperty.set(MCDevBundle("creator.step.generic.load_template.message"))
257249
templateLoadingProperty.set(true)
258250

259-
tryWriteSafeContext(context.modalityState) {
260-
VirtualFileManager.getInstance().syncRefresh()
261-
}
251+
// For some reason syncRefresh doesn't play nice with writeAction() coroutines so we do it beforehand
252+
application.invokeAndWait(
253+
{ runWriteAction { VirtualFileManager.getInstance().syncRefresh() } },
254+
context.modalityState
255+
)
262256

263257
val dialogCoroutineContext = context.modalityState.asContextElement()
264258
val uiContext = dialogCoroutineContext + Dispatchers.EDT

src/main/kotlin/creator/custom/providers/BuiltinTemplateProvider.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ import com.intellij.openapi.progress.ProgressIndicator
3333
import com.intellij.ui.dsl.builder.bindSelected
3434
import com.intellij.ui.dsl.builder.panel
3535
import javax.swing.JComponent
36-
import kotlinx.coroutines.Dispatchers
37-
import kotlinx.coroutines.withContext
3836

3937
class BuiltinTemplateProvider : RemoteTemplateProvider() {
4038

@@ -61,16 +59,16 @@ class BuiltinTemplateProvider : RemoteTemplateProvider() {
6159
override suspend fun loadTemplates(
6260
context: WizardContext,
6361
repo: MinecraftSettings.TemplateRepo
64-
): Collection<LoadedTemplate> = withContext(Dispatchers.IO) {
62+
): Collection<LoadedTemplate> {
6563
val remoteTemplates = doLoadTemplates(context, repo, builtinTemplatesInnerPath)
6664
if (remoteTemplates.isNotEmpty()) {
67-
return@withContext remoteTemplates
65+
return remoteTemplates
6866
}
6967

7068
val repoRoot = builtinTemplatesPath.virtualFile
71-
?: return@withContext emptyList()
69+
?: return emptyList()
7270
repoRoot.refreshSync(context.modalityState)
73-
TemplateProvider.findTemplates(context.modalityState, repoRoot)
71+
return TemplateProvider.findTemplates(context.modalityState, repoRoot)
7472
}
7573

7674
override fun setupConfigUi(

src/main/kotlin/creator/custom/providers/LocalTemplateProvider.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ import com.intellij.ui.dsl.builder.textValidation
3939
import java.nio.file.Path
4040
import javax.swing.JComponent
4141
import kotlin.io.path.absolute
42-
import kotlinx.coroutines.Dispatchers
43-
import kotlinx.coroutines.withContext
4442

4543
class LocalTemplateProvider : TemplateProvider {
4644

@@ -51,13 +49,13 @@ class LocalTemplateProvider : TemplateProvider {
5149
override suspend fun loadTemplates(
5250
context: WizardContext,
5351
repo: MinecraftSettings.TemplateRepo
54-
): Collection<LoadedTemplate> = withContext(Dispatchers.IO) {
52+
): Collection<LoadedTemplate> {
5553
val rootPath = Path.of(repo.data.trim()).absolute()
5654
val repoRoot = rootPath.virtualFile
57-
?: return@withContext emptyList()
55+
?: return emptyList()
5856
val modalityState = context.modalityState
5957
repoRoot.refreshSync(modalityState)
60-
TemplateProvider.findTemplates(modalityState, repoRoot)
58+
return TemplateProvider.findTemplates(modalityState, repoRoot)
6159
}
6260

6361
override fun setupConfigUi(

src/main/kotlin/creator/custom/providers/RemoteTemplateProvider.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ import javax.swing.ListCellRenderer
6767
import kotlin.io.path.absolutePathString
6868
import kotlin.io.path.exists
6969
import kotlin.io.path.writeBytes
70-
import kotlinx.coroutines.Dispatchers
71-
import kotlinx.coroutines.withContext
7270

7371
open class RemoteTemplateProvider : TemplateProvider {
7472

@@ -150,20 +148,18 @@ open class RemoteTemplateProvider : TemplateProvider {
150148
context: WizardContext,
151149
repo: MinecraftSettings.TemplateRepo,
152150
rawInnerPath: String
153-
): List<LoadedTemplate> = withContext(Dispatchers.IO) { // don't run on EDT
151+
): List<LoadedTemplate> {
154152
val remoteRootPath = RemoteTemplateRepo.getDestinationZip(repo.name)
155153
if (!remoteRootPath.exists()) {
156-
return@withContext emptyList()
154+
return emptyList()
157155
}
158156

159157
val archiveRoot = remoteRootPath.absolutePathString() + JarFileSystem.JAR_SEPARATOR
160158

161159
val fs = JarFileSystem.getInstance()
162-
163160
val rootFile = fs.refreshAndFindFileByPath(archiveRoot)
164-
?: return@withContext emptyList()
161+
?: return emptyList()
165162
val modalityState = context.modalityState
166-
167163
rootFile.refreshSync(modalityState)
168164

169165
val innerPath = replaceVariables(rawInnerPath)
@@ -174,10 +170,10 @@ open class RemoteTemplateProvider : TemplateProvider {
174170
}
175171

176172
if (repoRoot == null) {
177-
return@withContext emptyList()
173+
return emptyList()
178174
}
179175

180-
return@withContext TemplateProvider.findTemplates(modalityState, repoRoot)
176+
return TemplateProvider.findTemplates(modalityState, repoRoot)
181177
}
182178

183179
private fun replaceVariables(originalRepoUrl: String): String =
@@ -271,7 +267,7 @@ open class RemoteTemplateProvider : TemplateProvider {
271267
index: Int,
272268
isSelected: Boolean,
273269
cellHasFocus: Boolean
274-
): Component {
270+
): Component? {
275271
text = value?.displayname?.let(MCDevBundle::invoke) ?: value?.name?.capitalize().toString()
276272
return this
277273
}

src/main/kotlin/creator/custom/providers/TemplateProvider.kt

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,9 @@ import com.intellij.serviceContainer.BaseKeyedLazyInstance
4545
import com.intellij.util.KeyedLazyInstance
4646
import com.intellij.util.xmlb.annotations.Attribute
4747
import java.util.ResourceBundle
48-
import java.util.concurrent.TimeUnit
4948
import javax.swing.JComponent
5049
import kotlinx.coroutines.Dispatchers
51-
import kotlinx.coroutines.withContext
52-
import org.jetbrains.concurrency.runAsync
50+
import kotlinx.coroutines.runBlocking
5351

5452
/**
5553
* Extensions responsible for creating a [TemplateDescriptor] based on whatever data it is provided in its configuration
@@ -81,8 +79,9 @@ interface TemplateProvider {
8179
modalityState: ModalityState,
8280
repoRoot: VirtualFile,
8381
templates: MutableList<VfsLoadedTemplate> = mutableListOf(),
84-
bundle: ResourceBundle? = loadMessagesBundle(modalityState, repoRoot)
85-
): List<VfsLoadedTemplate> = withContext(Dispatchers.IO) {
82+
bundle: ResourceBundle? = null
83+
): List<VfsLoadedTemplate> {
84+
val bundle = bundle ?: loadMessagesBundle(modalityState, repoRoot)
8685
val templatesToLoad = mutableListOf<VirtualFile>()
8786
val visitor = object : VirtualFileVisitor<Unit>() {
8887
override fun visitFile(file: VirtualFile): Boolean {
@@ -115,10 +114,10 @@ interface TemplateProvider {
115114
}
116115
}
117116

118-
templates
117+
return templates
119118
}
120119

121-
fun loadMessagesBundle(modalityState: ModalityState, repoRoot: VirtualFile): ResourceBundle? = try {
120+
suspend fun loadMessagesBundle(modalityState: ModalityState, repoRoot: VirtualFile): ResourceBundle? = try {
122121
val locale = DynamicBundle.getLocale()
123122
// Simplified bundle resolution, but covers all the most common cases
124123
val baseBundle = doLoadMessageBundle(
@@ -145,7 +144,7 @@ interface TemplateProvider {
145144
null
146145
}
147146

148-
private fun doLoadMessageBundle(
147+
private suspend fun doLoadMessageBundle(
149148
file: VirtualFile?,
150149
modalityState: ModalityState,
151150
parent: ResourceBundle?
@@ -155,9 +154,8 @@ interface TemplateProvider {
155154
}
156155

157156
try {
158-
return runAsync {
159-
file.inputStream.reader().use { TemplateResourceBundle(it, parent) }
160-
}.blockingGet(20, TimeUnit.MILLISECONDS)
157+
return file.refreshSync(modalityState)
158+
?.inputStream?.reader()?.use { TemplateResourceBundle(it, parent) }
161159
} catch (t: Throwable) {
162160
if (t is ControlFlowException) {
163161
return parent
@@ -169,19 +167,15 @@ interface TemplateProvider {
169167
return parent
170168
}
171169

172-
fun createVfsLoadedTemplate(
170+
suspend fun createVfsLoadedTemplate(
173171
modalityState: ModalityState,
174172
templateRoot: VirtualFile,
175173
descriptorFile: VirtualFile,
176174
tooltip: String? = null,
177175
bundle: ResourceBundle? = null
178176
): VfsLoadedTemplate? {
179-
var descriptor = runCatching {
180-
runAsync {
181-
descriptorFile.refreshSync(modalityState)
182-
Gson().fromJson<TemplateDescriptor>(descriptorFile.readText())
183-
}.blockingGet(100, TimeUnit.MILLISECONDS)
184-
}.getOrNull() ?: return null
177+
descriptorFile.refreshSync(modalityState)
178+
var descriptor = Gson().fromJson<TemplateDescriptor>(descriptorFile.readText())
185179
if (descriptor.version != TemplateDescriptor.FORMAT_VERSION) {
186180
thisLogger().warn("Cannot handle template ${descriptorFile.path} of version ${descriptor.version}")
187181
return null
@@ -200,7 +194,7 @@ interface TemplateProvider {
200194
descriptor.translateOrNull("platform.${labelKey.lowercase()}.label") ?: descriptor.translate(labelKey)
201195

202196
if (descriptor.inherit != null) {
203-
val parent = templateRoot.findFileByRelativePath(descriptor.inherit)
197+
val parent = templateRoot.findFileByRelativePath(descriptor.inherit!!)
204198
if (parent != null) {
205199
parent.refresh(false, false)
206200
val parentDescriptor = Gson().fromJson<TemplateDescriptor>(parent.readText())
@@ -237,5 +231,5 @@ class TemplateProviderBean : BaseKeyedLazyInstance<TemplateProvider>(), KeyedLaz
237231

238232
override fun getKey(): String = name
239233

240-
override fun getImplementationClassName(): String = implementation
234+
override fun getImplementationClassName(): String? = implementation
241235
}

0 commit comments

Comments
 (0)