Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2020
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.37 KB | None | 0 0
  1. import kotlinx.coroutines.SupervisorJob
  2. import kotlinx.coroutines.cancel
  3. import processing.core.PApplet
  4. import java.util.SortedSet
  5. import java.util.TreeSet
  6. import kotlin.coroutines.Continuation
  7. import kotlin.coroutines.createCoroutine
  8. import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
  9. import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
  10. import kotlin.coroutines.resume
  11.  
  12. data class ScheduledCallback(
  13.     val suspendedAtMillis: Int,
  14.     val resumeAtMillis: Int,
  15.     val continuation: Continuation<Unit>
  16. ) : Comparable<ScheduledCallback> {
  17.     override fun compareTo(other: ScheduledCallback): Int {
  18.         val resumeAtComparison = resumeAtMillis.compareTo(other.resumeAtMillis)
  19.  
  20.         return if (resumeAtComparison == 0)
  21.             suspendedAtMillis.compareTo(other.suspendedAtMillis)
  22.         else
  23.             resumeAtComparison
  24.     }
  25. }
  26.  
  27. open class ScheduledSketch : PApplet() {
  28.     /**
  29.      * A set of pending tasks. Each task has an associated millisecond value where it will be resumed as soon as
  30.      * possible. Every time draw() is called, every callback in this set whose millisecond value is less than or equal
  31.      * to the current millisecond value will be executed and removed from the set.
  32.      */
  33.     private val schedule: SortedSet<ScheduledCallback> = TreeSet()
  34.  
  35.     /**
  36.      * The job that all running tasks will be grouped under, so that once the application is closed, everything is
  37.      * cleaned up.
  38.      */
  39.     private val job = SupervisorJob()
  40.  
  41.     override fun exitActual() {
  42.         job.cancel("The sketch is exiting!")
  43.         super.exitActual()
  44.     }
  45.  
  46.     override fun setup() {
  47.         this::main.createCoroutine(Continuation(job, ::println)).resume(Unit)
  48.     }
  49.  
  50.     suspend fun main() {
  51.         while (true) {
  52.             background(255f, 255f, 255f)
  53.             circle(128f, 128f, 16f)
  54.             yieldFor(20)
  55.             background(255f, 255f, 255f)
  56.             yieldFor(20)
  57.         }
  58.     }
  59.  
  60.     private suspend fun yieldUntil(millis: Int) = suspendCoroutineUninterceptedOrReturn<Unit> {
  61.         schedule.add(ScheduledCallback(millis(), millis, it))
  62.         COROUTINE_SUSPENDED
  63.     }
  64.  
  65.     private suspend fun yieldFor(millis: Int) = yieldUntil(millis() + millis)
  66.  
  67.     override fun draw() {
  68.         val millis = millis()
  69.         val queue = TreeSet<ScheduledCallback>()
  70.  
  71.         schedule.forEach { scheduled ->
  72.             if (millis >= scheduled.resumeAtMillis) {
  73.                 queue.add(scheduled)
  74.                 schedule.remove(scheduled)
  75.             }
  76.         }
  77.  
  78.         queue.forEach { scheduled ->
  79.             scheduled.continuation.resume(Unit)
  80.         }
  81.     }
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement