diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-05-12 22:52:37 +0200 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-05-25 04:38:15 +0200 |
| commit | be2c37ac8c8e317eb7e05829ff2078c1b3bbce4e (patch) | |
| tree | 46caefa23c106ae789bdd49ab59daeca69cb2d3d /data/client.c | |
| parent | 522e11c8086b7d8ab76b9be07c1861f35ed2327f (diff) | |
Reimplement client with ImGui and ImPlot (scaffold)
Diffstat (limited to 'data/client.c')
| -rw-r--r-- | data/client.c | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/data/client.c b/data/client.c deleted file mode 100644 index d5e8e56..0000000 --- a/data/client.c +++ /dev/null @@ -1,522 +0,0 @@ -#include <curses.h> -#include <locale.h> -#include <stdlib.h> -#include <string.h> - -#include "logger.c" -#include "plots.c" -#include "tui.c" - -#define UI_AVAIL_PLOTS_COL PANE_AND_MARGIN_WIDTH -#define UI_WINDOWS_COL (PANE_AND_MARGIN_WIDTH * 2) -#define UI_PLOTS_COL (PANE_AND_MARGIN_WIDTH * 3) - -#define MAX_WINDOW_ROWS 4 -#define MAX_WINDOW_COLS 4 -#define MAX_WINDOW_PLOTS (MAX_WINDOW_ROWS * MAX_WINDOW_COLS) - -#define CTRL(x) (x & 0x1f) - -enum { - PAIR_HEADER = 1, - PAIR_SELECTED = 2, - PAIR_TO_BE_CREATED = 3, - PAIR_TO_BE_UPDATED = 4, - PAIR_TO_BE_REMOVED = 5, -}; - -enum UIColumn { - UICOL_AVAIL_PLOTS, - UICOL_WINDOWS, - UICOL_PLOTS, - UICOL_COUNT, -}; - -enum WindowState { - WINDOW_TO_BE_CREATED, - WINDOW_TO_BE_UPDATED, - WINDOW_IS_LIVE, - WINDOW_TO_BE_REMOVED, -}; - -enum WindowPlotState { - PLOT_TO_BE_CREATED, - PLOT_IS_LIVE, - PLOT_TO_BE_REMOVED, -}; - -struct WindowHandle { - size_t wid; - size_t rows; - size_t cols; - size_t rows_update; - size_t cols_update; - enum WindowState state; - size_t plot_count; - size_t plot_sel; - enum WindowPlotState plot_states[MAX_WINDOW_PLOTS]; - struct PlotDef *plot_defs[MAX_WINDOW_PLOTS]; -}; - -// Globals -bool g_exit; -enum UIColumn g_col_sel; -size_t g_apsel; -size_t g_wsel; -size_t g_apscroll; -size_t g_wscroll; -size_t g_pscroll; -size_t g_wid_count; -struct WindowHandle *g_window_handles; -size_t g_window_count; -size_t g_window_cap; - -// ---------------------------------------------------------------------------- -// UI functions -// ---------------------------------------------------------------------------- -void ui_print_sim_description(void) { - // Simulation desciption - int l = 1; - - tui_line(false, l++, PAIR_HEADER, A_BOLD, "SALIS DATA CLIENT"); - tui_str_field(l++, "name", NAME); - tui_ulx_field(l++, "seed", SEED); - tui_str_field(l++, "conn", IP ":" PORT_STR); - tui_str_field(l++, "anc", ANC); - tui_str_field(l++, "arch", ARCH); - tui_ulx_field(l++, "asav", AUTOSAVE_INTERVAL); - tui_ulx_field(l++, "cres", CORES); -#if defined(MUTA_FLIP) - tui_str_field(l++, "mflp", "true"); -#else - tui_str_field(l++, "mflp", "false"); -#endif - tui_ulx_field(l++, "mrng", MUTA_RANGE); - tui_ulx_field(l++, "size", MVEC_SIZE); -#if defined(MVEC_LOOP) - tui_str_field(l++, "loop", "true"); -#else - tui_str_field(l++, "loop", "false"); -#endif -#if defined(COMPRESS) - tui_str_field(l++, "xsav", "enabled"); -#else - tui_str_field(l++, "xsav", "disabled"); -#endif - tui_ulx_field(l++, "dpsi", DATA_PUSH_INTERVAL); - - // Window summary - l++; - - tui_line(false, l++, PAIR_HEADER, A_BOLD, "SUMMARY"); - tui_uld_field(l++, "wcnt", g_window_count); - tui_uld_field(l++, "wcap", g_window_cap); - tui_uld_field(l++, "widc", g_wid_count); -} - -void ui_print_avail_plots(void) { - int l = 1; - int pair = g_col_sel == UICOL_AVAIL_PLOTS ? PAIR_SELECTED : PAIR_HEADER; - - tui_field(l++, UI_AVAIL_PLOTS_COL, pair, A_BOLD, "AVAIL PLOTS [%ld:%ld]", g_apsel, g_apscroll); - - for (size_t i = g_apscroll; i < g_general_plots_count; i++) { - pair = i == g_apsel ? PAIR_SELECTED : PAIR_NORMAL; - tui_field(l++, UI_AVAIL_PLOTS_COL, pair, A_NORMAL, g_general_plots_def[i].name); - } -} - -void ui_print_windows(void) { - int l = 1; - int pair = g_col_sel == UICOL_WINDOWS ? PAIR_SELECTED : PAIR_HEADER; - - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - tui_field(l++, UI_WINDOWS_COL, pair, A_BOLD, "WINDOWS [%ld:%ld]", whdl->wid, g_wscroll); - - for (size_t i = g_wscroll; i < g_window_count; i++) { - whdl = &g_window_handles[i]; - char mark = ' '; - - switch (whdl->state) { - case WINDOW_TO_BE_CREATED: - pair = PAIR_TO_BE_CREATED; - mark = '+'; - break; - case WINDOW_TO_BE_UPDATED: - pair = PAIR_TO_BE_UPDATED; - mark = 'u'; - break; - case WINDOW_IS_LIVE: - pair = PAIR_NORMAL; - break; - case WINDOW_TO_BE_REMOVED: - pair = PAIR_TO_BE_REMOVED; - mark = 'd'; - break; - } - - pair = i == g_wsel ? PAIR_SELECTED : pair; - tui_field(l++, UI_WINDOWS_COL, pair, A_NORMAL, "wid:%ld [%dx%d] %c", whdl->wid, whdl->rows_update, whdl->cols_update, mark); - } -} - -void ui_print_plots(void) { - int l = 1; - int pair = g_col_sel == UICOL_PLOTS ? PAIR_SELECTED : PAIR_HEADER; - - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - tui_field(l++, UI_PLOTS_COL, pair, A_BOLD, "PLOTS [%ld:%ld]", whdl->plot_sel, g_pscroll); - - if (!g_window_count) return; - - for (size_t i = g_pscroll; i < whdl->plot_count; i++) { - struct PlotDef *plot_def = whdl->plot_defs[i]; - enum WindowPlotState plot_state = whdl->plot_states[i]; - char mark = ' '; - - switch (plot_state) { - case PLOT_TO_BE_CREATED: - pair = PAIR_TO_BE_CREATED; - mark = '+'; - break; - case PLOT_IS_LIVE: - pair = PAIR_NORMAL; - break; - case PLOT_TO_BE_REMOVED: - pair = PAIR_TO_BE_REMOVED; - mark = 'd'; - break; - } - - pair = i == whdl->plot_sel ? PAIR_SELECTED : pair; - tui_field(l++, UI_PLOTS_COL, pair, A_NORMAL, "%s %c", plot_def->name, mark); - plot_def++; - } -} - -void ui_print_footer(void) { - tui_field(LINES - 1, 1, PAIR_NORMAL, A_NORMAL, "[+] new window | [enter] add plot | [x] delete elem | [ctrl+c] quit"); -} - -void ui_print(void) { - ui_print_sim_description(); - ui_print_avail_plots(); - ui_print_windows(); - ui_print_plots(); - ui_print_footer(); -} - -// ---------------------------------------------------------------------------- -// Control function -// ---------------------------------------------------------------------------- -void ev_scroll(int ev) { - size_t *scroll_var = NULL; - - switch (g_col_sel) { - case UICOL_AVAIL_PLOTS: - scroll_var = &g_apscroll; - break; - case UICOL_WINDOWS: - scroll_var = &g_wscroll; - break; - case UICOL_PLOTS: - scroll_var = &g_pscroll; - break; - default:; - } - - assert(scroll_var); - - switch (ev) { - case 'w': - *scroll_var += 1; - break; - case 's': - *scroll_var -= (*scroll_var ? 1 : 0); - break; - case 'q': - *scroll_var = 0; - break; - } -} - -void ev_new_window(void) { - if (g_window_count == g_window_cap) { - // Reallocate dynamic array - size_t new_window_cap = g_window_cap * 2; - struct WindowHandle *new_window_handles = calloc(new_window_cap, sizeof(struct WindowHandle)); - memcpy(new_window_handles, g_window_handles, sizeof(struct WindowHandle) * g_window_count); - free(g_window_handles); - g_window_cap = new_window_cap; - g_window_handles = new_window_handles; - } - - g_window_count++; - g_window_handles[g_window_count - 1] = (struct WindowHandle){ - .wid = g_wid_count++, - .rows = 2, - .cols = 2, - .rows_update = 2, - .cols_update = 2, - .state = WINDOW_TO_BE_CREATED, - }; -} - -void ev_delete_window_handle(size_t widx) { - assert(g_window_count); - assert(widx < g_window_count); - assert(g_window_handles[widx].state == WINDOW_TO_BE_CREATED); - - for (size_t i = widx; i < g_window_count - 1; i++) { - memcpy(&g_window_handles[i], &g_window_handles[i + 1], sizeof(struct WindowHandle)); - } - - g_window_handles[g_window_count - 1] = (struct WindowHandle){ 0 }; - g_window_count--; - g_wsel -= (g_window_count && g_wsel == g_window_count) ? 1 : 0; -} - -void ev_add_plot(void) { - assert(g_col_sel == UICOL_AVAIL_PLOTS); - assert(g_window_count); - - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - size_t max_plots = whdl->rows_update * whdl->cols_update; - size_t pidx = 0; - - do { - if (!whdl->plot_defs[pidx]) break; - pidx++; - } while (pidx < max_plots); - - if (pidx == max_plots) return; - - whdl->plot_count++; - whdl->plot_states[pidx] = PLOT_TO_BE_CREATED; - whdl->plot_defs[pidx] = &g_general_plots_def[g_apsel]; -} - -void ev_delete_plot(size_t widx) { - assert(g_window_count); - assert(widx < g_window_count); - - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - assert(whdl->plot_count); - assert(whdl->plot_sel < whdl->plot_count); - assert(whdl->plot_states[whdl->plot_sel] == PLOT_TO_BE_CREATED); - - for (size_t i = whdl->plot_sel; i < whdl->plot_count - 1; i++) { - whdl->plot_states[i] = whdl->plot_states[i + 1]; - whdl->plot_defs[i] = whdl->plot_defs[i + 1]; - } - - whdl->plot_states[whdl->plot_count - 1] = 0; - whdl->plot_defs[whdl->plot_count - 1] = NULL; - whdl->plot_count--; - - if (!whdl->plot_count) { - whdl->plot_sel = 0; - } else if (whdl->plot_sel >= whdl->plot_count) { - whdl->plot_sel = whdl->plot_count - 1; - } -} - -void ev_delete_elem(void) { - if (g_col_sel == UICOL_WINDOWS && g_window_count) { - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - - switch (whdl->state) { - case WINDOW_TO_BE_CREATED: - ev_delete_window_handle(g_wsel); - break; - case WINDOW_TO_BE_UPDATED: - break; - case WINDOW_IS_LIVE: - break; - case WINDOW_TO_BE_REMOVED: - break; - } - } - - if (g_col_sel == UICOL_PLOTS && g_window_count && g_window_handles[g_wsel].plot_count) { - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - - switch (whdl->plot_states[whdl->plot_sel]) { - case PLOT_TO_BE_CREATED: - ev_delete_plot(g_wsel); - break; - case PLOT_IS_LIVE: - break; - case PLOT_TO_BE_REMOVED: - break; - } - } -} - -void ev_resize_window(int ev) { - assert(g_col_sel == UICOL_WINDOWS); - assert(g_window_count); - - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - - switch (ev) { - case 'A': - if (whdl->cols_update > 1 && (whdl->rows_update * (whdl->cols_update - 1)) >= whdl->plot_count) whdl->cols_update--; - break; - case 'D': - whdl->cols_update += whdl->cols_update < MAX_WINDOW_COLS ? 1 : 0; - break; - case 'W': - if (whdl->rows_update > 1 && (whdl->cols_update * (whdl->rows_update - 1)) >= whdl->plot_count) whdl->rows_update--; - break; - case 'S': - whdl->rows_update += whdl->rows_update < MAX_WINDOW_ROWS ? 1 : 0; - break; - } -} - -void ev_swap_plots(int ev) { - assert(g_col_sel == UICOL_PLOTS); - assert(g_window_count); - - struct WindowHandle *whdl = &g_window_handles[g_wsel]; - size_t pidx1; - size_t pidx2; - - switch (ev) { - case 'W': - if (!whdl->plot_count || !whdl->plot_sel) return; - pidx1 = whdl->plot_sel; - pidx2 = whdl->plot_sel - 1; - whdl->plot_sel--; - break; - case 'S': - if (!whdl->plot_count || whdl->plot_sel >= whdl->plot_count - 1) return; - pidx1 = whdl->plot_sel; - pidx2 = whdl->plot_sel + 1; - whdl->plot_sel++; - break; - } - - enum WindowPlotState tmp_state = whdl->plot_states[pidx1]; - whdl->plot_states[pidx1] = whdl->plot_states[pidx2]; - whdl->plot_states[pidx2] = tmp_state; - - struct PlotDef *tmp_def = whdl->plot_defs[pidx1]; - whdl->plot_defs[pidx1] = whdl->plot_defs[pidx2]; - whdl->plot_defs[pidx2] = tmp_def; -} - -void ev_handle(void) { - int ev = getch(); - - switch (ev) { - case CTRL('c'): - g_exit = true; - break; - case KEY_RESIZE: - tui_line_buff_resize(); - break; - case 'w': - case 's': - case 'q': - ev_scroll(ev); - break; - case 'Q': - g_apscroll = 0; - g_wscroll = 0; - g_pscroll = 0; - break; - case KEY_LEFT: - g_col_sel -= g_col_sel ? 1 : 0; - break; - case KEY_RIGHT: - g_col_sel += g_col_sel < UICOL_COUNT - 1 ? 1 : 0; - break; - case KEY_UP: - if (g_col_sel == UICOL_AVAIL_PLOTS && g_apsel) g_apsel--; - if (g_col_sel == UICOL_WINDOWS && g_wsel) g_wsel--; - if (g_col_sel == UICOL_PLOTS && g_window_count && g_window_handles[g_wsel].plot_sel) g_window_handles[g_wsel].plot_sel--; - break; - case KEY_DOWN: - if (g_col_sel == UICOL_AVAIL_PLOTS && g_apsel < g_general_plots_count - 1) g_apsel++; - if (g_col_sel == UICOL_WINDOWS && g_window_count && g_wsel < g_window_count - 1) g_wsel++; - if (g_col_sel == UICOL_PLOTS && g_window_count && g_window_handles[g_wsel].plot_count && g_window_handles[g_wsel].plot_sel < g_window_handles[g_wsel].plot_count - 1) g_window_handles[g_wsel].plot_sel++; - break; - case '+': - ev_new_window(); - break; - case '\n': - if (g_col_sel == UICOL_AVAIL_PLOTS && g_window_count) ev_add_plot(); - break; - case 'x': - ev_delete_elem(); - break; - case 'A': - case 'D': - case 'W': - case 'S': - if (g_col_sel == UICOL_WINDOWS && g_window_count) ev_resize_window(ev); - if (g_col_sel == UICOL_PLOTS && g_window_count) ev_swap_plots(ev); - break; - default: - break; - } -} - -// ---------------------------------------------------------------------------- -// Main functions -// ---------------------------------------------------------------------------- -void init(void) { - log_info("Initializing salis data client"); - - setlocale(LC_ALL, ""); - - initscr(); - raw(); - noecho(); - curs_set(0); - keypad(stdscr, TRUE); - - start_color(); - init_color(COLOR_BLACK, 0, 0, 0); - - init_pair(PAIR_NORMAL, COLOR_WHITE, COLOR_BLACK); - init_pair(PAIR_HEADER, COLOR_BLUE, COLOR_BLACK); - init_pair(PAIR_SELECTED, COLOR_YELLOW, COLOR_BLACK); - init_pair(PAIR_TO_BE_CREATED, COLOR_GREEN, COLOR_BLACK); - init_pair(PAIR_TO_BE_UPDATED, COLOR_GREEN, COLOR_BLACK); - init_pair(PAIR_TO_BE_REMOVED, COLOR_RED, COLOR_BLACK); - - tui_line_buff_resize(); - - g_window_count = 0; - g_window_cap = 1; - g_window_handles = calloc(g_window_cap, sizeof(struct WindowHandle)); -} - -void exec(void) { - while (!g_exit) { - ui_print(); - ev_handle(); - clear(); - } -} - -void quit(void) { - tui_line_buff_free(); - endwin(); - log_info("Shutting down salis data client"); -} - -int main(void) { - init(); - exec(); - quit(); - - free(g_window_handles); - g_window_count = 0; - g_window_cap = 0; - - return 0; -} |
