I've been lost on how to do this for days now. :we...
# kotlin-native
a
I've been lost on how to do this for days now. 😩
Copy code
private val apiThread = Worker.start()

private fun startUiLoop() {
    apiThread.execute(TransferMode.SAFE, { Unit }) {
        sleep(2000)
        updateUi()
    }.consume { startUiLoop() }
}
I'm stumped on the syntax here (or a K/N solution in general) for a simple timed interval loop. I have Windows C libraries implemented, if that changes things.
k
Post more code. What does updateUi do? I don’t know how Windows works for UI, though. Why don’t you loop in execute rather than call startUiLoop?
My brief googling tells me Windows is also a main thread UI model. I would assume updateUi is not posting back to the main thread. Your worker is operating on a different thread, as would the updateUi call.
a
Copy code
private fun displayAppWindow() = appWindow("gearNet", 640, 480) {
    val xrdApi: ClashBountyApi = ClashBountyImpl()
    vbox {
        hbox {
            connectBtn = button(text = "Connect to GGXrd") {
                action {
                    statusText.value = "Xrd is not connected."
                    if (xrdApi.connectToXrd()) {
                        statusText.value = "Xrd Connected!"
                        refreshBtn.enabled = true
                    }
                }
            }
            statusText = textfield { readonly = true; value = "..." }
        }
        hbox {
            vbox {
                consoleText = textarea { readonly = true; stretchy = true; value = ""; }
                refreshBtn = button(text = "Get lobby data") {
                    action {
                        logXrdData()
                    }
                }
                refreshBtn.enabled = false
            }
            vbox {
                for (i in 0..7) {
                    guiApi.get(i).playerForm = group("") {
                        vbox {
                            hbox {
                                guiApi.get(i).playerCharacter = textfield { readonly = true; value = ""; enabled = false }
                                guiApi.get(i).playerMatchesPlayed = textfield { readonly = true; value = "- / -"; enabled = false }
                                textfield { readonly = true; value = "- W$"; enabled = false }
                            }
                            hbox {
                                guiApi.get(i).playerLoadPercent = progressbar { value = 0; enabled = false; visible = true }
                            }

                        }
                    }
                }
            }
        }
    }
    startUiLoop()
}
I'm using this library to create my GUI: https://github.com/msink/kotlin-libui the full
startUiLoop()
function does a bit more, but for the sake of simplicity I figured ask something more specific.
Copy code
private fun startUiLoop() {
    apiThread.execute(TransferMode.SAFE, { Unit }) {
        logInfo("UI UPDATED")
        if (xrdApi.isXrdRunning()) {
            setAppStatus("Xrd is running.")
            connectBtn.enabled = true
        } else {
            setAppStatus("Xrd is not running.")
            connectBtn.enabled = false
        }
        sleep(2000)
        startUiLoop()
    }
}
o
I am not sure, what’s the purpose of code written here, you want update UI after 2 seconds? @msink doesn’t libui has interval timer API?
a
Yes, every 2 seconds I'd like to run a function (that updates the values in my app's GUI)
m
libui has:
fun onTimer(milliseconds: Int, block: () -> Boolean): Unit
Copy code
import kotlinx.cinterop.*
import platform.posix.*
import libui.ktx.*

fun main(args: Array<String>) = appWindow(
    title = "Hello",
    width = 320,
    height = 240
) {
    vbox {
        lateinit var scroll: TextArea

        button("Say Something") {
            action {
                scroll.append("Saying something\n")
            }
        }
        scroll = textarea {
            readonly = true
            stretchy = true
        }
        onTimer(1000) {
            memScoped {
                val now = alloc<time_tVar>().apply { value = time(null) }
                val str = ctime(now.ptr)!!.toKString()
                if (!scroll.disposed) scroll.append(str)
            }
            true
        }
    }
}
It executes block on a timer on the main thread, block should return
true
to repeat and
false
to stop.
o
That shall help you, @azeDevs