mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
LLM-12328 Subscribe listeners with a plugin service scope disposable
Add util methods for creating or binding a disposable to a CoroutineScope. (cherry picked from commit f03d5ae7601941ca59ddf483210d2426aabb4944) GitOrigin-RevId: d39517066a3cd63c25b18c119f605e14b1b58d16
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5945a6d2c6
commit
c627d8d26d
@@ -972,7 +972,6 @@ public final class EditorUtil {
|
||||
}
|
||||
|
||||
public static void disposeWithEditor(@NotNull Editor editor, @NotNull Disposable disposable) {
|
||||
ThreadingAssertions.assertEventDispatchThread();
|
||||
ReadAction.run(() -> {
|
||||
if (editor.isDisposed()) {
|
||||
Disposer.dispose(disposable);
|
||||
|
||||
@@ -3,11 +3,15 @@ package com.intellij.util
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.job
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental
|
||||
import org.jetbrains.annotations.ApiStatus.Internal
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
@Internal
|
||||
@Experimental
|
||||
@@ -21,3 +25,37 @@ fun Job.cancelOnDispose(disposable: Disposable, disposeOnCompletion: Boolean = t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches [this] disposable to a scope [cs] so that when [cs] is canceled, [this] is also disposed.
|
||||
*
|
||||
* When [this] disposable is disposed from another place [cs] won't be touched.
|
||||
*/
|
||||
fun Disposable.attachAsChildTo(cs: CoroutineScope) {
|
||||
val disposableRef = AtomicReference<Disposable?>(this)
|
||||
val job = cs.launch {
|
||||
try {
|
||||
awaitCancellation()
|
||||
}
|
||||
finally {
|
||||
disposableRef.getAndSet(null)?.let {
|
||||
Disposer.dispose(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
val registered = Disposer.tryRegister(this) {
|
||||
disposableRef.getAndSet(null)?.let {
|
||||
job.cancel("disposed")
|
||||
}
|
||||
}
|
||||
if (!registered) job.cancel("disposable is already disposed")
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a disposable that will be disposed on [this] scope cancellation.
|
||||
*
|
||||
* Manual disposal of a created Disposable is also possible and doesn't touch [this] scope.
|
||||
*/
|
||||
fun CoroutineScope.asDisposable(): Disposable {
|
||||
return Disposer.newDisposable("Disposable from scope: $this").also { it.attachAsChildTo(this) }
|
||||
}
|
||||
Reference in New Issue
Block a user