Skip to content

Commit

Permalink
Render experiments
Browse files Browse the repository at this point in the history
  • Loading branch information
marad committed May 30, 2020
1 parent f56d8fb commit c2073e9
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
63 changes: 63 additions & 0 deletions src/main/kotlin/kweb/Element.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import kweb.util.random
import kweb.util.toJson
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ConcurrentSkipListSet
import java.util.concurrent.atomic.AtomicReference
import kotlin.reflect.KClass

@KWebDSL
Expand Down Expand Up @@ -369,6 +370,68 @@ open class Element(override val browser: WebBrowser, val creator: ElementCreator
* See [here](https://docs.kweb.io/en/latest/dom.html#immediate-events).
*/
val onImmediate get() = OnImmediateReceiver(this)

private enum class RenderState {
NOT_RENDERING, RENDERING_NO_PENDING_CHANGE, RENDERING_WITH_PENDING_CHANGE
}

fun <T : Any?> render(kval: KVal<T>, block: ElementCreator<Element>.(T) -> Unit) {

val containerSpan = this

val previousElementCreator: AtomicReference<ElementCreator<Element>?> = AtomicReference(null)

val renderState = AtomicReference(RenderState.NOT_RENDERING)

fun eraseAndRender() {
do {
containerSpan.removeChildren()
containerSpan.new {
previousElementCreator.getAndSet(this)?.cleanup()
renderState.set(RenderState.RENDERING_NO_PENDING_CHANGE)
block(kval.value)
if (renderState.get() == RenderState.RENDERING_NO_PENDING_CHANGE) {
renderState.set(RenderState.NOT_RENDERING)
}
}
} while (renderState.get() != RenderState.NOT_RENDERING)
}

val listenerHandle = kval.addListener { _, _ ->
when (renderState.get()) {
RenderState.NOT_RENDERING -> {
eraseAndRender()
}
RenderState.RENDERING_NO_PENDING_CHANGE -> {
renderState.set(RenderState.RENDERING_WITH_PENDING_CHANGE)
}
else -> {
// This space intentionally left blank
}
}
}

containerSpan.new {
previousElementCreator.getAndSet(this)?.cleanup()
renderState.set(RenderState.RENDERING_NO_PENDING_CHANGE)
block(kval.value)
if (renderState.get() == RenderState.RENDERING_WITH_PENDING_CHANGE) {
eraseAndRender()
} else {
renderState.set(RenderState.NOT_RENDERING)
}

}

// this.onCleanup(false) {
// containerSpan.deleteIfExists()
// }

// this.onCleanup(true) {
// previousElementCreator.getAndSet(null)?.cleanup()
// kval.removeListener(listenerHandle)
// }
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/kweb/ElementCreator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import kweb.client.Server2ClientMessage.Instruction.Type.CreateElement
import kweb.html.BodyElement
import kweb.html.HeadElement
import kweb.plugins.KwebPlugin
import kweb.state.KVal
import kweb.util.KWebDSL
import kweb.util.toJson
import mu.KLogging
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicReference
import kotlin.reflect.KClass

/**
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/kweb/demos/todo/TodoApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class TodoApp {
doc.head.new {
title().text("To Do List #${params.getValue("id").value}")
}
render(params.getValue("id")) { listId ->
span().render(params.getValue("id")) { listId ->
// render(params.getValue("id")) { listId ->
logger.info("Rendering list id $listId")

try {
Expand Down

0 comments on commit c2073e9

Please sign in to comment.