Skip to content

Commit

Permalink
feat: trigger listener now supports direct onKey and onButton callbac…
Browse files Browse the repository at this point in the history
…ks which are triggered before the generic onAction callbacks, closes #1070
  • Loading branch information
AlmasB committed Jul 15, 2022
1 parent 621cbd7 commit ffb97c6
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 13 deletions.
55 changes: 42 additions & 13 deletions fxgl-core/src/main/kotlin/com/almasb/fxgl/input/Input.kt
Expand Up @@ -20,7 +20,6 @@ import javafx.scene.Node
import javafx.scene.input.*
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap

Expand Down Expand Up @@ -271,15 +270,25 @@ class Input {
currentActions[i].action()
}

activeTriggers.forEach { trigger ->
listeners.forEach {
it.action(trigger)
}
activeTriggers.forEach {
updateTriggerListeners(it)
}

captureAppliers.forEach { it.update(tpf) }
}

private fun updateTriggerListeners(trigger: Trigger) {
listeners.forEach {
if (trigger is KeyTrigger) {
it.actionKey(trigger)
} else if (trigger is MouseTrigger) {
it.actionBtn(trigger)
}

it.action(trigger)
}
}

/**
* Called automatically by FXGL on key event.
*/
Expand Down Expand Up @@ -337,9 +346,7 @@ class Input {
if (newTrigger !in activeTriggers) {
activeTriggers += newTrigger

listeners.forEach {
it.begin(newTrigger)
}
handleTriggerPressed(newTrigger)
}

bindings.filter { (act, trigger) -> act !in currentActions && trigger.isTriggered(event) }
Expand All @@ -361,12 +368,22 @@ class Input {
}
}

private fun handleReleased(event: InputEvent) {
val releasedTriggers = activeTriggers.filter { it.isReleased(event) }
releasedTriggers.forEach { trigger ->
listeners.forEach {
it.end(trigger)
private fun handleTriggerPressed(trigger: Trigger) {
listeners.forEach {
if (trigger is KeyTrigger) {
it.beginKey(trigger)
} else if (trigger is MouseTrigger) {
it.beginBtn(trigger)
}

it.begin(trigger)
}
}

private fun handleReleased(event: InputEvent) {
val releasedTriggers = activeTriggers.filter { it.isReleased(event) || (it is KeyTrigger && isIllegal(it.key)) }
releasedTriggers.forEach {
handleTriggerReleased(it)
}

activeTriggers -= releasedTriggers
Expand All @@ -392,6 +409,18 @@ class Input {
}
}

private fun handleTriggerReleased(trigger: Trigger) {
listeners.forEach {
if (trigger is KeyTrigger) {
it.endKey(trigger)
} else if (trigger is MouseTrigger) {
it.endBtn(trigger)
}

it.end(trigger)
}
}

fun addTriggerListener(triggerListener: TriggerListener) {
listeners += triggerListener
}
Expand Down
40 changes: 40 additions & 0 deletions fxgl-core/src/main/kotlin/com/almasb/fxgl/input/TriggerListener.kt
Expand Up @@ -16,6 +16,14 @@ abstract class TriggerListener {
internal fun action(trigger: Trigger) = onAction(trigger)
internal fun end(trigger: Trigger) = onActionEnd(trigger)

internal fun beginKey(trigger: KeyTrigger) = onKeyBegin(trigger)
internal fun actionKey(trigger: KeyTrigger) = onKey(trigger)
internal fun endKey(trigger: KeyTrigger) = onKeyEnd(trigger)

internal fun beginBtn(trigger: MouseTrigger) = onButtonBegin(trigger)
internal fun actionBtn(trigger: MouseTrigger) = onButton(trigger)
internal fun endBtn(trigger: MouseTrigger) = onButtonEnd(trigger)

/**
* Called once in the same tick when triggered.
*/
Expand All @@ -31,4 +39,36 @@ abstract class TriggerListener {
* Called once in the same tick when trigger was released.
*/
protected open fun onActionEnd(trigger: Trigger) {}

/**
* Called once in the same tick when triggered.
*/
protected open fun onKeyBegin(keyTrigger: KeyTrigger) {}

/**
* Called as long as the trigger is being held (pressed).
* Starts from the next tick from the one when was triggered.
*/
protected open fun onKey(keyTrigger: KeyTrigger) {}

/**
* Called once in the same tick when trigger was released.
*/
protected open fun onKeyEnd(keyTrigger: KeyTrigger) {}

/**
* Called once in the same tick when triggered.
*/
protected open fun onButtonBegin(mouseTrigger: MouseTrigger) {}

/**
* Called as long as the trigger is being held (pressed).
* Starts from the next tick from the one when was triggered.
*/
protected open fun onButton(mouseTrigger: MouseTrigger) {}

/**
* Called once in the same tick when trigger was released.
*/
protected open fun onButtonEnd(mouseTrigger: MouseTrigger) {}
}

0 comments on commit ffb97c6

Please sign in to comment.