diff --git a/zircon.core/src/commonTest/kotlin/org/hexworks/zircon/internal/renderer/TestRenderer.kt b/zircon.core/src/commonTest/kotlin/org/hexworks/zircon/internal/renderer/TestRenderer.kt new file mode 100644 index 0000000000..a758c6167e --- /dev/null +++ b/zircon.core/src/commonTest/kotlin/org/hexworks/zircon/internal/renderer/TestRenderer.kt @@ -0,0 +1,79 @@ +package org.hexworks.zircon.internal.renderer + +import org.hexworks.cobalt.databinding.api.extension.toProperty +import org.hexworks.cobalt.databinding.api.property.Property +import org.hexworks.cobalt.databinding.api.value.ObservableValue +import org.hexworks.zircon.api.behavior.Clearable +import org.hexworks.zircon.api.component.ComponentContainer +import org.hexworks.zircon.api.data.Size +import org.hexworks.zircon.api.graphics.TileGraphics +import org.hexworks.zircon.api.grid.TileGrid +import org.hexworks.zircon.api.resource.TilesetResource +import org.hexworks.zircon.api.uievent.UIEvent +import org.hexworks.zircon.api.uievent.UIEventResponse +import org.hexworks.zircon.api.view.base.BaseView +import org.hexworks.zircon.internal.behavior.RenderableContainer +import org.hexworks.zircon.internal.config.RuntimeConfig +import org.hexworks.zircon.internal.graphics.FastTileGraphics +import org.hexworks.zircon.internal.grid.ThreadSafeTileGrid +import org.hexworks.zircon.internal.uievent.UIEventDispatcher + +/** + * This is a simple test renderer that draws things back into the provided [tileGraphics]. After instantiation, + * you should call [withComponentContainer] to add components and fragments, and then call [render] to see the result. + * You can also [dispatch] events to interact with it. + * + * @sample org.hexworks.zircon.internal.renderer.TestRendererTest.tinyExample + */ +class TestRenderer( + private val tileGraphics: TileGraphics, + tileset: TilesetResource = RuntimeConfig.config.defaultTileset, + gridSize: Size = Size.defaultGridSize() +) : UIEventDispatcher, Renderer, Clearable { + private val tileGrid: TileGrid = ThreadSafeTileGrid(tileset, gridSize) + private val mainView = object : BaseView(tileGrid) {} + private val closedValueProperty: Property = false.toProperty() + override val closedValue: ObservableValue get() = closedValueProperty + + init { + mainView.dock() + } + + fun withComponentContainer(cb: ComponentContainer.() -> Unit) { + with(mainView.screen, cb) + } + + override fun create() { + } + + override fun clear() { + tileGraphics.clear() + } + + override fun render() { + (tileGrid as RenderableContainer).renderables.forEach { renderable -> + if (!renderable.isHidden) { + val graphics = FastTileGraphics( + initialSize = renderable.size, + initialTileset = renderable.tileset, + initialTiles = mapOf() + ) + renderable.render(graphics) + graphics.contents().forEach { (pos, tile) -> + tileGraphics.draw(tile, pos + renderable.position) + } + } + } + } + + override fun dispatch(event: UIEvent): UIEventResponse = (mainView.screen as UIEventDispatcher).dispatch(event) + + override fun close() { + if (!closedValueProperty.value) { + tileGrid.close() + closedValueProperty.value = true + } + } + + override val isClosed: ObservableValue get() = closedValue +} diff --git a/zircon.core/src/jvmTest/kotlin/org/hexworks/zircon/internal/renderer/TestRendererTest.kt b/zircon.core/src/jvmTest/kotlin/org/hexworks/zircon/internal/renderer/TestRendererTest.kt new file mode 100644 index 0000000000..c3b96fb108 --- /dev/null +++ b/zircon.core/src/jvmTest/kotlin/org/hexworks/zircon/internal/renderer/TestRendererTest.kt @@ -0,0 +1,45 @@ +package org.hexworks.zircon.internal.renderer + +import org.assertj.core.api.Assertions.assertThat +import org.hexworks.zircon.api.ComponentDecorations.box +import org.hexworks.zircon.api.Components +import org.hexworks.zircon.api.DrawSurfaces +import org.hexworks.zircon.api.data.Size +import org.hexworks.zircon.api.graphics.BoxType +import org.hexworks.zircon.characterTilesAsString +import org.junit.Test + +class TestRendererTest { + @Test + fun tinyExample() { + val graphics = DrawSurfaces.tileGraphicsBuilder().withSize(Size.create(3, 1)).build() + val testRenderer = TestRenderer(graphics).apply { + withComponentContainer { + addComponent(Components.textBox(3).addParagraph("Foo").build()) + } + } + testRenderer.render() + assertThat(graphics.characterTilesAsString()).isEqualTo("Foo") + } + + @Test + fun rendersAsExpected() { + val text = "Hello Zircon" + val graphics = DrawSurfaces.tileGraphicsBuilder().withSize(Size.create(text.length + 2, 4)).build() + val testRenderer = TestRenderer(graphics).apply { + withComponentContainer { + addComponent(Components.textBox(text.length) + .withDecorations(box(boxType = BoxType.TOP_BOTTOM_DOUBLE)) + .addParagraph(text, withNewLine = false) + .build()) + } + } + testRenderer.render() + assertThat(graphics.characterTilesAsString()).isEqualTo(""" + ╒════════════╕ + │Hello Zircon│ + │ │ + ╘════════════╛ + """.trimIndent()) + } +}