[input] Add listeners to buttons

The listener is invoked when the button state changes.
This commit is contained in:
Bill Currie 2021-11-25 17:52:27 +09:00
parent c4118a4bf1
commit 8e8a573876
2 changed files with 39 additions and 0 deletions

View file

@ -31,6 +31,7 @@
#ifndef __QFCC__ #ifndef __QFCC__
#include "QF/listener.h"
#include "QF/mathlib.h" #include "QF/mathlib.h"
/*** Recipe for converting an axis to a floating point value. /*** Recipe for converting an axis to a floating point value.
@ -114,10 +115,18 @@ typedef enum {
typedef struct in_button_s { typedef struct in_button_s {
int down[2]; ///< button ids holding this button down int down[2]; ///< button ids holding this button down
int state; ///< in_button_state int state; ///< in_button_state
struct button_listener_set_s *listeners;
const char *name; const char *name;
const char *description; const char *description;
} in_button_t; } 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 { typedef struct in_axisbinding_s {
in_recipe_t *recipe; in_recipe_t *recipe;
in_axis_t *axis; in_axis_t *axis;
@ -307,6 +316,10 @@ int IN_RegisterButton (in_button_t *button);
int IN_RegisterAxis (in_axis_t *axis); int IN_RegisterAxis (in_axis_t *axis);
in_button_t *IN_FindButton (const char *name); in_button_t *IN_FindButton (const char *name);
in_axis_t *IN_FindAxis (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; struct IE_event_s;
int IN_Binding_HandleEvent (const struct IE_event_s *ie_event); int IN_Binding_HandleEvent (const struct IE_event_s *ie_event);

View file

@ -87,6 +87,9 @@ button_press (in_button_t *button, int id)
return; return;
} }
button->state |= inb_down | inb_edge_down; button->state |= inb_down | inb_edge_down;
if (button->listeners) {
LISTENER_INVOKE (button->listeners, button);
}
} }
static void static void
@ -118,6 +121,9 @@ button_release (in_button_t *button, int id)
} }
button->state &= ~inb_down; // now up button->state &= ~inb_down; // now up
button->state |= inb_edge_up; button->state |= inb_edge_up;
if (button->listeners) {
LISTENER_INVOKE (button->listeners, button);
}
} }
void void
@ -196,6 +202,26 @@ IN_FindButton (const char *name)
return 0; 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)) static void __attribute__((constructor))
in_button_init (void) in_button_init (void)
{ {