Skip to content

Commit 154e91a

Browse files
committed
add EventQueue.store_next() to allow reusing event objects
1 parent db297ad commit 154e91a

File tree

5 files changed

+56
-7
lines changed

5 files changed

+56
-7
lines changed

locale/circuitpython.pot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,10 @@ msgstr ""
949949
msgid "Expected a UUID"
950950
msgstr ""
951951

952+
#: shared-bindings/keypad/EventQueue.c
953+
msgid "Expected an %q"
954+
msgstr ""
955+
952956
#: shared-bindings/_bleio/Adapter.c
953957
msgid "Expected an Address"
954958
msgstr ""

shared-bindings/keypad/Event.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
//| class Event:
3434
//| """A key transition event."""
35-
//| def __init__(self, key_num: int, pressed: bool) -> None:
35+
//| def __init__(self, key_num: int=0, pressed: bool=True) -> None:
3636
//| """Create a key transition event, which reports a key-pressed or key-released transition.
3737
//|
3838
//| :param int key_num: the key number
@@ -46,8 +46,8 @@ STATIC mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args,
4646
self->base.type = &keypad_event_type;
4747
enum { ARG_key_num, ARG_pressed };
4848
static const mp_arg_t allowed_args[] = {
49-
{ MP_QSTR_key_num, MP_ARG_REQUIRED | MP_ARG_INT },
50-
{ MP_QSTR_pressed, MP_ARG_REQUIRED | MP_ARG_BOOL },
49+
{ MP_QSTR_key_num, MP_ARG_INT, {.u_int = 0} },
50+
{ MP_QSTR_pressed, MP_ARG_BOOL, {.u_bool = true} },
5151
};
5252
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
5353
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

shared-bindings/keypad/EventQueue.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626

2727
#include "py/runtime.h"
28+
#include "shared-bindings/keypad/Event.h"
2829
#include "shared-bindings/keypad/EventQueue.h"
2930

3031
//| class EventQueue:
@@ -54,6 +55,34 @@ STATIC mp_obj_t keypad_eventqueue_next(mp_obj_t self_in) {
5455
}
5556
MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_next_obj, keypad_eventqueue_next);
5657

58+
//| def store_next(self, Event: event) -> bool:
59+
//| """Store the next key transition event in the supplied event, if available,
60+
//| and return ``True``.
61+
//| If there are no queued events, do not touch ``event`` and return ``False``.
62+
//|
63+
//| The advantage of this method over ``next()`` is that it does not allocate storage.
64+
//| Instead you can reuse an existing ``Event`` object.
65+
//|
66+
//| Note that the queue size is limited; see ``max_events`` in the constructor of
67+
//| a scanner such as `Keys` or `KeyMatrix`.
68+
//| If a new event arrives when the queue is full, the oldest event is discarded.
69+
//|
70+
//| :return ``True`` if an event was available and stored, ``False`` if not.
71+
//| :rtype: bool
72+
//| """
73+
//| ...
74+
//|
75+
STATIC mp_obj_t keypad_eventqueue_store_next(mp_obj_t self_in, mp_obj_t event_in) {
76+
keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in);
77+
78+
if (!mp_obj_is_type(event_in, &keypad_event_type)) {
79+
mp_raise_ValueError_varg(translate("Expected an %q"), MP_QSTR_Event);
80+
}
81+
keypad_event_obj_t *event = MP_OBJ_TO_PTR(event_in);
82+
return mp_obj_new_bool(common_hal_keypad_eventqueue_store_next(self, event));
83+
}
84+
MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_store_next_obj, keypad_eventqueue_store_next);
85+
5786
//| def clear(self) -> None:
5887
//| """Clear any queued key transition events.
5988
//| """
@@ -91,8 +120,9 @@ STATIC mp_obj_t keypad_eventqueue_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
91120
}
92121

93122
STATIC const mp_rom_map_elem_t keypad_eventqueue_locals_dict_table[] = {
94-
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&keypad_eventqueue_clear_obj) },
95-
{ MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&keypad_eventqueue_next_obj) },
123+
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&keypad_eventqueue_clear_obj) },
124+
{ MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&keypad_eventqueue_next_obj) },
125+
{ MP_ROM_QSTR(MP_QSTR_store_next), MP_ROM_PTR(&keypad_eventqueue_store_next_obj) },
96126
};
97127

98128
STATIC MP_DEFINE_CONST_DICT(keypad_eventqueue_locals_dict, keypad_eventqueue_locals_dict_table);

shared-bindings/keypad/EventQueue.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H
2828
#define MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H
2929

30-
#include "py/objlist.h"
31-
#include "shared-module/keypad/Keys.h"
30+
#include "shared-module/keypad/Event.h"
31+
#include "shared-module/keypad/EventQueue.h"
3232

3333
extern const mp_obj_type_t keypad_eventqueue_type;
3434

@@ -37,5 +37,6 @@ void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_
3737
void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self);
3838
size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self);
3939
mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self);
40+
bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event);
4041

4142
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H

shared-module/keypad/EventQueue.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self) {
4949
return MP_OBJ_FROM_PTR(event);
5050
}
5151

52+
bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event) {
53+
int encoded_event = ringbuf_get16(&self->encoded_events);
54+
if (encoded_event == -1) {
55+
return false;
56+
}
57+
58+
// "Construct" using the existing event.
59+
common_hal_keypad_event_construct(event, encoded_event & EVENT_KEY_NUM_MASK, encoded_event & EVENT_PRESSED);
60+
return true;
61+
}
62+
63+
64+
65+
5266
void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self) {
5367
ringbuf_clear(&self->encoded_events);
5468
}

0 commit comments

Comments
 (0)