package ocelot.desktop.util

import java.util.concurrent.TimeUnit
import scala.concurrent.duration.{Duration, DurationInt}

class Ticker extends Logging {
  var lastTick: Long = System.nanoTime()
  var tick: Long = 0

  private var _tickIntervalNs: Long = _

  def tickInterval: Duration = Duration.fromNanos(_tickIntervalNs)

  def tickInterval_=(interval: Duration): Unit = {
    val us = interval.toMicros
    logger.info(f"Setting tick interval to $us μs (${1_000_000f / us} s^-1)")
    _tickIntervalNs = interval.toNanos
  }

  tickInterval = 1.second / 20

  def waitNext(count: Boolean = true): Unit = {
    val deadline = lastTick + _tickIntervalNs
    var time = System.nanoTime()
    while (time < deadline) {
      val rem = deadline - time
      if (rem > 1000000)
        TimeUnit.NANOSECONDS.sleep(rem - 1000000)
      else
        Thread.`yield`()
      time = System.nanoTime()
    }

    lastTick = System.nanoTime()
    if (count) tick += 1
  }
}
