From 14cf1327fe0b6e3c16c0df6628293b6197f66708 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Sat, 19 Feb 2022 11:19:02 -0800 Subject: [PATCH] feat: register_custom_input_handler() API This introduces a new API on `ESCInputsManager` that makes it possible to inject custom logic for processing input events. An example of how to use this API will be introduced in a separate commit as part of https://github.com/godot-escoria/escoria-demo-game/pull/503 via a new plugin, `addons/escoria-ui-keyboard-9verbs/`, which shows how this can be used to add support for keyboard shortcuts to select a specific verb. --- .../game/core-scripts/esc_background.gd | 7 ++- addons/escoria-core/game/inputs_manager.gd | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/addons/escoria-core/game/core-scripts/esc_background.gd b/addons/escoria-core/game/core-scripts/esc_background.gd index 6605ca09..34af7d4a 100644 --- a/addons/escoria-core/game/core-scripts/esc_background.gd +++ b/addons/escoria-core/game/core-scripts/esc_background.gd @@ -82,8 +82,11 @@ func _ready(): # # #### Parameters # - event: Event received -func _unhandled_input(event) -> void: - if not escoria.current_state == escoria.GAME_STATE.DEFAULT: +func _unhandled_input(event: InputEvent) -> void: + var is_default_state = escoria.current_state == escoria.GAME_STATE.DEFAULT + if escoria.inputs_manager.try_custom_input_handler(event, is_default_state): + return + if not is_default_state: return if InputMap.has_action(escoria.inputs_manager.SWITCH_ACTION_VERB) \ and event.is_action_pressed(escoria.inputs_manager.SWITCH_ACTION_VERB): diff --git a/addons/escoria-core/game/inputs_manager.gd b/addons/escoria-core/game/inputs_manager.gd index bddebcd3..7d54c88f 100644 --- a/addons/escoria-core/game/inputs_manager.gd +++ b/addons/escoria-core/game/inputs_manager.gd @@ -31,6 +31,18 @@ var hover_stack: Array = [] # The global id of the topmost item from the hover_stack var hotspot_focused: String = "" +# Function reference that can be used to intercept and process input events. +# If set, this function must have the following signature: +# +# (event: InputEvent, is_default_state: bool) -> bool +# +# #### Parameters +# +# - event: The event to process +# - is_default_state: Whether the current state is escoria.GAME_STATE.DEFAULT +# +# **Returns** Whether the function processed the event. +var custom_input_handler = null # Register core signals (from escoria.gd) func register_core(): @@ -101,6 +113,43 @@ func register_background(background: ESCBackground): ) +# Registers a function that can be used to intercept and process input events. +# `callback` must have the following signature: +# +# (event: InputEvent, is_default_state: bool) -> bool +# +# where +# +# - event: The event to process +# - is_default_state: Whether the current state is escoria.GAME_STATE.DEFAULT +# - returns whether the function processed the event +# +# `callback` is responsible for calling `get_tree().set_input_as_handled()`, +# if appropriate. +# +# #### Parameters +# - callback: Function reference satisfying the above contract +func register_custom_input_handler(callback) -> void: + custom_input_handler = callback + + +# If a callback was specified via `register_custom_input_handler()`, +# forwards the event to the callback and returns its result; otherwise, +# returns `false`. +# +# #### Parameters +# +# - event: The event to process +# - is_default_state: Whether the current state is escoria.GAME_STATE.DEFAULT +# +# **Returns** Result of `custom_input_handler` if set; otherwise, `false` +func try_custom_input_handler(event: InputEvent, is_default_state: bool) -> bool: + if custom_input_handler: + return custom_input_handler.call_func(event, is_default_state) + else: + return false + + # Clear the stack of hovered items func clear_stack(): hover_stack = []