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

eu.joaocosta.minart.input.KeyboardInput.scala Maven / Gradle / Ivy

package eu.joaocosta.minart.input

import scala.collection.immutable.Queue

import eu.joaocosta.minart.input.KeyboardInput.Key

/** The keyboard input stores the state of the keyboard at a certain point in time.
  * It also accumulates keys that have been pressed and released.
  *
  * @param keysDown keys that are pressed down
  * @param events ordered press/release keyboard events.
  *               Note that only the most recent `KeyboardInput.maxEvents` are guaranteed to be present.
  */
case class KeyboardInput(keysDown: Set[Key], events: Queue[KeyboardInput.Event]) {

  /** Keys that have been pressed */
  lazy val keysPressed: Set[Key] = events.collect { case KeyboardInput.Event.Pressed(key) =>
    key
  }.toSet

  /** Keys that have been released */
  lazy val keysReleased: Set[Key] = events.collect { case KeyboardInput.Event.Released(key) =>
    key
  }.toSet

  /** Checks if a key is down. */
  def isDown(key: Key): Boolean = keysDown(key)

  /** Checks if a key is up. */
  def isUp(key: Key): Boolean = !keysDown(key)

  private def pushEvent(event: KeyboardInput.Event) = {
    val newQueue = events :+ event
    if (newQueue.size >= KeyboardInput.maxEvents * 2) this.copy(events = newQueue.drop(KeyboardInput.maxEvents))
    else this.copy(events = newQueue)
  }

  /** Returns a new state where a key has been pressed. */
  def press(key: Key): KeyboardInput =
    if (keysDown(key)) this // Ignore key repeat
    else pushEvent(KeyboardInput.Event.Pressed(key)).copy(keysDown = keysDown + key)

  /** Returns a new state where a key has been released. */
  def release(key: Key): KeyboardInput =
    pushEvent(KeyboardInput.Event.Released(key)).copy(keysDown = keysDown - key)

  /** Clears the `keysPressed` and `keysReleased`. */
  def clearPressRelease(): KeyboardInput = KeyboardInput(keysDown, Queue.empty)
}

object KeyboardInput {

  /** Keyboard Input with everything unset
    */
  val empty = KeyboardInput(Set(), Queue.empty)

  /** Maximum events guaranteed to be stored by KeyboardInput */
  val maxEvents = 1024

  /** Keyboard Event */
  sealed trait Event {
    def key: Key
  }
  object Event {

    /** Event representing a key press */
    final case class Pressed(key: Key) extends Event

    /** Event representing a key release */
    final case class Released(key: Key) extends Event
  }

  /** Internal trait to store mappings from platform-specific key representations to a [[Key]].
    * This should not have to be used in the application code.
    */
  trait KeyMapping[A] {
    protected def mappings: Map[A, Key]
    def getKey(keyCode: A): Option[Key] = mappings.get(keyCode)
  }

  /** Platform-agnostic identifier for a keyboard key.
    */
  sealed trait Key
  object Key {
    case object A extends Key
    case object B extends Key
    case object C extends Key
    case object D extends Key
    case object E extends Key
    case object F extends Key
    case object G extends Key
    case object H extends Key
    case object I extends Key
    case object J extends Key
    case object K extends Key
    case object L extends Key
    case object M extends Key
    case object N extends Key
    case object O extends Key
    case object P extends Key
    case object Q extends Key
    case object R extends Key
    case object S extends Key
    case object T extends Key
    case object U extends Key
    case object V extends Key
    case object W extends Key
    case object X extends Key
    case object Y extends Key
    case object Z extends Key

    case object Digit0 extends Key
    case object Digit1 extends Key
    case object Digit2 extends Key
    case object Digit3 extends Key
    case object Digit4 extends Key
    case object Digit5 extends Key
    case object Digit6 extends Key
    case object Digit7 extends Key
    case object Digit8 extends Key
    case object Digit9 extends Key

    case object NumPad0 extends Key
    case object NumPad1 extends Key
    case object NumPad2 extends Key
    case object NumPad3 extends Key
    case object NumPad4 extends Key
    case object NumPad5 extends Key
    case object NumPad6 extends Key
    case object NumPad7 extends Key
    case object NumPad8 extends Key
    case object NumPad9 extends Key

    case object Space     extends Key
    case object Tab       extends Key
    case object Enter     extends Key
    case object Backspace extends Key

    case object Escape extends Key
    case object Shift  extends Key
    case object Ctrl   extends Key
    case object Alt    extends Key
    case object Meta   extends Key

    case object Up    extends Key
    case object Down  extends Key
    case object Left  extends Key
    case object Right extends Key
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy