mirror of
				https://github.com/JakeWharton/mosaic.git
				synced 2025-11-04 06:32:26 +08:00 
			
		
		
		
	Enable debug rendering at runtime (#714)
Set MOSAIC_DEBUG_RENDERING=true env var.
This commit is contained in:
		@ -57,12 +57,6 @@ import kotlinx.coroutines.launch
 | 
				
			|||||||
import kotlinx.coroutines.runBlocking
 | 
					import kotlinx.coroutines.runBlocking
 | 
				
			||||||
import kotlinx.coroutines.withTimeoutOrNull
 | 
					import kotlinx.coroutines.withTimeoutOrNull
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * True for a debug-like output that renders each "frame" on its own with a timestamp delta.
 | 
					 | 
				
			||||||
 * False when using ANSI control sequences to overwrite output.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
private const val debugOutput = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public fun renderMosaic(content: @Composable () -> Unit): String {
 | 
					public fun renderMosaic(content: @Composable () -> Unit): String {
 | 
				
			||||||
	val mosaicComposition = MosaicComposition(
 | 
						val mosaicComposition = MosaicComposition(
 | 
				
			||||||
		coroutineContext = BroadcastFrameClock(),
 | 
							coroutineContext = BroadcastFrameClock(),
 | 
				
			||||||
@ -330,7 +324,7 @@ private fun createRendering(
 | 
				
			|||||||
	ansiLevel: AnsiLevel = AnsiLevel.TRUECOLOR,
 | 
						ansiLevel: AnsiLevel = AnsiLevel.TRUECOLOR,
 | 
				
			||||||
	synchronizedRendering: Boolean = false,
 | 
						synchronizedRendering: Boolean = false,
 | 
				
			||||||
): Rendering {
 | 
					): Rendering {
 | 
				
			||||||
	return if (debugOutput) {
 | 
						return if (env("MOSAIC_DEBUG_RENDERING") == "true") {
 | 
				
			||||||
		DebugRendering(ansiLevel = ansiLevel)
 | 
							DebugRendering(ansiLevel = ansiLevel)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		AnsiRendering(ansiLevel, synchronizedRendering)
 | 
							AnsiRendering(ansiLevel, synchronizedRendering)
 | 
				
			||||||
 | 
				
			|||||||
@ -21,45 +21,54 @@ internal class DebugRendering(
 | 
				
			|||||||
) : Rendering {
 | 
					) : Rendering {
 | 
				
			||||||
	private var lastRender: TimeMark? = null
 | 
						private var lastRender: TimeMark? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fun StringBuilder.appendSurface(canvas: TextCanvas) {
 | 
				
			||||||
 | 
							for (row in 0 until canvas.height) {
 | 
				
			||||||
 | 
								canvas.appendRowTo(this, row, ansiLevel)
 | 
				
			||||||
 | 
								append("\r\n")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override fun render(mosaic: Mosaic): CharSequence {
 | 
						override fun render(mosaic: Mosaic): CharSequence {
 | 
				
			||||||
		var failed = false
 | 
							var failed = false
 | 
				
			||||||
		val output = buildString {
 | 
							val output = buildString {
 | 
				
			||||||
			lastRender?.let { lastRender ->
 | 
								lastRender?.let { lastRender ->
 | 
				
			||||||
				repeat(50) { append('~') }
 | 
									repeat(50) { append('~') }
 | 
				
			||||||
				append(" +")
 | 
									append(" +")
 | 
				
			||||||
				appendLine(lastRender.elapsedNow())
 | 
									append(lastRender.elapsedNow())
 | 
				
			||||||
 | 
									append("\r\n")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			lastRender = systemClock.markNow()
 | 
								lastRender = systemClock.markNow()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			appendLine("NODES:")
 | 
								append("NODES:\r\n")
 | 
				
			||||||
			appendLine(mosaic.dump())
 | 
								append(mosaic.dump().replace("\n", "\r\n"))
 | 
				
			||||||
			appendLine()
 | 
								append("\r\n\r\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			val statics = mutableObjectListOf<TextCanvas>()
 | 
								val statics = mutableObjectListOf<TextCanvas>()
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				mosaic.paintStaticsTo(statics)
 | 
									mosaic.paintStaticsTo(statics)
 | 
				
			||||||
				if (statics.isNotEmpty()) {
 | 
									if (statics.isNotEmpty()) {
 | 
				
			||||||
					appendLine("STATIC:")
 | 
										append("STATIC:\r\n")
 | 
				
			||||||
					statics.forEach { static ->
 | 
										statics.forEach { static ->
 | 
				
			||||||
						appendLine(static.render(ansiLevel))
 | 
											appendSurface(static)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					appendLine()
 | 
										append("\r\n")
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} catch (t: Throwable) {
 | 
								} catch (t: Throwable) {
 | 
				
			||||||
				failed = true
 | 
									failed = true
 | 
				
			||||||
				appendLine(t.stackTraceToString())
 | 
									append(t.stackTraceToString().replace("\n", "\r\n"))
 | 
				
			||||||
 | 
									append("\r\n")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			appendLine("OUTPUT:")
 | 
								append("OUTPUT:\r\n")
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				appendLine(mosaic.paint().render(ansiLevel))
 | 
									appendSurface(mosaic.paint())
 | 
				
			||||||
			} catch (t: Throwable) {
 | 
								} catch (t: Throwable) {
 | 
				
			||||||
				failed = true
 | 
									failed = true
 | 
				
			||||||
				append(t.stackTraceToString())
 | 
									append(t.stackTraceToString().replace("\n", "\r\n"))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (failed) {
 | 
							if (failed) {
 | 
				
			||||||
			throw RuntimeException("Failed\n\n$output")
 | 
								throw RuntimeException("Failed\r\n\r\n$output")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return output
 | 
							return output
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -49,8 +49,8 @@ class DebugRenderingTest {
 | 
				
			|||||||
					|  Layout\(\) x=6 y=0 w=5 h=1 DrawBehind
 | 
										|  Layout\(\) x=6 y=0 w=5 h=1 DrawBehind
 | 
				
			||||||
					|
 | 
										|
 | 
				
			||||||
					|OUTPUT:
 | 
										|OUTPUT:
 | 
				
			||||||
					|(kotlin\.|java\.lang\.)?UnsupportedOperationException:?
 | 
										|(kotlin\.|java\.lang\.)?UnsupportedOperationException
 | 
				
			||||||
					""".trimMargin().toRegex(),
 | 
										""".trimMargin().replaceLineEndingsWithCRLF().toRegex(),
 | 
				
			||||||
				)
 | 
									)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -77,7 +77,7 @@ class DebugRenderingTest {
 | 
				
			|||||||
				|OUTPUT:
 | 
									|OUTPUT:
 | 
				
			||||||
				|Hello
 | 
									|Hello
 | 
				
			||||||
				|
 | 
									|
 | 
				
			||||||
				""".trimMargin(),
 | 
									""".trimMargin().replaceLineEndingsWithCRLF(),
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -96,7 +96,7 @@ class DebugRenderingTest {
 | 
				
			|||||||
				|OUTPUT:
 | 
									|OUTPUT:
 | 
				
			||||||
				|Hello
 | 
									|Hello
 | 
				
			||||||
				|
 | 
									|
 | 
				
			||||||
				""".trimMargin(),
 | 
									""".trimMargin().replaceLineEndingsWithCRLF(),
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			timeSource += 100.milliseconds
 | 
								timeSource += 100.milliseconds
 | 
				
			||||||
@ -113,7 +113,7 @@ class DebugRenderingTest {
 | 
				
			|||||||
				|OUTPUT:
 | 
									|OUTPUT:
 | 
				
			||||||
				|Hey!
 | 
									|Hey!
 | 
				
			||||||
				|
 | 
									|
 | 
				
			||||||
				""".trimMargin(),
 | 
									""".trimMargin().replaceLineEndingsWithCRLF(),
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user