From 8e8a573876b00d74db520ea5609294628c02e5c9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 25 Nov 2021 17:52:27 +0900 Subject: [PATCH] [input] Add listeners to buttons The listener is invoked when the button state changes. --- include/QF/input/binding.h | 13 +++++++++++++ libs/input/in_button.c | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/QF/input/binding.h b/include/QF/input/binding.h index ddcb4c35a..704cd61e7 100644 --- a/include/QF/input/binding.h +++ b/include/QF/input/binding.h @@ -31,6 +31,7 @@ #ifndef __QFCC__ +#include "QF/listener.h" #include "QF/mathlib.h" /*** Recipe for converting an axis to a floating point value. @@ -114,10 +115,18 @@ typedef enum { typedef struct in_button_s { int down[2]; ///< button ids holding this button down int state; ///< in_button_state + struct button_listener_set_s *listeners; const char *name; const char *description; } in_button_t; +typedef struct button_listener_set_s LISTENER_SET_TYPE (in_button_t) + button_listener_set_t; + +/*** Function type for button listeners. +*/ +typedef void (*button_listener_t) (void *data, const in_button_t *button); + typedef struct in_axisbinding_s { in_recipe_t *recipe; in_axis_t *axis; @@ -307,6 +316,10 @@ int IN_RegisterButton (in_button_t *button); int IN_RegisterAxis (in_axis_t *axis); in_button_t *IN_FindButton (const char *name); in_axis_t *IN_FindAxis (const char *name); +void IN_ButtonAddListener (in_button_t *button, button_listener_t listener, + void *data); +void IN_ButtonRemoveListener (in_button_t *button, button_listener_t listener, + void *data); struct IE_event_s; int IN_Binding_HandleEvent (const struct IE_event_s *ie_event); diff --git a/libs/input/in_button.c b/libs/input/in_button.c index 17cfc5944..15d28160d 100644 --- a/libs/input/in_button.c +++ b/libs/input/in_button.c @@ -87,6 +87,9 @@ button_press (in_button_t *button, int id) return; } button->state |= inb_down | inb_edge_down; + if (button->listeners) { + LISTENER_INVOKE (button->listeners, button); + } } static void @@ -118,6 +121,9 @@ button_release (in_button_t *button, int id) } button->state &= ~inb_down; // now up button->state |= inb_edge_up; + if (button->listeners) { + LISTENER_INVOKE (button->listeners, button); + } } void @@ -196,6 +202,26 @@ IN_FindButton (const char *name) return 0; } +void +IN_ButtonAddListener (in_button_t *button, button_listener_t listener, + void *data) +{ + if (!button->listeners) { + button->listeners = malloc (sizeof (*button->listeners)); + LISTENER_SET_INIT (button->listeners, 8); + } + LISTENER_ADD (button->listeners, listener, data); +} + +void +IN_ButtonRemoveListener (in_button_t *button, button_listener_t listener, + void *data) +{ + if (button->listeners) { + LISTENER_REMOVE (button->listeners, listener, data); + } +} + static void __attribute__((constructor)) in_button_init (void) {