Skip to content

Commit

Permalink
Streamline input handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-arold committed Sep 27, 2018
1 parent 6614e77 commit 8d5e6c3
Show file tree
Hide file tree
Showing 101 changed files with 1,505 additions and 1,174 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -4,7 +4,7 @@ allprojects {
}

buildscript {
ext.kotlinVersion = "1.2.70"
ext.kotlinVersion = "1.2.71"
repositories {
jcenter()
mavenCentral()
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Expand Up @@ -4,4 +4,5 @@ include ":zircon.core"
include ":zircon.jvm"
include ":zircon.jvm.swing"
include ":zircon.jvm.libgdx"
include ":zircon.jvm.sitegen"
include ":zircon.examples"
Expand Up @@ -22,11 +22,6 @@ interface AnimationInfo {
*/
fun isInfinite(): Boolean

/**
* Adds a callback which will be called when the [Animation] finishes.
*/
fun onFinished(fn: (AnimationInfo) -> Unit)

/**
* Adds a callback which will be called when the [Animation] finishes.
*/
Expand Down
Expand Up @@ -8,9 +8,10 @@ import org.hexworks.zircon.api.util.Maybe
* Represents an object which can be drawn upon.
* A [DrawSurface] is the most basic interface for all drawable surfaces
* which exposes simple get and set functions for getting and setting
* [Tile]s and drawing [Drawable]s.
* [Tile]s and drawing [Drawable]s. Each [DrawSurface] can use its own
* tileset, so it also implements [TilesetOverride].
*/
interface DrawSurface : Boundable {
interface DrawSurface : Boundable, TilesetOverride {

/**
* Returns the character stored at a particular position on this [DrawSurface].
Expand Down
@@ -1,29 +1,135 @@
package org.hexworks.zircon.api.behavior

import org.hexworks.zircon.api.event.Subscription
import org.hexworks.zircon.api.input.Input
import org.hexworks.zircon.api.input.MouseAction
import org.hexworks.zircon.api.input.MouseActionType.*
import org.hexworks.zircon.api.kotlin.map
import org.hexworks.zircon.api.listener.InputListener
import org.hexworks.zircon.api.listener.KeyStrokeListener
import org.hexworks.zircon.api.listener.MouseListener
import org.hexworks.zircon.api.util.Consumer

/**
* Represents an object which (re) emits the [Input]s
* it has received from the underlying technology (like Swing or LibGDX).
*/

interface InputEmitter {

/**
* Adds an input listener to this [InputEmitter].
* It will be notified when an [Input] is consumed
* by this object.
* Adds an [InputListener] listener to this [InputEmitter]. It will be notified when any
* kind of [Input] is received by this object.
*/
fun onInput(listener: InputListener): Subscription

/**
* Adds a [KeyStrokeListener] listener to this [InputEmitter]. It will be notified when a
* [org.hexworks.zircon.api.input.KeyStroke] is received by this object.
*/
fun onInput(listener: Consumer<Input>)
fun onKeyStroke(listener: KeyStrokeListener): Subscription {
return onInput(object : InputListener {
override fun inputEmitted(input: Input) {
input.asKeyStroke().map {
listener.keyStroked(it)
}
}
})
}

/**
* Adds an input listener to this [InputEmitter].
* It will be notified when an [Input] is consumed
* by this object.
* Adds a [MouseListener] listener to this [InputEmitter]. It will be notified when a
* [org.hexworks.zircon.api.input.MouseAction] is received by this object.
*/
fun onInput(listener: (Input) -> Unit) = onInput(object : Consumer<Input> {
override fun accept(p: Input) {
listener.invoke(p)
}
})
fun onMouseAction(listener: MouseListener): Subscription {
return onInput(object : InputListener {
override fun inputEmitted(input: Input) {
input.asMouseAction().map {
when (it.actionType) {
MOUSE_CLICKED -> listener.mouseClicked(it)
MOUSE_PRESSED -> listener.mousePressed(it)
MOUSE_RELEASED -> listener.mouseReleased(it)
MOUSE_ENTERED -> listener.mouseEntered(it)
MOUSE_EXITED -> listener.mouseExited(it)
MOUSE_WHEEL_ROTATED_UP -> listener.mouseWheelRotatedUp(it)
MOUSE_WHEEL_ROTATED_DOWN -> listener.mouseWheelRotatedDown(it)
MOUSE_DRAGGED -> listener.mouseDragged(it)
MOUSE_MOVED -> listener.mouseMoved(it)
}
}
}
})
}

fun onMouseClicked(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseClicked(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMousePressed(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mousePressed(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseReleased(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseReleased(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseEntered(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseEntered(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseExited(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseExited(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseWheelRotatedUp(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseWheelRotatedUp(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseWheelRotatedDown(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseWheelRotatedDown(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseDragged(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseDragged(action: MouseAction) {
consumer.accept(action)
}
})
}

fun onMouseMoved(consumer: Consumer<MouseAction>): Subscription {
return onMouseAction(object : MouseListener {
override fun mouseMoved(action: MouseAction) {
consumer.accept(action)
}
})
}
}
Expand Up @@ -14,15 +14,4 @@ interface ShutdownHook {
*/
fun onShutdown(listener: Runnable)

/**
* Adds a listener which will be notified when the environment shuts down.
* Note that this is only true for graceful termination.
* If a `SIGKILL` is sent for example graceful termination is not possible.
*/
fun onShutdown(listener: () -> Unit) = onShutdown(object : Runnable {
override fun run() {
listener.invoke()
}
})

}
Expand Up @@ -92,17 +92,22 @@ data class AnimationBuilder private constructor(

override fun createCopy() = copy(
frames = frames
.map {
.asSequence()
.map { frame ->
DefaultAnimationFrame(
size = it.getSize(),
layers = it.getLayers().map { it.createCopy() }.toList(),
repeatCount = it.getRepeatCount())
size = frame.getSize(),
layers = frame.getLayers().asSequence()
.map { it.createCopy() }
.toList(),
repeatCount = frame.getRepeatCount())
}
.toMutableList(),
positions = positions.toMutableList())

private fun recalculateFrameCountAndLength() {
totalFrameCount = frames.map { it.getRepeatCount() }.reduce(Int::plus)
totalFrameCount = frames.asSequence()
.map { it.getRepeatCount() }
.reduce(Int::plus)
uniqueFrameCount = frames.size
}

Expand Down
Expand Up @@ -18,7 +18,7 @@ data class PanelBuilder(
}
fillMissingValues()
return DefaultPanel(
title = title().orElseGet { "" },
title = title().orElse(""),
renderingStrategy = DefaultComponentRenderingStrategy(
decorationRenderers = decorationRenderers(),
componentRenderer = DefaultPanelRenderer()),
Expand Down
Expand Up @@ -3,6 +3,7 @@ package org.hexworks.zircon.api.builder.data
import org.hexworks.zircon.api.builder.Builder
import org.hexworks.zircon.api.data.*
import org.hexworks.zircon.api.data.BlockSide.*
import org.hexworks.zircon.api.kotlin.map
import org.hexworks.zircon.api.util.Maybe
import org.hexworks.zircon.internal.data.DefaultBlock

Expand Down
@@ -1,9 +1,8 @@
package org.hexworks.zircon.api.builder.game

import org.hexworks.zircon.api.builder.Builder
import org.hexworks.zircon.api.builder.animation.AnimationBuilder
import org.hexworks.zircon.api.game.GameArea
import org.hexworks.zircon.api.data.Size3D
import org.hexworks.zircon.api.game.GameArea
import org.hexworks.zircon.api.graphics.TileGraphics
import org.hexworks.zircon.internal.config.RuntimeConfig
import org.hexworks.zircon.internal.game.InMemoryGameArea
Expand All @@ -23,8 +22,8 @@ data class GameAreaBuilder(private var size: Size3D = Size3D.one(),
fun size(size: Size3D) = also {
this.size = size
levels = mutableMapOf()
(0 until size.zLength).forEach {
levels[it] = mutableListOf()
(0 until size.zLength).forEach { z ->
levels[z] = mutableListOf()
}
}

Expand All @@ -34,7 +33,7 @@ data class GameAreaBuilder(private var size: Size3D = Size3D.one(),
require(level in 0.rangeTo(size.zLength)) {
"Level '$level' is out create bounds (0 - ${size.zLength})!"
}
require(images.all { it.size() == size.to2DSize() }) {
require(images.all { image -> image.size() == size.to2DSize() }) {
"The supplied image(s) do(es) not match the size create the GameArea (${size.to2DSize()})!"
}
this.levels[level] = images.toMutableList()
Expand Down
@@ -1,5 +1,6 @@
package org.hexworks.zircon.api.component

import org.hexworks.zircon.api.behavior.InputEmitter
import org.hexworks.zircon.api.data.Position
import org.hexworks.zircon.api.data.Size
import org.hexworks.zircon.api.data.Tile
Expand All @@ -19,7 +20,7 @@ import org.hexworks.zircon.internal.behavior.Identifiable
* like a label or a check box is a [Container] while a label which is only intended to
* display information is a [Component].
*/
interface Component : Identifiable, Layer {
interface Component : Identifiable, Layer, InputEmitter {

/**
* Tells whether this [Component] is attached to a parent or not.
Expand Down Expand Up @@ -47,24 +48,6 @@ interface Component : Identifiable, Layer {
*/
fun absolutePosition(): Position

/**
* Adds a callback to this [Component] which will be called
* when the mouse is pressed on this component.
*/
fun onMousePressed(callback: Consumer<MouseAction>)

/**
* Adds a callback to this [Component] which will be called
* when the mouse is released on this component.
*/
fun onMouseReleased(callback: Consumer<MouseAction>)

/**
* Adds a callback to this [Component] which will be called
* when the mouse is moved over this component (to a new [org.hexworks.zircon.api.data.Position]).
*/
fun onMouseMoved(callback: Consumer<MouseAction>)

/**
* Gets the styles this [Component] uses.
*/
Expand Down
Expand Up @@ -12,6 +12,7 @@ import org.hexworks.zircon.api.util.Maybe
*/
interface Container : Component {

// TODO: implement ComponentContainer
/**
* Returns the immediate child [Component]s of this [Container].
*/
Expand Down
Expand Up @@ -25,9 +25,8 @@ interface RadioButtonGroup : Component, Scrollable {

/**
* Clears the selected item in this [RadioButtonGroup].
* @return `true` if the selection changed `false` if not
*/
fun clearSelection(): Boolean
fun clearSelection()

interface Selection {
fun getKey(): String
Expand Down
@@ -1,12 +1,12 @@
package org.hexworks.zircon.api.component.renderer.impl

import org.hexworks.zircon.api.builder.modifier.BorderBuilder
import org.hexworks.zircon.api.color.ANSITileColor
import org.hexworks.zircon.api.component.renderer.ComponentDecorationRenderContext
import org.hexworks.zircon.api.component.renderer.ComponentDecorationRenderer
import org.hexworks.zircon.api.data.Position
import org.hexworks.zircon.api.data.Size
import org.hexworks.zircon.api.graphics.SubTileGraphics
import org.hexworks.zircon.api.kotlin.map
import org.hexworks.zircon.api.modifier.Border
import org.hexworks.zircon.api.modifier.BorderPosition
import org.hexworks.zircon.api.shape.LineFactory
Expand Down
Expand Up @@ -8,6 +8,7 @@ import org.hexworks.zircon.api.data.Position
import org.hexworks.zircon.api.data.Size
import org.hexworks.zircon.api.graphics.BoxType
import org.hexworks.zircon.api.graphics.SubTileGraphics
import org.hexworks.zircon.api.kotlin.map
import org.hexworks.zircon.api.util.Maybe

class BoxDecorationRenderer(private val boxType: BoxType = BoxType.SINGLE,
Expand Down

This file was deleted.

Expand Up @@ -5,8 +5,8 @@ import org.hexworks.zircon.api.resource.TilesetResource
data class GridPosition(override val x: Int,
override val y: Int) : Position {

override fun toAbsolutePosition(tileset: TilesetResource): AbsolutePosition {
return AbsolutePosition(x * tileset.width, y * tileset.height)
override fun toPixelPosition(tileset: TilesetResource): PixelPosition {
return PixelPosition(x * tileset.width, y * tileset.height)
}

companion object {
Expand Down

0 comments on commit 8d5e6c3

Please sign in to comment.