tt

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit b3d6da5c2f700d7a3e563dfd6b2c5e15ae8c0cb5
parent 02c05873bb9a00540c01b4753df50be15937445e
Author: Pablo Cárdenas <pablo.cardenas@imca.edu.pe>
Date:   Mon, 24 Jun 2024 10:39:39 -0500

Asynchronous update on every key

Diffstat:
Mttcli.c | 173++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mttsrv.c | 47+++++++++++++++++++++++++++++------------------
2 files changed, 135 insertions(+), 85 deletions(-)

diff --git a/ttcli.c b/ttcli.c @@ -12,7 +12,7 @@ #define AHEAD_SHOW 4 #define AHEAD_HIDE 2 -#define WAIT_TIME 2000000000 +#define WAIT_TIME 1500000000 #define MAX(a, b) ((a) < (b) ? (b) : (a)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -59,7 +59,7 @@ void print_text( (last_input.tv_sec - first_input.tv_sec) + (last_input.tv_nsec - first_input.tv_nsec) / 1000000000.0; - mvwprintw(win, 9, 24, " WPM: %.0f",(pos / 5.0) / (elapsed / 60.0)); + mvwprintw(win, 9, 24, " WPM: %.0f", (pos / 5.0) / (elapsed / 60.0)); mvwprintw(win, 10, 24, "Errors: %d", count_errors); mvwprintw(win, 11, 24, " Slows: %d", count_slows); wrefresh(win); @@ -122,33 +122,35 @@ void print_text( int y = i / 58; int x = i % 58; + int c = text[i] == ' ' ? '_' : text[i]; + wattron(win, COLOR_PAIR(3)); if (i < spaces[current_word]) { wattron(win, A_DIM); - mvwprintw(win, y, x, "%c", text[i]); + mvwprintw(win, y, x, "%c", c); wattroff(win, A_DIM); } else if (i < spaces[space_start]) { if (error) { wattron(win, COLOR_PAIR(4)); - mvwprintw(win, y, x, "%c", text[i]); + mvwprintw(win, y, x, "%c", c); wattroff(win, COLOR_PAIR(4)); } else if (diff_back < WAIT_TIME) { wattron(win, A_BOLD); - mvwprintw(win, y, x, "%c", text[i]); + mvwprintw(win, y, x, "%c", c); wattroff(win, A_BOLD); } else if (diff_input < WAIT_TIME) { mvwprintw(win, y, x, "_"); } else { /* wattron(win, A_BOLD); */ - mvwprintw(win, y, x, "%c", text[i]); + mvwprintw(win, y, x, "%c", c); /* wattroff(win, A_BOLD); */ } } else if (i < spaces[space_end]) { wattron(win, A_BOLD); - mvwprintw(win, y, x, "%c", text[i]); + mvwprintw(win, y, x, "%c", c); wattroff(win, A_BOLD); } else { - mvwprintw(win, y, x, "%c", text[i]); + mvwprintw(win, y, x, "%c", c); } wattroff(win, COLOR_PAIR(3)); } @@ -228,6 +230,9 @@ int main(int argc, const char *argv[]) char recv_step = 0; char outdated = 0; + char header_type; + short header_length; + int pos; int error; int count_errors = 0; @@ -250,7 +255,7 @@ int main(int argc, const char *argv[]) FD_ZERO(&writefds); FD_SET(0, &readfds); FD_SET(sockfd, &readfds); - if (outdated == 1 && recv_step == 0) { + if (outdated == 1) { FD_SET(sockfd, &writefds); } @@ -258,7 +263,8 @@ int main(int argc, const char *argv[]) select(FD_SETSIZE, &readfds, &writefds, NULL, &select_timeout); if (FD_ISSET(0, &readfds)) { - if (first_input.tv_sec == 0 && first_input.tv_nsec == 0) { + if (first_input.tv_sec == 0 && + first_input.tv_nsec == 0) { clock_gettime(CLOCK_REALTIME, &first_input); } @@ -298,9 +304,11 @@ int main(int argc, const char *argv[]) 1000000000 + current.tv_nsec - last_input.tv_nsec; - if (pos < length && !error && diff_back > WAIT_TIME) { + if (pos < length && !error && + diff_back > WAIT_TIME) { if (c == text[pos]) { - if (pos != 0 && diff_input > WAIT_TIME) { + if (pos != 0 && + diff_input > WAIT_TIME) { count_slows++; } last_input = current; @@ -315,64 +323,95 @@ int main(int argc, const char *argv[]) } if (FD_ISSET(sockfd, &readfds)) { - if (recv_step == 0) { - memset(&last_back, 0, sizeof last_back); - memset(&last_input, 0, sizeof last_input); - memset(&first_input, 0, sizeof first_input); - - error = 0; - count_errors = 0; - count_slows = 0; - - length = recv(sockfd, text, 4096, 0); - if (length == 0) { - endwin(); - fprintf(stderr, "Closed by server\n"); - close(sockfd); - return 0; - } - text[length] = '\0'; - - spaces[0] = -1; - num_spaces = 1; - for (int i = 0; i < length; i++) { - pos_to_word[i] = num_spaces - 1; - if (isspace(text[i])) { - spaces[num_spaces] = i + 1; - num_spaces++; - } - } - spaces[num_spaces] = length; - num_spaces++; - - pos = 0; - } else if (recv_step == 1) { - int recv_length = - recv(sockfd, &num_players, 1, 0); - if (recv_length == 0) { - endwin(); - fprintf(stderr, "Closed by server\n"); - close(sockfd); - return 0; + int buffer_length; + void *buffer; + switch (recv_step) { + case 0: + // HEADER + buffer_length = 1; + buffer = &header_type; + break; + case 1: + // LENGTH + buffer_length = 2; + buffer = &header_length; + break; + case 2: + // MESSAGE + buffer_length = header_length; + if (header_type == 0) { + buffer = &text; + } else if (header_type == 1) { + buffer = &state_players; } - if (num_players != 0) { - recv_step = 2; - } else { + break; + } + + int recv_length = + recv(sockfd, buffer, buffer_length, 0); + + if (recv_length == 0) { + endwin(); + fprintf(stderr, "Closed by server\n"); + close(sockfd); + return 0; + } + + switch (recv_step) { + case 0: + recv_step = 1; + break; + case 1: + if (header_length == 0) { recv_step = 0; + } else { + recv_step = 2; } - } else if (recv_step == 2) { - int recv_length = - recv(sockfd, - state_players, - num_players * sizeof(struct state), - 0); - if (recv_length == 0) { - endwin(); - fprintf(stderr, "Closed by server\n"); - close(sockfd); - return 0; - } + break; + + case 2: recv_step = 0; + if (header_type == 0) { + length = recv_length; + text[length] = '\0'; + + memset(&last_back, 0, sizeof last_back); + memset(&last_input, + 0, + sizeof last_input); + memset(&first_input, + 0, + sizeof first_input); + + error = 0; + count_errors = 0; + count_slows = 0; + + spaces[0] = -1; + num_spaces = 1; + for (int i = 0; i < length; i++) { + pos_to_word[i] = num_spaces - 1; + if (isspace(text[i])) { + spaces[num_spaces] = + i + 1; + num_spaces++; + } + } + spaces[num_spaces] = length; + num_spaces++; + + pos = 0; + num_players = 0; + } else if (header_type == 1) { + num_players = header_length / + (sizeof(struct state)); + mvprintw( + 20, + 0, + "num_players = %d", + num_players); + } + break; } } @@ -381,8 +420,8 @@ int main(int argc, const char *argv[]) .pos = pos, }; send(sockfd, &state, sizeof state, 0); - recv_step = 1; outdated = 0; + mvprintw(19, 0, "sent %d", pos); } print_text( diff --git a/ttsrv.c b/ttsrv.c @@ -21,8 +21,7 @@ int main(int argc, const char *argv[]) return 1; } - struct json_object *root = - json_object_from_file(argv[2]); + struct json_object *root = json_object_from_file(argv[2]); if (!root) { fprintf(stderr, "Failed to parse JSON file.\n"); return 1; @@ -56,7 +55,6 @@ int main(int argc, const char *argv[]) FD_SET(sockfd, &set); struct state states[FD_SETSIZE]; - int length = 0; while (1) { fd_set readfds = set; @@ -72,8 +70,11 @@ int main(int argc, const char *argv[]) if (!((*buffer != '\n' && *buffer != '\0') && (*endptr == '\0' || *endptr == '\n'))) { fprintf(stderr, "Error parsing quote index.\n"); - } else if (!(0 <= quote_idx && quote_idx < num_quotes)) { - fprintf(stderr, "0 <= quote_index < %d.\n", num_quotes); + } else if (!(0 <= quote_idx && + quote_idx < num_quotes)) { + fprintf(stderr, + "0 <= quote_index < %d.\n", + num_quotes); } else { json_object *quote = json_object_array_get_idx( quotes, quote_idx); @@ -81,13 +82,15 @@ int main(int argc, const char *argv[]) quote, "text", &quote); const char *str_quote = json_object_get_string(quote); - length = strlen(str_quote); + short length = strlen(str_quote); for (int i = 0; i < FD_SETSIZE; i++) { states[i].pos = 0; if (!(i != 0 && i != sockfd && FD_ISSET(i, &set))) { continue; } + send(i, "\x00", 1, 0); + send(i, &length, sizeof length, 0); send(i, str_quote, length, 0); } } @@ -106,7 +109,8 @@ int main(int argc, const char *argv[]) continue; } - int length = recv(fd, &states[fd], 16, 0); + int length = + recv(fd, &states[fd], sizeof(struct state), 0); if (length == 0) { states[fd].pos = 0; printf("Disconnected\n"); @@ -114,20 +118,27 @@ int main(int argc, const char *argv[]) continue; } - struct state buffer[FD_SETSIZE]; - unsigned short buffer_size = 0; - for (int i = 0; i < FD_SETSIZE; i++) { - if (!(i != 0 && i != fd && i != sockfd && - FD_ISSET(i, &set))) { + for (int dest = 0; dest < FD_SETSIZE; dest++) { + if (!(dest != 0 && dest != fd && + dest != sockfd && FD_ISSET(dest, &set))) { continue; } - buffer[buffer_size++] = states[i]; + struct state buffer[FD_SETSIZE]; + unsigned short buffer_size = 0; + for (int i = 0; i < FD_SETSIZE; i++) { + if (!(i != 0 && i != dest && + i != sockfd && + FD_ISSET(i, &set))) { + continue; + } + buffer[buffer_size++] = states[i]; + } + buffer_size *= sizeof(struct state); + + send(dest, "\x01", 1, 0); + send(dest, &buffer_size, 2, 0); + send(dest, buffer, buffer_size, 0); } - send(fd, &buffer_size, 1, 0); - send(fd, - buffer, - buffer_size * (sizeof(struct state)), - 0); } } return 0;