@@ -39,6 +39,11 @@ data class AvaloniaPreviewerParameters(
3939 val workingDirectory : Path
4040)
4141
42+ data class AvaloniaPreviewerProcessResult (
43+ val exitCode : Int? ,
44+ val outputSnippet : String?
45+ )
46+
4247class AvaloniaPreviewerProcess (
4348 private val project : Project ,
4449 private val lifetime : Lifetime ,
@@ -79,16 +84,18 @@ class AvaloniaPreviewerProcess(
7984 executionMode : ProcessExecutionMode ,
8085 commandLine : GeneralCommandLine ,
8186 consoleView : ConsoleView ? ,
82- title : String
87+ title : String ,
88+ outputListener : (String ) -> Unit = {}
8389 ): ProcessHandler = when (executionMode) {
84- ProcessExecutionMode .Run -> runProcess(commandLine, consoleView, title)
90+ ProcessExecutionMode .Run -> runProcess(commandLine, consoleView, title, outputListener )
8591 ProcessExecutionMode .Debug -> debugProcess(commandLine, consoleView)
8692 }
8793
8894 private fun runProcess (
8995 commandLine : GeneralCommandLine ,
9096 consoleView : ConsoleView ? ,
91- title : String
97+ title : String ,
98+ outputListener : (String ) -> Unit
9299 ): OSProcessHandler {
93100 val processHandler = lifetime.bracketOrThrowEx({
94101 object : OSProcessHandler (commandLine) {
@@ -97,6 +104,7 @@ class AvaloniaPreviewerProcess(
97104
98105 override fun notifyTextAvailable (text : String , outputType : Key <* >) {
99106 logger.info(" $title [$outputType ]: $text " )
107+ outputListener(text)
100108 super .notifyTextAvailable(text, outputType)
101109 }
102110
@@ -158,13 +166,41 @@ class AvaloniaPreviewerProcess(
158166 transport : PreviewerTransport ,
159167 method : PreviewerMethod ,
160168 title : String
161- ) {
169+ ): AvaloniaPreviewerProcessResult {
162170 logger.info(" 1/4: generating process command line" )
163171 val commandLine = getCommandLine(transport, method)
164172 logger.info(" 2/3: starting a process" )
165- val process = startProcess(executionMode, commandLine, consoleView, title)
173+ val outputCollector = OutputCollector ()
174+ val process = startProcess(
175+ executionMode,
176+ commandLine,
177+ consoleView,
178+ title,
179+ outputCollector::append
180+ )
166181 logger.info(" 3/3: awaiting termination" )
167182 waitForTermination(process, title)
183+ val exitCode = process.exitCode
184+ val outputSnippet = outputCollector.content()
185+ return AvaloniaPreviewerProcessResult (exitCode, outputSnippet)
186+ }
187+
188+ private class OutputCollector (private val maxChars : Int = 32 * 1024 ) {
189+ private val buffer = StringBuilder ()
190+
191+ fun append (text : String ) {
192+ synchronized(buffer) {
193+ buffer.append(text)
194+ if (buffer.length > maxChars) {
195+ val excess = buffer.length - maxChars
196+ buffer.delete(0 , excess)
197+ }
198+ }
199+ }
200+
201+ fun content (): String? = synchronized(buffer) {
202+ if (buffer.isEmpty()) null else buffer.toString()
203+ }
168204 }
169205}
170206
0 commit comments