mirror of
				https://github.com/JakeWharton/mosaic.git
				synced 2025-11-01 03:43:31 +08:00 
			
		
		
		
	Rename render to draw
I want rendering to be a different step which aggregates canvases together into the final output.
This commit is contained in:
		 Jake Wharton
					Jake Wharton
				
			
				
					committed by
					
						 Jake Wharton
						Jake Wharton
					
				
			
			
				
	
			
			
			 Jake Wharton
						Jake Wharton
					
				
			
						parent
						
							1cf9e2e2a0
						
					
				
				
					commit
					5383798ea6
				
			| @ -16,30 +16,30 @@ public fun <T> Static( | ||||
| 	items: Flow<T>, | ||||
| 	content: @Composable (T) -> Unit, | ||||
| ) { | ||||
| 	class Item(val value: T, var rendered: Boolean) | ||||
| 	class Item(val value: T, var drawn: Boolean) | ||||
|  | ||||
| 	// Keep list of items which have not yet been rendered. | ||||
| 	// Keep list of items which have not yet been drawn. | ||||
| 	val pending = remember { mutableStateListOf<Item>() } | ||||
|  | ||||
| 	LaunchedEffect(items) { | ||||
| 		items.collect { | ||||
| 			pending.add(Item(it, rendered = false)) | ||||
| 			pending.add(Item(it, drawn = false)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ComposeNode<StaticNode, MosaicNodeApplier>( | ||||
| 		factory = { | ||||
| 			StaticNode { | ||||
| 				pending.removeAll { it.rendered } | ||||
| 				pending.removeAll { it.drawn } | ||||
| 			} | ||||
| 		}, | ||||
| 		update = {}, | ||||
| 		content = { | ||||
| 			for (item in pending) { | ||||
| 				Row { | ||||
| 					// Render item and mark it as having been included in render. | ||||
| 					// Draw item and mark it as such. | ||||
| 					content(item.value) | ||||
| 					item.rendered = true | ||||
| 					item.drawn = true | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| @ -47,7 +47,7 @@ public fun <T> Static( | ||||
| } | ||||
|  | ||||
| internal class StaticNode( | ||||
| 	private val postRender: () -> Unit, | ||||
| 	private val onPostDraw: () -> Unit, | ||||
| ) : ContainerNode() { | ||||
| 	// Delegate container column for static content. | ||||
| 	private val box = LinearNode(isRow = false) | ||||
| @ -63,25 +63,25 @@ internal class StaticNode( | ||||
| 		// Not visible. | ||||
| 	} | ||||
|  | ||||
| 	override fun renderTo(canvas: TextCanvas) { | ||||
| 	override fun drawTo(canvas: TextCanvas) { | ||||
| 		// No content. | ||||
| 	} | ||||
|  | ||||
| 	override fun renderStatics(): List<TextCanvas> { | ||||
| 	override fun drawStatics(): List<TextCanvas> { | ||||
| 		val statics = mutableListOf<TextCanvas>() | ||||
|  | ||||
| 		// Render contents of static node to a separate display. | ||||
| 		val static = box.render() | ||||
| 		// Draw contents of static node to a separate node hierarchy. | ||||
| 		val static = box.draw() | ||||
|  | ||||
| 		// Add display canvas to static canvases if it is not empty. | ||||
| 		if (static.width > 0 && static.height > 0) { | ||||
| 			statics.add(static) | ||||
| 		} | ||||
|  | ||||
| 		// Propagate any static content of the display. | ||||
| 		statics.addAll(box.renderStatics()) | ||||
| 		// Propagate any static content of this static node. | ||||
| 		statics.addAll(box.drawStatics()) | ||||
|  | ||||
| 		postRender() | ||||
| 		onPostDraw() | ||||
|  | ||||
| 		return statics | ||||
| 	} | ||||
|  | ||||
| @ -51,8 +51,8 @@ public suspend fun runMosaic(body: suspend MosaicScope.() -> Unit): Unit = corou | ||||
| 				hasFrameWaiters = false | ||||
| 				clock.sendFrame(0L) // Frame time value is not used by Compose runtime. | ||||
|  | ||||
| 				val canvas = rootNode.render() | ||||
| 				val statics = rootNode.renderStatics() | ||||
| 				val canvas = rootNode.draw() | ||||
| 				val statics = rootNode.drawStatics() | ||||
| 				output.display(canvas, statics) | ||||
|  | ||||
| 				displaySignal?.complete(Unit) | ||||
|  | ||||
| @ -9,26 +9,26 @@ internal sealed class MosaicNode { | ||||
| 	var height = 0 | ||||
|  | ||||
| 	// These two values are set by a call to `layout` on the parent node. | ||||
| 	/** Pixels right relative to parent at which this node will render. */ | ||||
| 	/** Pixels right relative to parent at which this node will draw. */ | ||||
| 	var x = 0 | ||||
| 	/** Pixels down relative to parent at which this node will render. */ | ||||
| 	/** Pixels down relative to parent at which this node will draw. */ | ||||
| 	var y = 0 | ||||
|  | ||||
| 	/** Measure this node (and any children) and update [width] and [height]. */ | ||||
| 	abstract fun measure() | ||||
| 	/** Layout any children nodes and update their [x] and [y] relative to this node. */ | ||||
| 	abstract fun layout() | ||||
| 	abstract fun renderTo(canvas: TextCanvas) | ||||
| 	abstract fun drawTo(canvas: TextCanvas) | ||||
|  | ||||
| 	fun render(): TextCanvas { | ||||
| 	fun draw(): TextCanvas { | ||||
| 		measure() | ||||
| 		layout() | ||||
| 		val canvas = TextSurface(width, height) | ||||
| 		renderTo(canvas) | ||||
| 		drawTo(canvas) | ||||
| 		return canvas | ||||
| 	} | ||||
|  | ||||
| 	abstract fun renderStatics(): List<TextCanvas> | ||||
| 	abstract fun drawStatics(): List<TextCanvas> | ||||
| } | ||||
|  | ||||
| internal class TextNode(initialValue: String = "") : MosaicNode() { | ||||
| @ -56,13 +56,13 @@ internal class TextNode(initialValue: String = "") : MosaicNode() { | ||||
| 		// No children. | ||||
| 	} | ||||
|  | ||||
| 	override fun renderTo(canvas: TextCanvas) { | ||||
| 	override fun drawTo(canvas: TextCanvas) { | ||||
| 		value.split('\n').forEachIndexed { index, line -> | ||||
| 			canvas.write(index, 0, line, foreground, background, style) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	override fun renderStatics() = emptyList<TextCanvas>() | ||||
| 	override fun drawStatics() = emptyList<TextCanvas>() | ||||
|  | ||||
| 	override fun toString() = "Text(\"$value\", x=$x, y=$y, width=$width, height=$height)" | ||||
| } | ||||
| @ -134,22 +134,22 @@ internal class LinearNode(var isRow: Boolean = true) : ContainerNode() { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	override fun renderTo(canvas: TextCanvas) { | ||||
| 	override fun drawTo(canvas: TextCanvas) { | ||||
| 		for (child in children) { | ||||
| 			if (child.width != 0 && child.height != 0) { | ||||
| 				val left = child.x | ||||
| 				val top = child.y | ||||
| 				val right = left + child.width - 1 | ||||
| 				val bottom = top + child.height - 1 | ||||
| 				child.renderTo(canvas[top..bottom, left..right]) | ||||
| 				child.drawTo(canvas[top..bottom, left..right]) | ||||
| 			} else { | ||||
| 				child.renderTo(canvas.empty()) | ||||
| 				child.drawTo(canvas.empty()) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	override fun renderStatics(): List<TextCanvas> { | ||||
| 		return children.flatMap(MosaicNode::renderStatics) | ||||
| 	override fun drawStatics(): List<TextCanvas> { | ||||
| 		return children.flatMap(MosaicNode::drawStatics) | ||||
| 	} | ||||
|  | ||||
| 	override fun toString() = children.joinToString(prefix = "Box(", postfix = ")") | ||||
|  | ||||
		Reference in New Issue
	
	Block a user