[input] Add axis listeners

The listener is invoked when the axis value changes due to IN_UpdateAxis
or IN_ClampAxis updating the axis. This does mean the listener
invocation make be somewhat delayed. I am a tad uncertain about this
design thus it being a separate commit.
This commit is contained in:
Bill Currie 2021-11-25 17:55:22 +09:00
parent 8e8a573876
commit 1a79915d22
2 changed files with 48 additions and 1 deletions

View file

@ -86,10 +86,18 @@ typedef struct in_axis_s {
in_axis_mode mode; ///< method used for updating the destination
float abs_input; ///< input from an absolute axis (eg, joystick)
float rel_input; ///< input from a relative axis (eg, mouse)
struct axis_listener_set_s *listeners;
const char *name;
const char *description;
} in_axis_t;
typedef struct axis_listener_set_s LISTENER_SET_TYPE (in_axis_t)
axis_listener_set_t;
/*** Function type for axis listeners.
*/
typedef void (*axis_listener_t) (void *data, const in_axis_t *axis);
/*** Current state of the logical button.
Captures the current state and any transitions during the last frame.
@ -285,6 +293,7 @@ VISIBLE
float
IN_UpdateAxis (in_axis_t *axis)
{
float prev_value = axis->value;
switch (axis->mode) {
case ina_set:
axis->value = axis->abs_input + axis->rel_input;
@ -294,6 +303,9 @@ IN_UpdateAxis (in_axis_t *axis)
break;
}
axis->rel_input = 0;
if (axis->value != prev_value && axis->listeners) {
LISTENER_INVOKE (axis->listeners, axis);
}
return axis->value;
}
@ -305,8 +317,20 @@ VISIBLE
float
IN_ClampAxis (in_axis_t *axis, float minval, float maxval)
{
IN_UpdateAxis (axis);
float prev_value = axis->value;
switch (axis->mode) {
case ina_set:
axis->value = axis->abs_input + axis->rel_input;
break;
case ina_accumulate:
axis->value += axis->abs_input + axis->rel_input;
break;
}
axis->rel_input = 0;
axis->value = bound (minval, axis->value, maxval);
if (axis->value != prev_value && axis->listeners) {
LISTENER_INVOKE (axis->listeners, axis);
}
return axis->value;
}
@ -320,6 +344,10 @@ 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);
void IN_AxisAddListener (in_axis_t *axis, axis_listener_t listener,
void *data);
void IN_AxisRemoveListener (in_axis_t *axis, axis_listener_t listener,
void *data);
struct IE_event_s;
int IN_Binding_HandleEvent (const struct IE_event_s *ie_event);

View file

@ -75,6 +75,25 @@ IN_FindAxis (const char *name)
return Hash_Find (axis_tab, name);
}
void
IN_AxisAddListener (in_axis_t *axis, axis_listener_t listener, void *data)
{
if (!axis->listeners) {
axis->listeners = malloc (sizeof (*axis->listeners));
LISTENER_SET_INIT (axis->listeners, 8);
}
LISTENER_ADD (axis->listeners, listener, data);
}
void
IN_AxisRemoveListener (in_axis_t *axis, axis_listener_t listener, void *data)
{
if (axis->listeners) {
LISTENER_REMOVE (axis->listeners, listener, data);
}
}
static void __attribute__((constructor))
in_axis_init (void)
{