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:
| M | ttcli.c | | | 173 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
| M | ttsrv.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", "e);
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;