@@ -2,6 +2,7 @@ package me.fornever.avaloniarider.previewer
22
33import com.intellij.execution.ui.ConsoleView
44import com.intellij.openapi.application.EDT
5+ import com.intellij.openapi.application.readAction
56import com.intellij.openapi.diagnostic.Logger
67import com.intellij.openapi.diagnostic.debug
78import com.intellij.openapi.editor.Document
@@ -11,6 +12,7 @@ import com.intellij.openapi.vfs.VirtualFile
1112import com.intellij.platform.backend.workspace.WorkspaceModel
1213import com.intellij.ui.scale.JBUIScale
1314import com.intellij.util.application
15+ import com.intellij.workspaceModel.ide.toPath
1416import com.jetbrains.rd.util.lifetime.Lifetime
1517import com.jetbrains.rd.util.lifetime.LifetimeDefinition
1618import com.jetbrains.rd.util.lifetime.SequentialLifetimes
@@ -22,21 +24,15 @@ import com.jetbrains.rd.util.throttleLast
2224import com.jetbrains.rider.build.BuildHost
2325import com.jetbrains.rider.model.riderSolutionLifecycle
2426import com.jetbrains.rider.projectView.solution
25- import com.intellij.workspaceModel.ide.toPath
2627import com.jetbrains.rider.projectView.workspace.ProjectModelEntity
2728import com.jetbrains.rider.projectView.workspace.containingProjectEntity
2829import com.jetbrains.rider.projectView.workspace.getProjectModelEntities
2930import com.jetbrains.rider.ui.SwingScheduler
3031import com.jetbrains.rider.ui.components.utils.documentChanged
31- import kotlinx.coroutines.CancellationException
32- import kotlinx.coroutines.CompletableDeferred
33- import kotlinx.coroutines.Dispatchers
34- import kotlinx.coroutines.Job
32+ import kotlinx.coroutines.*
3533import kotlinx.coroutines.channels.BufferOverflow
36- import kotlinx.coroutines.delay
3734import kotlinx.coroutines.flow.MutableSharedFlow
3835import kotlinx.coroutines.flow.collectLatest
39- import kotlinx.coroutines.withContext
4036import me.fornever.avaloniarider.AvaloniaRiderBundle
4137import me.fornever.avaloniarider.controlmessages.AvaloniaInputEventMessage
4238import me.fornever.avaloniarider.controlmessages.FrameMessage
@@ -56,6 +52,8 @@ import java.net.SocketException
5652import java.nio.file.Files
5753import java.nio.file.Path
5854import java.time.Duration
55+ import kotlin.coroutines.resume
56+ import kotlin.coroutines.resumeWithException
5957
6058/* *
6159 * The sources on this class are thread-free. Make sure to schedule them onto the proper threads if necessary.
@@ -182,38 +180,36 @@ class AvaloniaPreviewerSessionController(
182180 }
183181 }
184182
185- private suspend fun getProjectContainingFile (virtualFile : VirtualFile ): ProjectModelEntity ? {
186- application.assertIsDispatchThread()
187-
188- val result = CompletableDeferred <ProjectModelEntity ?>()
183+ private suspend fun getProjectContainingFile (virtualFile : VirtualFile ): ProjectModelEntity ? =
184+ suspendCancellableCoroutine { cont ->
185+ Lifetime .using { lt ->
186+ application.assertIsDispatchThread()
187+
188+ project.solution.riderSolutionLifecycle.isProjectModelReady.adviseUntil(lt) { isReady ->
189+ if (! isReady) return @adviseUntil false
190+ try {
191+ logger.debug { " Project model view synchronized" }
192+ val projectModelEntities = workspaceModel.getProjectModelEntities(virtualFile, project)
193+ logger.debug {
194+ " Project model nodes for file $xamlFile : " + projectModelEntities.joinToString(" , " )
195+ }
196+ val containingProject =
197+ projectModelEntities.firstNotNullOfOrNull { it.containingProjectEntity() }
198+ if (containingProject != null ) {
199+ cont.resume(containingProject)
200+ } else {
201+ logger.warn(" Workspace model doesn't contain project entity for $virtualFile " )
202+ cont.resume(null )
203+ }
204+ } catch (t: Throwable ) {
205+ cont.resumeWithException(t)
206+ }
189207
190- project.solution.riderSolutionLifecycle.isProjectModelReady.adviseUntil(controllerLifetime) { isReady ->
191- if (! isReady) return @adviseUntil false
192- try {
193- logger.debug { " Project model view synchronized" }
194- val projectModelEntities = workspaceModel.getProjectModelEntities(virtualFile, project)
195- logger.debug {
196- " Project model nodes for file $xamlFile : " + projectModelEntities.joinToString(" , " )
197- }
198- val containingProject = projectModelEntities.asSequence()
199- .mapNotNull { it.containingProjectEntity() }
200- .firstOrNull()
201- if (containingProject != null ) {
202- result.complete(containingProject)
203- } else {
204- logger.warn(" Workspace model doesn't contain project entity for $virtualFile " )
205- result.complete(null )
208+ return @adviseUntil true
206209 }
207- } catch (t: Throwable ) {
208- result.completeExceptionally(t)
209210 }
210-
211- return @adviseUntil true
212211 }
213212
214- return result.await()
215- }
216-
217213 private fun createSession (
218214 lifetime : Lifetime ,
219215 socket : ServerSocket ,
@@ -240,7 +236,7 @@ class AvaloniaPreviewerSessionController(
240236
241237 suspend fun dispatchXamlUpdate () {
242238 while (lifetime.isAlive) {
243- val (text, projectRelativePath) = application.runReadAction< Pair < String , String ?>> {
239+ val (text, projectRelativePath) = readAction {
244240 document.text to computeDocumentPathInProject(projectFilePathProperty.valueOrNull)
245241 }
246242 val effectivePath = projectRelativePath ? : lastKnownProjectRelativePath
@@ -249,7 +245,7 @@ class AvaloniaPreviewerSessionController(
249245 if (lastKnownProjectRelativePath == null ) {
250246 logger.warn(message)
251247 } else {
252- logger.debug { message }
248+ logger.info( message)
253249 }
254250 inFlightUpdate.value = false
255251 delay(projectPathRetryDelay.toMillis())
0 commit comments