mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
IJPL-158385 ToolboxUpdateActions - use coroutine scope, avoid Disposable
GitOrigin-RevId: a2e45785e0324d654c6f9747816ae2609d8fc171
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cfaad7d6fe
commit
8fa4a1fc9a
@@ -283,9 +283,7 @@ f:org.jetbrains.ide.ToolboxIdeExitHandler$ExitParameters
|
||||
f:org.jetbrains.ide.ToolboxRestServiceKt
|
||||
- sf:getToolboxHandlerEP():com.intellij.openapi.extensions.ExtensionPointName
|
||||
f:org.jetbrains.ide.ToolboxSettingsActionRegistry
|
||||
- com.intellij.openapi.Disposable
|
||||
- <init>():V
|
||||
- dispose():V
|
||||
- <init>(kotlinx.coroutines.CoroutineScope):V
|
||||
- f:getActions():java.util.List
|
||||
- f:isNewAction(java.lang.String):Z
|
||||
- f:markAsRead(java.lang.String):V
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.ide
|
||||
|
||||
import com.intellij.ide.actions.SettingsEntryPointAction
|
||||
@@ -7,24 +7,38 @@ import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.util.Alarm
|
||||
import com.intellij.util.messages.Topic
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue
|
||||
import com.intellij.util.ui.update.Update
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import org.jetbrains.annotations.Nls
|
||||
import java.util.*
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
@Service(Service.Level.APP)
|
||||
class ToolboxSettingsActionRegistry : Disposable {
|
||||
class ToolboxSettingsActionRegistry(coroutineScope: CoroutineScope) {
|
||||
private val readActions = Collections.synchronizedSet(HashSet<String>())
|
||||
private val pendingActions = Collections.synchronizedList(LinkedList<ToolboxUpdateAction>())
|
||||
|
||||
private val alarm = MergingUpdateQueue("toolbox-updates", 500, true, null, this, null, Alarm.ThreadToUse.SWING_THREAD).usePassThroughInUnitTestMode()
|
||||
private val updateRequests = MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
|
||||
override fun dispose() = Unit
|
||||
init {
|
||||
coroutineScope.launch {
|
||||
updateRequests
|
||||
.debounce(500)
|
||||
.collectLatest {
|
||||
withContext(Dispatchers.EDT) {
|
||||
SettingsEntryPointAction.updateState()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isNewAction(actionId: String) = actionId !in readActions
|
||||
|
||||
@@ -33,11 +47,12 @@ class ToolboxSettingsActionRegistry : Disposable {
|
||||
}
|
||||
|
||||
fun scheduleUpdate() {
|
||||
alarm.queue(object: Update(this){
|
||||
override fun run() {
|
||||
SettingsEntryPointAction.updateState()
|
||||
}
|
||||
})
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
SettingsEntryPointAction.updateState()
|
||||
}
|
||||
else {
|
||||
check(updateRequests.tryEmit(Unit))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun registerUpdateAction(action: ToolboxUpdateAction) {
|
||||
|
||||
@@ -3196,6 +3196,8 @@ c:com.intellij.util.ui.update.MergingUpdateQueue
|
||||
- <init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable):V
|
||||
- <init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable,javax.swing.JComponent):V
|
||||
- <init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable,javax.swing.JComponent,com.intellij.util.Alarm$ThreadToUse):V
|
||||
- <init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable,javax.swing.JComponent,com.intellij.util.Alarm$ThreadToUse,kotlinx.coroutines.CoroutineScope):V
|
||||
- b:<init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable,javax.swing.JComponent,com.intellij.util.Alarm$ThreadToUse,kotlinx.coroutines.CoroutineScope,I,kotlin.jvm.internal.DefaultConstructorMarker):V
|
||||
- <init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable,javax.swing.JComponent,Z):V
|
||||
- b:<init>(java.lang.String,I,Z,javax.swing.JComponent,com.intellij.openapi.Disposable,javax.swing.JComponent,Z,I,kotlin.jvm.internal.DefaultConstructorMarker):V
|
||||
- f:activate():V
|
||||
|
||||
@@ -18,7 +18,7 @@ import com.intellij.util.Alarm
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.intellij.util.ui.EdtInvocationManager
|
||||
import com.intellij.util.ui.update.UiNotifyConnector.Companion.installOn
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
@@ -50,14 +50,15 @@ import kotlin.concurrent.Volatile
|
||||
* @param activationComponent if not `null` the tasks will be processing only when the given component is showing
|
||||
* @param thread specifies on which thread the tasks are executed
|
||||
*/
|
||||
open class MergingUpdateQueue(
|
||||
open class MergingUpdateQueue @JvmOverloads constructor(
|
||||
private val name: @NonNls String,
|
||||
private var mergingTimeSpan: Int,
|
||||
isActive: Boolean,
|
||||
private var modalityStateComponent: JComponent?,
|
||||
parent: Disposable?,
|
||||
activationComponent: JComponent?,
|
||||
thread: Alarm.ThreadToUse
|
||||
thread: Alarm.ThreadToUse,
|
||||
coroutineScope: CoroutineScope? = null,
|
||||
) : Disposable, Activatable {
|
||||
@Volatile
|
||||
var isSuspended: Boolean = false
|
||||
@@ -111,6 +112,7 @@ open class MergingUpdateQueue(
|
||||
parent = parent,
|
||||
activationComponent = activationComponent,
|
||||
thread = if (executeInDispatchThread) Alarm.ThreadToUse.SWING_THREAD else Alarm.ThreadToUse.POOLED_THREAD,
|
||||
coroutineScope = null,
|
||||
)
|
||||
|
||||
init {
|
||||
@@ -119,7 +121,17 @@ open class MergingUpdateQueue(
|
||||
Disposer.register(parent, this)
|
||||
}
|
||||
|
||||
waiterForMerge = if (executeInDispatchThread) Alarm(threadToUse = thread) else Alarm(threadToUse = thread, parentDisposable = this)
|
||||
waiterForMerge = if (coroutineScope == null) {
|
||||
if (executeInDispatchThread) {
|
||||
Alarm(threadToUse = thread)
|
||||
}
|
||||
else {
|
||||
Alarm(threadToUse = thread, parentDisposable = this)
|
||||
}
|
||||
}
|
||||
else {
|
||||
Alarm(threadToUse = thread, coroutineScope = coroutineScope)
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
showNotify()
|
||||
@@ -139,6 +151,42 @@ open class MergingUpdateQueue(
|
||||
@JvmField
|
||||
val ANY_COMPONENT: JComponent = object : JComponent() {}
|
||||
|
||||
@Internal
|
||||
fun edtMergingUpdateQueue(
|
||||
name: String,
|
||||
mergingTimeSpan: Int,
|
||||
coroutineScope: CoroutineScope,
|
||||
): MergingUpdateQueue {
|
||||
return MergingUpdateQueue(
|
||||
name = name,
|
||||
mergingTimeSpan = mergingTimeSpan,
|
||||
isActive = true,
|
||||
modalityStateComponent = null,
|
||||
parent = null,
|
||||
activationComponent = null,
|
||||
thread = Alarm.ThreadToUse.SWING_THREAD,
|
||||
coroutineScope = coroutineScope,
|
||||
)
|
||||
}
|
||||
|
||||
@Internal
|
||||
fun mergingUpdateQueue(
|
||||
name: String,
|
||||
mergingTimeSpan: Int,
|
||||
coroutineScope: CoroutineScope,
|
||||
): MergingUpdateQueue {
|
||||
return MergingUpdateQueue(
|
||||
name = name,
|
||||
mergingTimeSpan = mergingTimeSpan,
|
||||
isActive = true,
|
||||
modalityStateComponent = null,
|
||||
parent = null,
|
||||
activationComponent = null,
|
||||
thread = Alarm.ThreadToUse.POOLED_THREAD,
|
||||
coroutineScope = coroutineScope,
|
||||
)
|
||||
}
|
||||
|
||||
private val queues: MutableSet<MergingUpdateQueue>? = if (SystemProperties.getBooleanProperty("intellij.MergingUpdateQueue.enable.global.flusher", false)) {
|
||||
ConcurrentCollectionFactory.createConcurrentSet()
|
||||
}
|
||||
@@ -146,7 +194,7 @@ open class MergingUpdateQueue(
|
||||
null
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Internal
|
||||
fun flushAllQueues() {
|
||||
if (queues != null) {
|
||||
for (queue in queues) {
|
||||
@@ -185,7 +233,7 @@ open class MergingUpdateQueue(
|
||||
* It is needed to support some old tests, which expect such behaviour.
|
||||
* @return this instance for the sequential creation (the Builder pattern)
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Internal
|
||||
@Deprecated(
|
||||
"""use {@link #waitForAllExecuted(long, TimeUnit)} instead in tests
|
||||
""")
|
||||
@@ -240,8 +288,8 @@ open class MergingUpdateQueue(
|
||||
restart(mergingTimeSpan)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
open protected fun getFlushTask(): Runnable = flushTask
|
||||
@Internal
|
||||
protected open fun getFlushTask(): Runnable = flushTask
|
||||
|
||||
private fun restart(mergingTimeSpanMillis: Int) {
|
||||
if (!isActive) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.openapi.wm.impl.welcomeScreen.recentProjects
|
||||
|
||||
import com.intellij.ide.RecentProjectsManager
|
||||
@@ -61,8 +61,15 @@ internal object RecentProjectPanelComponentFactory {
|
||||
}
|
||||
})
|
||||
|
||||
val updateQueue = MergingUpdateQueue("Welcome screen UI updater", UPDATE_INTERVAL, true, null,
|
||||
parentDisposable, tree, Alarm.ThreadToUse.SWING_THREAD)
|
||||
val updateQueue = MergingUpdateQueue(
|
||||
name = "Welcome screen UI updater",
|
||||
mergingTimeSpan = UPDATE_INTERVAL,
|
||||
isActive = true,
|
||||
modalityStateComponent = null,
|
||||
parent = parentDisposable,
|
||||
activationComponent = tree,
|
||||
thread = Alarm.ThreadToUse.SWING_THREAD,
|
||||
)
|
||||
updateQueue.queue(Update.create(filteringTree, Runnable { repaintProgressBars(updateQueue, filteringTree) }))
|
||||
|
||||
return filteringTree
|
||||
|
||||
Reference in New Issue
Block a user