summaryrefslogtreecommitdiff
path: root/src/fruits/cmsrv
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-11-22 14:22:11 -0500
committerAndrew Opalach <andrew@akon.city> 2025-11-22 14:22:11 -0500
commit0d6d13425015d78606232874498327cabcb0e4e2 (patch)
tree34682f9e9602117dac6db5f7de8c67d1207135c4 /src/fruits/cmsrv
parentd4ea79a8622b6bf03555f186aeb1f5fa9283721f (diff)
downloadcamu-0d6d13425015d78606232874498327cabcb0e4e2.tar.gz
camu-0d6d13425015d78606232874498327cabcb0e4e2.tar.bz2
camu-0d6d13425015d78606232874498327cabcb0e4e2.zip
Fixes and cleanup around synced gapless
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/fruits/cmsrv')
-rw-r--r--src/fruits/cmsrv/cmsrv.c88
-rw-r--r--src/fruits/cmsrv/ui.c27
2 files changed, 86 insertions, 29 deletions
diff --git a/src/fruits/cmsrv/cmsrv.c b/src/fruits/cmsrv/cmsrv.c
index 8e24701..ef66be8 100644
--- a/src/fruits/cmsrv/cmsrv.c
+++ b/src/fruits/cmsrv/cmsrv.c
@@ -36,6 +36,19 @@ struct cmsrv {
#endif
};
+static void close_cmsrv(struct cmsrv *s)
+{
+#ifdef CMSRV_LOCAL_SOCKET
+ nn_line_processor_stop(&s->local.cli);
+#endif
+#ifdef CMSRV_USE_UI
+ nn_poll_stop(&s->input_poll);
+ nn_timer_stop(&s->render_timer);
+#endif
+ camu_server_close(&s->server);
+ nn_signal_stop(&s->quit_signal);
+}
+
#ifdef CMSRV_LOCAL_SOCKET
static u8 server_line_callback(void *userdata, str *line)
{
@@ -43,10 +56,34 @@ static u8 server_line_callback(void *userdata, str *line)
struct lia_list *list = al_array_at(s->server.lists, 0);
if (al_str_eq(line, &al_str_c(";PAUSE"))) {
lia_list_toggle_pause(list, LIANA_SEQUENCE_ANY, -1.0);
- } else if (al_str_eq(line, &al_str_c(";NEXT"))) {
- lia_list_skip(list, LIANA_SEQUENCE_ANY, 1);
- } else if (al_str_eq(line, &al_str_c(";PREV"))) {
- lia_list_skip(list, LIANA_SEQUENCE_ANY, -1);
+ } else if (al_str_cmp(line, &al_str_c(";NEXT"), 0, 5) == 0) {
+ s32 n = 1;
+ if (line->length > 6) {
+ str arg = al_str_substr(line, 6, line->length);
+ bool error;
+ s64 i = al_str_to_long(&arg, 10, &error);
+ if (!error) n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ }
+ lia_list_skip(list, LIANA_SEQUENCE_ANY, n);
+ } else if (al_str_cmp(line, &al_str_c(";PREV"), 0, 5) == 0) {
+ s32 n = -1;
+ if (line->length > 6) {
+ str arg = al_str_substr(line, 6, line->length);
+ bool error;
+ s64 i = -al_str_to_long(&arg, 10, &error);
+ if (!error) n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ }
+ lia_list_skip(list, LIANA_SEQUENCE_ANY, n);
+ } else if (al_str_cmp(line, &al_str_c(";SEEK"), 0, 5) == 0) {
+ if (line->length > 6) {
+ str arg = al_str_substr(line, 6, line->length);
+ bool error;
+ s64 i = al_str_to_long(&arg, 10, &error);
+ if (!error) {
+ i *= 1000000;
+ lia_list_seek(list, LIANA_SEQUENCE_ANY, 0, CLAMP(i, (s64)0, (s64)INT64_MAX));
+ }
+ }
} else if (al_str_eq(line, &al_str_c(";SHUFFLE"))) {
lia_list_shuffle(list);
} else if (al_str_eq(line, &al_str_c(";SORT"))) {
@@ -54,22 +91,24 @@ static u8 server_line_callback(void *userdata, str *line)
} else if (al_str_eq(line, &al_str_c(";REVERSE"))) {
lia_list_reverse(list);
} else if (al_str_eq(line, &al_str_c(";CLEAR"))) {
- //lia_list_clear(list);
+ lia_list_clear(list);
} else {
struct nn_packet *packet = nn_packet_create();
nn_packet_write_str(packet, line);
camu_server_local_add(&s->server, packet);
+ nn_packet_free(packet);
}
return NNWT_LINE_PROCESSOR_CONTINUE;
}
#endif
#ifdef CMSRV_USE_UI
-static void render_timer_callback(void *userdata, struct nn_timer *timer)
+static s32 log_callback(void *userdata, u8 level, char *message)
{
struct cmsrv *s = (struct cmsrv *)userdata;
- (void)timer;
- cmsrv_ui_render(&s->ui);
+ (void)level;
+ cmsrv_ui_push_message(&s->ui, al_strndup(message, AL_LOG_MESSAGE_SIZE));
+ return al_strnlen(message, AL_LOG_MESSAGE_SIZE);
}
static void input_poll_callback(void *userdata, s32 revents)
@@ -82,7 +121,7 @@ static void input_poll_callback(void *userdata, s32 revents)
if (input.evtype == NCTYPE_PRESS || input.evtype == NCTYPE_UNKNOWN) {
switch (input.id) {
case 'q':
- nn_event_loop_break_one(&s->loop);
+ close_cmsrv(s);
break;
case '1':
cmsrv_ui_set_pane(&s->ui, CMSRV_UI_LISTS);
@@ -98,19 +137,18 @@ static void input_poll_callback(void *userdata, s32 revents)
}
}
-static s32 log_callback(void *userdata, u8 level, char *message)
+static void render_timer_callback(void *userdata, struct nn_timer *timer)
{
struct cmsrv *s = (struct cmsrv *)userdata;
- (void)level;
- cmsrv_ui_push_message(&s->ui, al_strndup(message, AL_LOG_MESSAGE_SIZE));
- return al_strnlen(message, AL_LOG_MESSAGE_SIZE);
+ (void)timer;
+ cmsrv_ui_render(&s->ui);
}
#endif
static void quit_signal_callback(void *userdata)
{
struct cmsrv *s = (struct cmsrv *)userdata;
- nn_event_loop_break_one(&s->loop);
+ close_cmsrv(s);
}
static struct cmsrv s = { 0 };
@@ -127,16 +165,17 @@ s32 wmain(s32 argc, wchar_t **argv)
s32 main(s32 argc, char *argv[])
#endif
{
- (void)argc;
- (void)argv;
- if (!nn_common_init("cmsrv_main")) return EXIT_FAILURE;
+ if (!nn_common_init("cmsrv_main")) {
+ return EXIT_FAILURE;
+ }
+
#ifdef CMSRV_USE_UI
- if (!cmsrv_ui_init(&s.ui, &s.server)) return EXIT_FAILURE;
+ if (!cmsrv_ui_init(&s.ui, &s.server)) {
+ return EXIT_FAILURE;
+ }
al_set_print(log_callback, &s);
#endif
- signal(SIGINT, sigint_handler);
-
#ifdef CAMU_HAVE_FFMPEG
camu_ff_common_init();
#endif
@@ -145,6 +184,7 @@ s32 main(s32 argc, char *argv[])
nn_signal_init(&s.quit_signal, &s.loop, quit_signal_callback, &s);
nn_signal_start(&s.quit_signal);
+ signal(SIGINT, sigint_handler);
camu_server_init(&s.server, &s.loop);
if (!camu_server_listen(&s.server, CAMU_TEST_TYPE, &CAMU_TEST_ADDR, CAMU_PORT)) {
@@ -174,11 +214,19 @@ s32 main(s32 argc, char *argv[])
nn_event_loop_run(&s.loop);
+#ifdef CMSRV_LOCAL_SOCKET
+ nn_socket_close(&s.local.sock);
+#endif
#ifdef CMSRV_USE_UI
cmsrv_ui_close(&s.ui);
#endif
+ camu_server_free(&s.server);
+ nn_event_loop_destroy(&s.loop);
nn_common_close();
+ (void)argc;
+ (void)argv;
+
return EXIT_SUCCESS;
}
diff --git a/src/fruits/cmsrv/ui.c b/src/fruits/cmsrv/ui.c
index e8fbc41..d96c09d 100644
--- a/src/fruits/cmsrv/ui.c
+++ b/src/fruits/cmsrv/ui.c
@@ -81,18 +81,22 @@ static void render_log(struct cmsrv_ui *ui)
u32 max_height = ncplane_dim_y(n) - 2;
u32 size = ui->log.messages.count;
- u32 index = (size > max_height) ? size - max_height : 0;
- for (u32 i = index; i < size; i++) {
+ if (size > max_height) {
+ u32 index = size - max_height;
+ for (u32 i = 0; i < index; i++) {
+ al_free(al_array_at(ui->log.messages, i));
+ }
+ al_array_remove_range(ui->log.messages, 0, index);
+ }
+ size = ui->log.messages.count;
+ al_assert(size <= max_height);
+ for (u32 i = 0; i < size; i++) {
u32 x = 1;
- u32 y = (i - index) + 1;
- // We can't use putnstr here to control the width because lots of
- // these messages will have wide characters.
+ u32 y = i + 1;
+ // We can't use putnstr here to control the width because lots of these
+ // messages will have wide characters.
ncplane_putstr_yx(n, y, x, al_array_at(ui->log.messages, i));
}
- for (u32 i = 0; i < index; i++) {
- al_free(al_array_at(ui->log.messages, i));
- }
- al_array_remove_range(ui->log.messages, 0, index);
u64 c = 0;
ncchannels_set_fg_default(&c);
@@ -242,4 +246,9 @@ void cmsrv_ui_render(struct cmsrv_ui *ui)
void cmsrv_ui_close(struct cmsrv_ui *ui)
{
notcurses_stop(ui->nc);
+ char *message;
+ al_array_foreach(ui->log.messages, i, message) {
+ al_free(message);
+ }
+ al_array_free(ui->log.messages);
}