diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-05-25 19:30:41 +0200 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-05-25 20:05:58 +0200 |
| commit | 5ce8953bcb98e037f50a37abadf664d95ee69cc2 (patch) | |
| tree | 5aac0bb58b637e3d7085cc0d7eafc113fa330a7e /data/client.cpp | |
| parent | 65ce077940bc5916b7c67fde1856b112ba38de39 (diff) | |
data client (WIP)
Diffstat (limited to 'data/client.cpp')
| -rw-r--r-- | data/client.cpp | 161 |
1 files changed, 99 insertions, 62 deletions
diff --git a/data/client.cpp b/data/client.cpp index f0ffa6a..65494b0 100644 --- a/data/client.cpp +++ b/data/client.cpp @@ -1,16 +1,22 @@ +#include <arpa/inet.h> #include <GLFW/glfw3.h> #include <imgui.h> #include <imgui_impl_glfw.h> #include <imgui_impl_opengl3.h> #include <implot.h> +#include <json-c/json.h> #include <limits.h> #include <math.h> #include <signal.h> +#include <threads.h> #include <initializer_list> #include "logger.c" +#define FETCH_INTERVAL 10 +#define FETCH_INTERVAL_SUBDIV 1000 + #define COLOR_BG ImVec4(0.f, 0.f, 0.f, 1.f) #define FONT_SIZE 12.f #define FONT_SOURCE "/usr/share/fonts/droid/DroidSansMono.ttf" @@ -43,17 +49,13 @@ struct Plot { const char *const *cols; }; -// Globals +// Window globals GLFWwindow *g_window; ImGuiIO *g_io; ImGuiStyle *g_imgui_style; ImPlotStyle *g_implot_style; -int g_status; - -// Data col -bool g_data_col_visible = true; -float g_data_col_width; +// Data globals const char *g_x_axes[] = { "rowid", "steps", @@ -62,6 +64,7 @@ const char *g_x_axes[] = { #undef FOR_CORE }; +int g_status; int g_entries = DEFAULT_ENTRIES; int g_nth = DEFAULT_NTH; int g_x_axis = DEFAULT_X_AXIS; @@ -70,9 +73,10 @@ int g_x_high = DEFAULT_X_HIGH; int g_hm_left = DEFAULT_HM_LEFT; int g_hm_pixel_count = DEFAULT_HM_PIXEL_COUNT; int g_hm_pixel_pow; // calculate on startup -bool g_data_touched; +int g_x_current; +thrd_t g_data_fetching_thread; -// Plots +// Plot globals Plot g_plots[] = { Plot("cycl", "general", { #define FOR_CORE(i) "cycl_" #i, @@ -114,7 +118,9 @@ Plot g_plots[] = { #define PLOT_COUNT (int)(sizeof(g_plots) / sizeof(g_plots[0])) -// Layout +// Layout globals +float g_data_col_width; +bool g_data_col_visible = true; int g_plot_cols = 2; int g_plot_col_selected; int g_plot_row_selected; @@ -135,7 +141,7 @@ void data_clamp(int *field, int low, int high) { if (*field > high) *field = high; } -void data_validate(void) { +void data_touched(void) { data_clamp(&g_entries, 1, DEFAULT_ENTRIES); data_clamp(&g_nth, DEFAULT_NTH, INT_MAX); data_clamp(&g_x_low, DEFAULT_X_LOW, INT_MAX); @@ -145,7 +151,7 @@ void data_validate(void) { #endif data_clamp(&g_hm_pixel_count, 1, DEFAULT_HM_PIXEL_COUNT); data_clamp(&g_hm_pixel_pow, 0, data_calc_max_hm_pixel_pow()); - g_data_touched = false; + g_x_current = 0; } void data_reset_values(void) { @@ -160,24 +166,75 @@ void data_reset_values(void) { } void data_reset_plot_cells(void) { - for (size_t i = 0; i < PLOT_MAX_COLS; i++) { - for (size_t j = 0; j < PLOT_COUNT; j++) { + for (int i = 0; i < PLOT_MAX_COLS; i++) { + for (int j = 0; j < PLOT_COUNT; j++) { g_plot_cells[i][j] = nullptr; } } } +void data_fetch(void) { + struct json_object *request = json_object_new_object(); + json_object_object_add(request, "request", json_object_new_string("data")); + json_object_object_add(request, "entries", json_object_new_int(g_entries)); + json_object_object_add(request, "nth", json_object_new_int(g_nth)); + json_object_object_add(request, "x-axis", json_object_new_string(g_x_axes[g_x_axis])); + json_object_object_add(request, "x-low", json_object_new_int(g_x_low)); + json_object_object_add(request, "x-high", json_object_new_int(g_x_high)); + json_object_object_add(request, "hm-left", json_object_new_int(g_hm_left)); + json_object_object_add(request, "hm-pixel-count", json_object_new_int(g_hm_pixel_count)); + json_object_object_add(request, "hm-pixel-pow", json_object_new_int(g_hm_pixel_pow)); + json_object_object_add(request, "x-current", json_object_new_int(g_x_current)); + const char *request_str = json_object_to_json_string(request); + + log_info("Sending request to server: %s", request_str); + int socket_fd = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in socket_addr; + memset(&socket_addr, 0, sizeof(struct sockaddr_in)); + socket_addr.sin_family = AF_INET; + socket_addr.sin_port = htons(PORT); + inet_pton(AF_INET, IP, &socket_addr.sin_addr); + if (connect(socket_fd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_in))) assert(false); + json_object_to_fd(socket_fd, request, 0); + shutdown(socket_fd, SHUT_WR); + + struct json_object *response = json_object_from_fd(socket_fd); + const char *response_str = json_object_to_json_string(response); + log_info("Server responded with: %s", response_str); + + json_object_put(request); + json_object_put(response); +} + +int data_fetching_thread(void *data) { + (void)data; + + assert(g_status == STATUS_RUNNING || g_status == STATUS_STOPPING); + + while (g_status == STATUS_RUNNING) { + data_fetch(); + + for (int i = 0; i < FETCH_INTERVAL_SUBDIV && g_status == STATUS_RUNNING; i++) { + usleep((FETCH_INTERVAL * 1000000) / FETCH_INTERVAL_SUBDIV); + } + } + + assert(g_status == STATUS_STOPPING); + g_status = STATUS_STOPPED; + return 0; +} + void data_start_fetching(void) { - assert(g_status == STATUS_RUNNING); log_info("Starting data fetching thread"); - // start data fetching thread + g_status = STATUS_RUNNING; + thrd_create(&g_data_fetching_thread, (thrd_start_t)data_fetching_thread, nullptr); } void data_stop_fetching(void) { - assert(g_status == STATUS_STOPPING); + assert(g_status == STATUS_RUNNING); log_info("Stopping data fetching thread"); - // join data fetching thread (set STATUS_STOPPED from within thread) - g_status = STATUS_STOPPED; + g_status = STATUS_STOPPING; + thrd_join(g_data_fetching_thread, nullptr); } // ---------------------------------------------------------------------------- @@ -207,47 +264,30 @@ void gui_print_data_col(void) { #endif ImGui::LabelText("data-push", "%#lx", DATA_PUSH_INTERVAL); - switch (g_status) { - case STATUS_STOPPED: - ImGui::LabelText("status", "%s", "stopped"); - break; - case STATUS_RUNNING: - ImGui::LabelText("status", "%s", "running"); - break; - case STATUS_STOPPING: - ImGui::LabelText("status", "%s", "stopping"); - break; - } - ImGui::SeparatorText("Data fields"); switch (g_status) { case STATUS_STOPPED: - if (ImGui::InputInt("entries", &g_entries, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; - if (ImGui::InputInt("nth", &g_nth, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; + if (ImGui::InputInt("entries", &g_entries, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); + if (ImGui::InputInt("nth", &g_nth, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); if (ImGui::BeginCombo("x-axis", g_x_axes[g_x_axis])) { for (int i = 0; i < CORES + 2; i++) { if (ImGui::Selectable(g_x_axes[i], g_x_axis == i)) { g_x_axis = i; - g_data_touched = true; + data_touched(); } } ImGui::EndCombo(); } - if (ImGui::InputInt("x-low", &g_x_low, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; - if (ImGui::InputInt("x-high", &g_x_high, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; - if (ImGui::InputInt("hm-left", &g_hm_left, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; - if (ImGui::InputInt("hm-pxl-count", &g_hm_pixel_count, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; - if (ImGui::InputInt("hm-pxl-pow", &g_hm_pixel_pow, 0, 0, ImGuiInputTextFlags_CharsDecimal)) g_data_touched = true; - - if (ImGui::Button("Run", ImVec2(-1.f, 0.f))) { - g_status = STATUS_RUNNING; - data_start_fetching(); - } - + if (ImGui::InputInt("x-low", &g_x_low, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); + if (ImGui::InputInt("x-high", &g_x_high, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); + if (ImGui::InputInt("hm-left", &g_hm_left, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); + if (ImGui::InputInt("hm-pxl-count", &g_hm_pixel_count, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); + if (ImGui::InputInt("hm-pxl-pow", &g_hm_pixel_pow, 0, 0, ImGuiInputTextFlags_CharsDecimal)) data_touched(); + if (ImGui::Button("Run", ImVec2(-1.f, 0.f))) data_start_fetching(); if (ImGui::Button("Reset", ImVec2(-1.f, 0.f))) data_reset_values(); break; @@ -263,10 +303,10 @@ void gui_print_data_col(void) { ImGui::LabelText("hm-pxl-pow", "%d", g_hm_pixel_pow); if (g_status == STATUS_RUNNING) { - if (ImGui::Button("Stop", ImVec2(-1.f, 0.f))) { - g_status = STATUS_STOPPING; - data_stop_fetching(); - } + if (ImGui::Button("Stop", ImVec2(-1.f, 0.f))) data_stop_fetching(); + ImGui::LabelText("##", "Running"); + } else { + ImGui::LabelText("##", "Stopping"); } } @@ -311,11 +351,11 @@ void gui_print_plots(void) { } if (ImPlot::BeginPlot(g_plots[i].name)) { - int test_x[] = {0,1,2,3}; - int test_y1[] = {1,2,3,4}; - int test_y2[] = {2,4,8,16}; - ImPlot::PlotLine("test1", test_x, test_y1, 4); - ImPlot::PlotLine("test2", test_x, test_y2, 4); + //int test_x[] = {0,1,2,3}; + //int test_y1[] = {1,2,3,4}; + //int test_y2[] = {2,4,8,16}; + //ImPlot::PlotLine("test1", test_x, test_y1, 4); + //ImPlot::PlotLine("test2", test_x, test_y2, 4); ImPlot::EndPlot(); } @@ -346,11 +386,11 @@ void gui_print_plot_maximized(void) { ImGui::Begin("plot-fullscreen", nullptr, WINDOW_STYLE); if (ImPlot::BeginPlot(g_plot_selected->name, viewport->Size)) { - int test_x[] = {0,1,2,3}; - int test_y1[] = {1,2,3,4}; - int test_y2[] = {2,4,8,16}; - ImPlot::PlotLine("test1", test_x, test_y1, 4); - ImPlot::PlotLine("test2", test_x, test_y2, 4); + //int test_x[] = {0,1,2,3}; + //int test_y1[] = {1,2,3,4}; + //int test_y2[] = {2,4,8,16}; + //ImPlot::PlotLine("test1", test_x, test_y1, 4); + //ImPlot::PlotLine("test2", test_x, test_y2, 4); ImPlot::EndPlot(); } @@ -373,6 +413,7 @@ void sig_handler(int signo) { (void)signo; log_warn("Signal received, will stop SALIS data client..."); + if (g_status == STATUS_RUNNING) data_stop_fetching(); glfwSetWindowShouldClose(g_window, GLFW_TRUE); } @@ -513,10 +554,6 @@ int main(int argc, char **argv) { gui_print(); - if (g_data_touched) { - data_validate(); - } - ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(g_window, &display_w, &display_h); |
