add EventQueue.store_next() to allow reusing event objects

This commit is contained in:
Dan Halbert 2021-06-21 08:18:06 -04:00
parent db297add67
commit 154e91ab85
5 changed files with 56 additions and 7 deletions

View File

@ -949,6 +949,10 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
#: shared-bindings/keypad/EventQueue.c
msgid "Expected an %q"
msgstr ""
#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""

View File

@ -32,7 +32,7 @@
//| class Event:
//| """A key transition event."""
//| def __init__(self, key_num: int, pressed: bool) -> None:
//| def __init__(self, key_num: int=0, pressed: bool=True) -> None:
//| """Create a key transition event, which reports a key-pressed or key-released transition.
//|
//| :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,
self->base.type = &keypad_event_type;
enum { ARG_key_num, ARG_pressed };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_key_num, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_pressed, MP_ARG_REQUIRED | MP_ARG_BOOL },
{ MP_QSTR_key_num, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_pressed, MP_ARG_BOOL, {.u_bool = true} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

View File

@ -25,6 +25,7 @@
*/
#include "py/runtime.h"
#include "shared-bindings/keypad/Event.h"
#include "shared-bindings/keypad/EventQueue.h"
//| class EventQueue:
@ -54,6 +55,34 @@ STATIC mp_obj_t keypad_eventqueue_next(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_next_obj, keypad_eventqueue_next);
//| def store_next(self, Event: event) -> bool:
//| """Store the next key transition event in the supplied event, if available,
//| and return ``True``.
//| If there are no queued events, do not touch ``event`` and return ``False``.
//|
//| The advantage of this method over ``next()`` is that it does not allocate storage.
//| Instead you can reuse an existing ``Event`` object.
//|
//| Note that the queue size is limited; see ``max_events`` in the constructor of
//| a scanner such as `Keys` or `KeyMatrix`.
//| If a new event arrives when the queue is full, the oldest event is discarded.
//|
//| :return ``True`` if an event was available and stored, ``False`` if not.
//| :rtype: bool
//| """
//| ...
//|
STATIC mp_obj_t keypad_eventqueue_store_next(mp_obj_t self_in, mp_obj_t event_in) {
keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!mp_obj_is_type(event_in, &keypad_event_type)) {
mp_raise_ValueError_varg(translate("Expected an %q"), MP_QSTR_Event);
}
keypad_event_obj_t *event = MP_OBJ_TO_PTR(event_in);
return mp_obj_new_bool(common_hal_keypad_eventqueue_store_next(self, event));
}
MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_store_next_obj, keypad_eventqueue_store_next);
//| def clear(self) -> None:
//| """Clear any queued key transition events.
//| """
@ -91,8 +120,9 @@ STATIC mp_obj_t keypad_eventqueue_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
}
STATIC const mp_rom_map_elem_t keypad_eventqueue_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&keypad_eventqueue_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&keypad_eventqueue_next_obj) },
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&keypad_eventqueue_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&keypad_eventqueue_next_obj) },
{ MP_ROM_QSTR(MP_QSTR_store_next), MP_ROM_PTR(&keypad_eventqueue_store_next_obj) },
};
STATIC MP_DEFINE_CONST_DICT(keypad_eventqueue_locals_dict, keypad_eventqueue_locals_dict_table);

View File

@ -27,8 +27,8 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H
#include "py/objlist.h"
#include "shared-module/keypad/Keys.h"
#include "shared-module/keypad/Event.h"
#include "shared-module/keypad/EventQueue.h"
extern const mp_obj_type_t keypad_eventqueue_type;
@ -37,5 +37,6 @@ void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_
void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self);
size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self);
mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self);
bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H

View File

@ -49,6 +49,20 @@ mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self) {
return MP_OBJ_FROM_PTR(event);
}
bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event) {
int encoded_event = ringbuf_get16(&self->encoded_events);
if (encoded_event == -1) {
return false;
}
// "Construct" using the existing event.
common_hal_keypad_event_construct(event, encoded_event & EVENT_KEY_NUM_MASK, encoded_event & EVENT_PRESSED);
return true;
}
void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self) {
ringbuf_clear(&self->encoded_events);
}