https://kotlinlang.org logo
Title
p

Pablo Caviglia

09/04/2020, 2:05 PM
Hi all, I need some assistance with a UI component I've created that changes its graphics during a period of time
`
class TaskProgress(private val scene: GenericScene) : Container() {

    var timeMsParent = 0L
    var currentTime = 0L

    fun startProgress(size: Double, timeMs: Long, callback: ((taskProgress: TaskProgress) -> Unit)? = null) {

        timeMsParent = timeMs

        graphics {

            val paint = ColorPaint(Colors["#00D532"])
            val strokeInfo = Context2d.StrokeInfo(thickness = 4.0, pixelHinting = true)

            scene.launchImmediately {

                val drawArc = {
                    val angleDegrees = currentTime * (360.0 / timeMsParent) * PI / 180
                    stroke(paint, strokeInfo) {
                        arc(Screen.HALF_WIDTH, Screen.HALF_HEIGHT,  size * 0.53, 0, angleDegrees)
                    }
                }

                while (currentTime < timeMsParent) {
                    drawArc()
                    // sleep
                    val sleepTime = 30L
                    delay(sleepTime)
                    currentTime += sleepTime
                    println("---> $currentTime")
                    clear()
                }

                currentTime = timeMsParent
                drawArc()

                callback?.invoke(this@TaskProgress)
            }
        }
    }

    fun stop() {
        timeMsParent = 0
        currentTime = 0
    }
}
the problem I have is that the elapsed time is not real time, in fact if I change the value of 'sleepTime' I get different timings in relation to real time
what am I doing wrong?
d

Deactivated User

09/04/2020, 2:38 PM
delay times are not exact, they are approximated to frames so if you request for example 30 milliseconds, and each frame is something between 15 and 18 milliseconds, that will sleep 3 frames. Around 48 milliseconds
For realtime, the best is to add an updater (to execute code on each frame), then check the current time to do stuff
p

Pablo Caviglia

09/04/2020, 2:43 PM
`
addFixedUpdater(timesPerSecondsUpdate) {
            currentTime += timesPerSecondsUpdate.timeSpan.milliseconds.toLong()
        }
was playing with that
and it looks it works fine
d

Deactivated User

09/04/2020, 2:47 PM
makes sense, we should state somehow the delay precision problem at the documentation 👍
p

Pablo Caviglia

09/04/2020, 2:48 PM
last question 😄 can I use this in classes that runs inside the korge's project, but in the 'business layer' of the code?
CoroutineScope(Dispatchers.Unconfined).launch {
d

Deactivated User

09/04/2020, 3:08 PM
I guess so, as long as it doesn't update the views
but ideally if you bound that to a scene or something, if you change the scene that coroutine is cancelled. The unconfined one won't be cancelled. As long as you are aware of that, you will be fine