From 241a3dcba524337b2b59c1931ed3403c00a6d05e Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Wed, 29 May 2019 21:24:30 +0200 Subject: [PATCH] Use cbuf for control event queue Replace the control_event_queue implementation by cbuf. --- app/meson.build | 4 -- app/src/control_event.c | 49 -------------- app/src/control_event.h | 28 -------- app/src/controller.c | 21 +++--- app/src/controller.h | 7 +- app/tests/test_control_event_queue.c | 95 ---------------------------- 6 files changed, 14 insertions(+), 190 deletions(-) delete mode 100644 app/tests/test_control_event_queue.c diff --git a/app/meson.build b/app/meson.build index 73cf55ca..9bcaa9ae 100644 --- a/app/meson.build +++ b/app/meson.build @@ -157,10 +157,6 @@ tests = [ ['test_cbuf', [ 'tests/test_cbuf.c', ]], - ['test_control_event_queue', [ - 'tests/test_control_event_queue.c', - 'src/control_event.c' - ]], ['test_control_event_serialize', [ 'tests/test_control_event_serialize.c', 'src/control_event.c' diff --git a/app/src/control_event.c b/app/src/control_event.c index ea6585a4..e22337fc 100644 --- a/app/src/control_event.c +++ b/app/src/control_event.c @@ -58,52 +58,3 @@ control_event_destroy(struct control_event *event) { SDL_free(event->text_event.text); } } - -bool -control_event_queue_is_empty(const struct control_event_queue *queue) { - return queue->head == queue->tail; -} - -bool -control_event_queue_is_full(const struct control_event_queue *queue) { - return (queue->head + 1) % CONTROL_EVENT_QUEUE_SIZE == queue->tail; -} - -bool -control_event_queue_init(struct control_event_queue *queue) { - queue->head = 0; - queue->tail = 0; - // the current implementation may not fail - return true; -} - -void -control_event_queue_destroy(struct control_event_queue *queue) { - int i = queue->tail; - while (i != queue->head) { - control_event_destroy(&queue->data[i]); - i = (i + 1) % CONTROL_EVENT_QUEUE_SIZE; - } -} - -bool -control_event_queue_push(struct control_event_queue *queue, - const struct control_event *event) { - if (control_event_queue_is_full(queue)) { - return false; - } - queue->data[queue->head] = *event; - queue->head = (queue->head + 1) % CONTROL_EVENT_QUEUE_SIZE; - return true; -} - -bool -control_event_queue_take(struct control_event_queue *queue, - struct control_event *event) { - if (control_event_queue_is_empty(queue)) { - return false; - } - *event = queue->data[queue->tail]; - queue->tail = (queue->tail + 1) % CONTROL_EVENT_QUEUE_SIZE; - return true; -} diff --git a/app/src/control_event.h b/app/src/control_event.h index 49ec7020..13533316 100644 --- a/app/src/control_event.h +++ b/app/src/control_event.h @@ -9,7 +9,6 @@ #include "android/keycodes.h" #include "common.h" -#define CONTROL_EVENT_QUEUE_SIZE 64 #define CONTROL_EVENT_TEXT_MAX_LENGTH 300 #define CONTROL_EVENT_SERIALIZED_MAX_SIZE (3 + CONTROL_EVENT_TEXT_MAX_LENGTH) @@ -54,38 +53,11 @@ struct control_event { }; }; -struct control_event_queue { - struct control_event data[CONTROL_EVENT_QUEUE_SIZE]; - int head; - int tail; -}; - // buf size must be at least CONTROL_EVENT_SERIALIZED_MAX_SIZE // return the number of bytes written size_t control_event_serialize(const struct control_event *event, unsigned char *buf); -bool -control_event_queue_init(struct control_event_queue *queue); - -void -control_event_queue_destroy(struct control_event_queue *queue); - -bool -control_event_queue_is_empty(const struct control_event_queue *queue); - -bool -control_event_queue_is_full(const struct control_event_queue *queue); - -// the event is "moved": the queue takes ownership of its fields -bool -control_event_queue_push(struct control_event_queue *queue, - const struct control_event *event); - -bool -control_event_queue_take(struct control_event_queue *queue, - struct control_event *event); - void control_event_destroy(struct control_event *event); diff --git a/app/src/controller.c b/app/src/controller.c index 8a342503..30118218 100644 --- a/app/src/controller.c +++ b/app/src/controller.c @@ -8,9 +8,7 @@ bool controller_init(struct controller *controller, socket_t video_socket) { - if (!control_event_queue_init(&controller->queue)) { - return false; - } + cbuf_init(&controller->queue); if (!(controller->mutex = SDL_CreateMutex())) { return false; @@ -31,16 +29,19 @@ void controller_destroy(struct controller *controller) { SDL_DestroyCond(controller->event_cond); SDL_DestroyMutex(controller->mutex); - control_event_queue_destroy(&controller->queue); + + struct control_event event; + while (cbuf_take(&controller->queue, &event)) { + control_event_destroy(&event); + } } bool controller_push_event(struct controller *controller, const struct control_event *event) { - bool res; mutex_lock(controller->mutex); - bool was_empty = control_event_queue_is_empty(&controller->queue); - res = control_event_queue_push(&controller->queue, event); + bool was_empty = cbuf_is_empty(&controller->queue); + bool res = cbuf_push(&controller->queue, *event); if (was_empty) { cond_signal(controller->event_cond); } @@ -66,8 +67,7 @@ run_controller(void *data) { for (;;) { mutex_lock(controller->mutex); - while (!controller->stopped - && control_event_queue_is_empty(&controller->queue)) { + while (!controller->stopped && cbuf_is_empty(&controller->queue)) { cond_wait(controller->event_cond, controller->mutex); } if (controller->stopped) { @@ -76,8 +76,7 @@ run_controller(void *data) { break; } struct control_event event; - bool non_empty = control_event_queue_take(&controller->queue, - &event); + bool non_empty = cbuf_take(&controller->queue, &event); SDL_assert(non_empty); mutex_unlock(controller->mutex); diff --git a/app/src/controller.h b/app/src/controller.h index 2f7696e3..7930bf8a 100644 --- a/app/src/controller.h +++ b/app/src/controller.h @@ -1,14 +1,16 @@ #ifndef CONTROL_H #define CONTROL_H -#include "control_event.h" - #include #include #include +#include "cbuf.h" +#include "control_event.h" #include "net.h" +struct control_event_queue CBUF(struct control_event, 64); + struct controller { socket_t video_socket; SDL_Thread *thread; @@ -33,7 +35,6 @@ controller_stop(struct controller *controller); void controller_join(struct controller *controller); -// expose simple API to hide control_event_queue bool controller_push_event(struct controller *controller, const struct control_event *event); diff --git a/app/tests/test_control_event_queue.c b/app/tests/test_control_event_queue.c deleted file mode 100644 index 432f6cec..00000000 --- a/app/tests/test_control_event_queue.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include - -#include "control_event.h" - -static void test_control_event_queue_empty(void) { - struct control_event_queue queue; - bool init_ok = control_event_queue_init(&queue); - assert(init_ok); - - assert(control_event_queue_is_empty(&queue)); - - struct control_event dummy_event; - bool push_ok = control_event_queue_push(&queue, &dummy_event); - assert(push_ok); - assert(!control_event_queue_is_empty(&queue)); - - bool take_ok = control_event_queue_take(&queue, &dummy_event); - assert(take_ok); - assert(control_event_queue_is_empty(&queue)); - - bool take_empty_ok = control_event_queue_take(&queue, &dummy_event); - assert(!take_empty_ok); // the queue is empty - - control_event_queue_destroy(&queue); -} - -static void test_control_event_queue_full(void) { - struct control_event_queue queue; - bool init_ok = control_event_queue_init(&queue); - assert(init_ok); - - assert(!control_event_queue_is_full(&queue)); - - struct control_event dummy_event; - // fill the queue - while (control_event_queue_push(&queue, &dummy_event)); - - bool take_ok = control_event_queue_take(&queue, &dummy_event); - assert(take_ok); - assert(!control_event_queue_is_full(&queue)); - - control_event_queue_destroy(&queue); -} - -static void test_control_event_queue_push_take(void) { - struct control_event_queue queue; - bool init_ok = control_event_queue_init(&queue); - assert(init_ok); - - struct control_event event = { - .type = CONTROL_EVENT_TYPE_KEYCODE, - .keycode_event = { - .action = AKEY_EVENT_ACTION_DOWN, - .keycode = AKEYCODE_ENTER, - .metastate = AMETA_CTRL_LEFT_ON | AMETA_CTRL_ON, - }, - }; - - bool push1_ok = control_event_queue_push(&queue, &event); - assert(push1_ok); - - event = (struct control_event) { - .type = CONTROL_EVENT_TYPE_TEXT, - .text_event = { - .text = "abc", - }, - }; - - bool push2_ok = control_event_queue_push(&queue, &event); - assert(push2_ok); - - // overwrite event - bool take1_ok = control_event_queue_take(&queue, &event); - assert(take1_ok); - assert(event.type == CONTROL_EVENT_TYPE_KEYCODE); - assert(event.keycode_event.action == AKEY_EVENT_ACTION_DOWN); - assert(event.keycode_event.keycode == AKEYCODE_ENTER); - assert(event.keycode_event.metastate == (AMETA_CTRL_LEFT_ON | AMETA_CTRL_ON)); - - // overwrite event - bool take2_ok = control_event_queue_take(&queue, &event); - assert(take2_ok); - assert(event.type == CONTROL_EVENT_TYPE_TEXT); - assert(!strcmp(event.text_event.text, "abc")); - - control_event_queue_destroy(&queue); -} - -int main(void) { - test_control_event_queue_empty(); - test_control_event_queue_full(); - test_control_event_queue_push_take(); - return 0; -}