Skip to content

Add async def wait to EventQueue objects #6705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions py/circuitpy_mpconfig.mk
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ CFLAGS += -DMICROPY_PY_USELECT=$(MICROPY_PY_USELECT)
MICROPY_PY_USELECT_SELECT ?= $(MICROPY_PY_USELECT)
CFLAGS += -DMICROPY_PY_USELECT_SELECT=$(MICROPY_PY_USELECT_SELECT)

# enable iobase if select is enabled
MICROPY_PY_IO_IOBASE ?= $(MICROPY_PY_USELECT)
CFLAGS += -DMICROPY_PY_IO_IOBASE=$(MICROPY_PY_IO_IOBASE)

CIRCUITPY_AESIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO)

Expand Down
17 changes: 17 additions & 0 deletions shared-bindings/keypad/EventQueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,28 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_overflowed_obj, keypad_eventqueu
MP_PROPERTY_GETTER(keypad_eventqueue_overflowed_obj,
(mp_obj_t)&keypad_eventqueue_get_overflowed_obj);

#if KEYPAD_HAS_WAIT
//| async def wait() -> Awaitable[None]:
//| """Wait for an event. Retrieve the event with `get` or `get_into`.
//|
//| This function is only avaialable on boards that support asyncio, and it requries
//| that the `asyncio` module actually be available to import."""
//|
STATIC mp_obj_t keypad_eventqueue_wait(mp_obj_t self_in) {
keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in);
return common_hal_keypad_eventqueue_wait(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_wait_obj, keypad_eventqueue_wait);
#endif

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_get), MP_ROM_PTR(&keypad_eventqueue_get_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_into), MP_ROM_PTR(&keypad_eventqueue_get_into_obj) },
{ MP_ROM_QSTR(MP_QSTR_overflowed), MP_ROM_PTR(&keypad_eventqueue_overflowed_obj) },
#if KEYPAD_HAS_WAIT
{ MP_ROM_QSTR(MP_QSTR_wait), MP_ROM_PTR(&keypad_eventqueue_wait_obj) },
#endif
};

STATIC MP_DEFINE_CONST_DICT(keypad_eventqueue_locals_dict, keypad_eventqueue_locals_dict_table);
Expand Down
3 changes: 3 additions & 0 deletions shared-bindings/keypad/EventQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include "shared-module/keypad/Event.h"
#include "shared-module/keypad/EventQueue.h"

#define KEYPAD_HAS_WAIT (MICROPY_PY_IO_IOBASE && MICROPY_PY_ASYNC_AWAIT)

extern const mp_obj_type_t keypad_eventqueue_type;

void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events);
Expand All @@ -41,5 +43,6 @@ bool common_hal_keypad_eventqueue_get_into(keypad_eventqueue_obj_t *self, keypad

bool common_hal_keypad_eventqueue_get_overflowed(keypad_eventqueue_obj_t *self);
void common_hal_keypad_eventqueue_set_overflowed(keypad_eventqueue_obj_t *self, bool overflowed);
mp_obj_t common_hal_keypad_eventqueue_wait(keypad_eventqueue_obj_t *self);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H
36 changes: 36 additions & 0 deletions shared-module/keypad/EventQueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
* THE SOFTWARE.
*/

#include "py/runtime.h"

#include "shared-bindings/keypad/Event.h"
#include "shared-bindings/keypad/EventQueue.h"
#include "shared-bindings/supervisor/__init__.h"
Expand Down Expand Up @@ -80,6 +82,17 @@ size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self) {
return ringbuf_num_filled(&self->encoded_events);
}

static void notify(keypad_eventqueue_obj_t *self) {
#if KEYPAD_HAS_WAIT
if (!self->queue) {
return;
}
mp_obj_t dest[2];
mp_load_method(self->queue, MP_QSTR_set, dest);
mp_call_method_n_kw(0, 0, dest);
#endif
}

bool keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_number, bool pressed, mp_obj_t timestamp) {
if (ringbuf_num_empty(&self->encoded_events) == 0) {
// Queue is full. Set the overflow flag. The caller will decide what else to do.
Expand All @@ -93,6 +106,29 @@ bool keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_numbe
}
ringbuf_put16(&self->encoded_events, encoded_event);
ringbuf_put_n(&self->encoded_events, (uint8_t *)&timestamp, sizeof(mp_obj_t));
notify(self);

return true;
}

#if KEYPAD_HAS_WAIT
mp_obj_t common_hal_keypad_eventqueue_wait(keypad_eventqueue_obj_t *self) {
if (!self->queue) {
mp_obj_t asyncio = mp_import_name(MP_QSTR_asyncio_dot_event, mp_const_none, MP_OBJ_NEW_SMALL_INT(0));
mp_printf(&mp_plat_print, "asyncio @ %p\n", MP_OBJ_TO_PTR(asyncio));
mp_obj_t asyncio_event = mp_import_from(asyncio, MP_QSTR_event);
mp_printf(&mp_plat_print, "asyncio_event @ %p\n", MP_OBJ_TO_PTR(asyncio_event));
mp_obj_t thread_safe_flag = mp_import_from(asyncio_event, MP_QSTR_ThreadSafeFlag);
mp_printf(&mp_plat_print, "thread_safe_flag @ %p\n", MP_OBJ_TO_PTR(thread_safe_flag));
self->queue = mp_call_function_0(thread_safe_flag);
mp_printf(&mp_plat_print, "self->queue @ %p\n", MP_OBJ_TO_PTR(self->queue));
}
int encoded_event = ringbuf_peek16(&self->encoded_events);
if (encoded_event != -1) {
notify(self);
}
mp_obj_t dest[2];
mp_load_method(self->queue, MP_QSTR_wait, dest);
return mp_call_method_n_kw(0, 0, dest);
}
#endif
1 change: 1 addition & 0 deletions shared-module/keypad/EventQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ typedef struct _keypad_eventqueue_obj_t {
mp_obj_base_t base;
ringbuf_t encoded_events;
bool overflowed;
mp_obj_t queue;
} keypad_eventqueue_obj_t;

bool keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_number, bool pressed, mp_obj_t timestamp);
Expand Down