From 3d55d2722a3129449ab1418e73abd97caa7fd2ae Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 18 Dec 2024 11:06:44 -0500 Subject: Extend server resource loading, work on client Also, cleanup in preparation for changing code style. Signed-off-by: Andrew Opalach --- src/fruits/cmc/cmc.c | 78 ++++++++++++++++++++++------------------- src/fruits/cmc/cmc.h | 17 +++++++++ src/fruits/cmc/meson.build | 5 ++- src/fruits/cmc/ui/pane_search.c | 39 +++++++++++++++++++++ src/fruits/cmc/ui/tile.h | 5 +++ src/fruits/cmc/ui/ui.c | 67 ++++++++++++++++++++++++++++------- src/fruits/cmc/ui/ui.h | 25 ++++++++++--- 7 files changed, 181 insertions(+), 55 deletions(-) create mode 100644 src/fruits/cmc/ui/pane_search.c create mode 100644 src/fruits/cmc/ui/tile.h (limited to 'src/fruits/cmc') diff --git a/src/fruits/cmc/cmc.c b/src/fruits/cmc/cmc.c index 724a489..3c62ba8 100644 --- a/src/fruits/cmc/cmc.c +++ b/src/fruits/cmc/cmc.c @@ -1,10 +1,8 @@ #include #include -#include "../../libclient/client.h" -#include "../../server/common.c" #include "../../portal/src/packet_ext.h" -#include "../../portal/src/post_cache.h" +#include "../../server/common.c" #include "cmc.h" @@ -12,18 +10,8 @@ enum { CLI_OPEN_UI = 0, - CLI_ADD -}; - -struct cmc { - struct aki_event_loop loop; - u8 command; - array(str) args; - struct camu_client client; - struct camu_post_cache cache; - array(struct cmc_search *) searches; - struct cmc_ui ui; - struct aki_poll input_poll; + CLI_ADD, + CLI_SEARCH }; static struct cmc_search *get_search_by_id(struct cmc *c, s32 id) @@ -35,21 +23,20 @@ static struct cmc_search *get_search_by_id(struct cmc *c, s32 id) return NULL; } -static void input_poll_callback(void *userdata, s32 revents) +static void parse_user_state(struct cmc *c, struct aki_packet *packet) { - struct cmc *c = (struct cmc *)userdata; - (void)revents; - struct ncinput input; - do { - if (!cmc_ui_read_input(&c->ui, &input)) break; - if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) { - switch (input.id) { - case 'q': - aki_event_loop_break_one(&c->loop); - break; - } - } - } while (1); + u32 size = aki_packet_read_u32(packet); + for (u32 i = 0; i < size; i++) { + struct cmc_search *search = al_alloc_object(struct cmc_search); + search->id = aki_packet_read_s32(packet); + str s; + aki_packet_read_str(packet, &s); + al_str_clone(&search->module, &s); + aki_packet_read_str(packet, &s); + al_str_clone(&search->query, &s); + al_array_init(search->pages); + al_array_push(c->searches, search); + } } static void client_callback(void *userdata, u8 op, void *opaque) @@ -57,19 +44,28 @@ static void client_callback(void *userdata, u8 op, void *opaque) struct cmc *c = (struct cmc *)userdata; switch (op) { case CAMU_CLIENT_LOGIN: { + struct aki_packet *packet = (struct aki_packet *)opaque; switch (c->command) { case CLI_OPEN_UI: - if (!cmc_ui_init(&c->ui)) { + parse_user_state(c, packet); + if (!cmc_ui_init(&c->ui, &c->loop, c)) { aki_event_loop_break_one(&c->loop); } - aki_poll_init(&c->input_poll, input_poll_callback, c); - aki_poll_set(&c->input_poll, cmc_ui_get_input_fd(&c->ui), AKI_POLL_READ); - aki_poll_start(&c->input_poll, &c->loop); break; case CLI_ADD: { str *arg; al_array_foreach_ptr(c->args, i, arg) { camu_client_add_from_path(&c->client, al_str_c("default"), arg); + al_str_free(arg); + } + camu_client_disconnect(&c->client); + break; + } + case CLI_SEARCH: { + str *arg; + al_array_foreach_ptr(c->args, i, arg) { + camu_client_create_search(&c->client, al_str_c("youtube"), arg); + al_str_free(arg); } camu_client_disconnect(&c->client); break; @@ -136,11 +132,22 @@ static bool parse_cmd(s32 argc, wchar_t **argv) al_array_push(c.args, arg); } } + } else if (al_str_eq(al_str_cr(argv[1]), al_str_c("search"))) { + if (argc < 3) return false; + c.command = CLI_SEARCH; + str query; + al_str_from(&query, ""); + for (s32 i = 2; i < argc; i++) { + al_str_cat(&query, al_str_cr(argv[i])); + if (i != argc - 1) { + al_str_cat(&query, al_str_c(" ")); + } + } + al_array_push(c.args, query); } return true; } - #ifndef _WIN32 s32 main(s32 argc, char *argv[]) #else @@ -152,12 +159,11 @@ s32 wmain(s32 argc, wchar_t **argv) aki_event_loop_init(&c.loop); al_array_init(c.args); + if (!parse_cmd(argc, argv)) return EXIT_FAILURE; camu_post_cache_init(&c.cache); al_array_init(c.searches); - if (!parse_cmd(argc, argv)) return EXIT_FAILURE; - c.client.callback = client_callback; c.client.userdata = &c; if (!camu_client_login(&c.client, &c.loop, CAMU_LOCAL_TYPE, CAMU_LOCAL_ADDR, CAMU_PORT, al_str_c("andrew"))) { diff --git a/src/fruits/cmc/cmc.h b/src/fruits/cmc/cmc.h index a9c8544..353bd87 100644 --- a/src/fruits/cmc/cmc.h +++ b/src/fruits/cmc/cmc.h @@ -4,6 +4,11 @@ #include #include +#include "../../libclient/client.h" +#include "../../portal/src/post_cache.h" + +#include "ui/ui.h" + struct cmc_search_page { u32 num; array(str) list; @@ -11,5 +16,17 @@ struct cmc_search_page { struct cmc_search { s32 id; + str module; + str query; array(struct cmc_search_page *) pages; }; + +struct cmc { + struct aki_event_loop loop; + u8 command; + array(str) args; + struct camu_client client; + struct camu_post_cache cache; + array(struct cmc_search *) searches; + struct cmc_ui ui; +}; diff --git a/src/fruits/cmc/meson.build b/src/fruits/cmc/meson.build index 627391e..76efff5 100644 --- a/src/fruits/cmc/meson.build +++ b/src/fruits/cmc/meson.build @@ -8,7 +8,10 @@ endif use_tui = true if use_tui - cmc_src += ['ui/ui.c'] + cmc_src += [ + 'ui/ui.c', + 'ui/pane_search.c', + ] cmc_deps += [dependency('notcurses')] endif diff --git a/src/fruits/cmc/ui/pane_search.c b/src/fruits/cmc/ui/pane_search.c new file mode 100644 index 0000000..cc549e1 --- /dev/null +++ b/src/fruits/cmc/ui/pane_search.c @@ -0,0 +1,39 @@ +#include "../cmc.h" + +#include "ui.h" + +void cmc_sp_init(struct cmc_ui *ui) +{ + if (ui->c->searches.size > 0) { + ui->sp.search = al_array_at(ui->c->searches, 0); + } + cmc_sp_layout(ui, notcurses_stdplane(ui->nc)); +} + +void cmc_sp_layout(struct cmc_ui *ui, struct ncplane *parent) +{ + if (ui->sp.n) ncplane_destroy(ui->sp.n); + struct ncplane_options nopts = { + .rows = ui->term_rows, + .cols = ui->term_cols, + .x = 0, + .y = 0 + }; + ui->sp.n = ncplane_create(parent, &nopts); +} + +bool cmc_sp_handle_input(struct cmc_ui *ui, struct ncinput *input) +{ + (void)ui; + (void)input; + return true; +} + +void cmc_sp_render(struct cmc_ui *ui) +{ + if (ui->sp.search) { + char *c_str = al_str_to_c_str(&ui->sp.search->query); + ncplane_putstr_yx(ui->sp.n, 0, 0, c_str); + al_free(c_str); + } +} diff --git a/src/fruits/cmc/ui/tile.h b/src/fruits/cmc/ui/tile.h new file mode 100644 index 0000000..6f15c7d --- /dev/null +++ b/src/fruits/cmc/ui/tile.h @@ -0,0 +1,5 @@ +#pragma once + +struct cmc_tile { + +}; diff --git a/src/fruits/cmc/ui/ui.c b/src/fruits/cmc/ui/ui.c index a838f96..58d630f 100644 --- a/src/fruits/cmc/ui/ui.c +++ b/src/fruits/cmc/ui/ui.c @@ -2,28 +2,69 @@ #include "ui.h" -bool cmc_ui_init(struct cmc_ui *ui) +static s32 resize_cb(struct ncplane *p) { - al_memset(ui, 0, sizeof(struct cmc_ui)); - if (!(ui->nc = notcurses_init(NULL, stdin))) { - return false; - } - return true; + struct cmc_ui *ui = (struct cmc_ui *)ncplane_userptr(p); + (void)ui; + return 0; } -s32 cmc_ui_get_input_fd(struct cmc_ui *ui) -{ - return notcurses_inputready_fd(ui->nc); -} - -bool cmc_ui_read_input(struct cmc_ui *ui, struct ncinput *input) +static bool read_input(struct cmc_ui *ui, struct ncinput *input) { al_memset(input, 0, sizeof(struct ncinput)); u32 ret = notcurses_get_nblock(ui->nc, input); return !(ret == (u32)-1 || ret == 0); } +static void input_poll_callback(void *userdata, s32 revents) +{ + struct cmc_ui *ui = (struct cmc_ui *)userdata; + (void)revents; + struct ncinput input; + do { + if (!read_input(ui, &input)) break; + bool do_render = false; + if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) { + switch (input.id) { + case 'q': + aki_event_loop_break_one(ui->loop); + break; + } + } + switch (ui->pane) { + case CMC_PANE_SEARCH: + if (cmc_sp_handle_input(ui, &input)) { + cmc_sp_render(ui); + do_render |= true; + } + } + if (do_render) { + notcurses_render(ui->nc); + } + } while (1); +} + +bool cmc_ui_init(struct cmc_ui *ui, struct aki_event_loop *loop, struct cmc *c) +{ + al_memset(ui, 0, sizeof(struct cmc_ui)); + ui->c = c; + if (!(ui->nc = notcurses_init(NULL, stdin))) { + return false; + } + ui->loop = loop; + notcurses_stddim_yx(ui->nc, &ui->term_rows, &ui->term_cols); + cmc_sp_init(ui); + struct ncplane *stdplane = notcurses_stdplane(ui->nc); + ncplane_set_resizecb(stdplane, resize_cb); + ncplane_set_userptr(stdplane, ui); + aki_poll_init(&ui->input_poll, input_poll_callback, ui); + aki_poll_set(&ui->input_poll, notcurses_inputready_fd(ui->nc), AKI_POLL_READ); + aki_poll_start(&ui->input_poll, ui->loop); + ui->pane = CMC_PANE_SEARCH; + return true; +} + void cmc_ui_close(struct cmc_ui *ui) { - notcurses_stop(ui->nc); + if (ui->nc) notcurses_stop(ui->nc); } diff --git a/src/fruits/cmc/ui/ui.h b/src/fruits/cmc/ui/ui.h index 4af222e..1a49985 100644 --- a/src/fruits/cmc/ui/ui.h +++ b/src/fruits/cmc/ui/ui.h @@ -1,18 +1,33 @@ #pragma once #include +#include #include +enum { + CMC_PANE_SEARCH = 0, +}; + +struct cmc; struct cmc_ui { struct notcurses *nc; + struct aki_event_loop *loop; u32 term_cols; u32 term_rows; bool pending_layout; + struct aki_poll input_poll; + u8 pane; + struct { + struct ncplane *n; + struct cmc_search *search; + } sp; // search pane. + struct cmc *c; }; -bool cmc_ui_init(struct cmc_ui *ui); - -s32 cmc_ui_get_input_fd(struct cmc_ui *ui); -bool cmc_ui_read_input(struct cmc_ui *ui, struct ncinput *input); - +bool cmc_ui_init(struct cmc_ui *ui, struct aki_event_loop *loop, struct cmc *c); void cmc_ui_close(struct cmc_ui *ui); + +void cmc_sp_init(struct cmc_ui *ui); +void cmc_sp_layout(struct cmc_ui *ui, struct ncplane *parent); +bool cmc_sp_handle_input(struct cmc_ui *ui, struct ncinput *input); +void cmc_sp_render(struct cmc_ui *ui); -- cgit v1.2.3-101-g0448