All Downloads are FREE. Search and download functionalities are using the official Maven repository.

indigo.shared.input.Keyboard.scala Maven / Gradle / Ivy

The newest version!
package indigo.shared.input

import indigo.shared.collections.Batch
import indigo.shared.constants.Key
import indigo.shared.events.KeyboardEvent

import scala.annotation.tailrec

final class Keyboard(keyboardEvents: Batch[KeyboardEvent], val keysDown: Batch[Key], val lastKeyHeldDown: Option[Key]) {

  lazy val keysReleased: Batch[Key] = keyboardEvents.collect { case k: KeyboardEvent.KeyUp => k.keyCode }

  def keysAreDown(keys: Key*): Boolean = keys.forall(keyCode => keysDown.contains(keyCode))
  def keysAreUp(keys: Key*): Boolean   = keys.forall(keyCode => keysReleased.contains(keyCode))

}
object Keyboard {

  val default: Keyboard =
    new Keyboard(Batch.empty, Batch.empty, None)

  def calculateNext(previous: Keyboard, events: Batch[KeyboardEvent]): Keyboard = {
    val keysDown = calculateKeysDown(events, previous.keysDown)

    new Keyboard(
      events,
      keysDown,
      keysDown.reverse.headOption
    )
  }

  private given CanEqual[Batch[KeyboardEvent], Batch[KeyboardEvent]] = CanEqual.derived

  def calculateKeysDown(keyboardEvents: Batch[KeyboardEvent], previousKeysDown: Batch[Key]): Batch[Key] = {
    @tailrec
    def rec(remaining: List[KeyboardEvent], keysDownAcc: List[Key]): Batch[Key] =
      remaining match {
        case Nil =>
          Batch.fromList(keysDownAcc.reverse)

        case KeyboardEvent.KeyDown(k) :: tl =>
          rec(tl, k :: keysDownAcc)

        case KeyboardEvent.KeyUp(k) :: tl =>
          rec(tl, keysDownAcc.filterNot(p => p === k))
      }

    rec(keyboardEvents.toList, previousKeysDown.reverse.toList)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy