From: Christian Heller Date: Mon, 10 Mar 2014 11:55:57 +0000 (+0100) Subject: In client, keybinding databases now store keybindings as arrays instead X-Git-Tag: tce~829 X-Git-Url: https://plomlompom.com/repos/%7B%7B%20web_path%20%7D%7D/decks/%7B%7Bdb.prefix%7D%7D/todo?a=commitdiff_plain;h=0907037fc188c28471805286a67b786264ba3e2f;p=plomrogue In client, keybinding databases now store keybindings as arrays instead of linked lists. --- diff --git a/TODO b/TODO index 7a18afd..766b12d 100644 --- a/TODO +++ b/TODO @@ -32,7 +32,3 @@ CLIENT: - enable toggling of showing "\n" in the window content either as newline breaks (as currently) or as " / " (without newline break) for more efficent screen estate use - -- does get_n_of_keybs() really need to be its own function? (only used once) - -- transform Keybindings struct series from a linked list into an array diff --git a/src/client/control.c b/src/client/control.c index dff79ab..f236ecf 100644 --- a/src/client/control.c +++ b/src/client/control.c @@ -149,21 +149,21 @@ static uint8_t try_server_commands(struct Command * command) extern uint8_t try_key(uint16_t key) { - struct Command * command = get_command_to_keycode(world.kb_global.kbs, key); + struct Command * command = get_command_to_keycode(&world.kb_global, key); if (!command && world.winDB.active) { struct Win * w = get_win_by_id(world.winDB.active); if (0 == w->view) { - command = get_command_to_keycode(w->kb.kbs, key); + command = get_command_to_keycode(&w->kb, key); } else if (1 == w->view) { - command = get_command_to_keycode(world.kb_wingeom.kbs, key); + command = get_command_to_keycode(&world.kb_wingeom, key); } else if (2 == w->view) { - command = get_command_to_keycode(world.kb_winkeys.kbs, key); + command = get_command_to_keycode(&world.kb_winkeys, key); } } if (command) diff --git a/src/client/draw_wins.c b/src/client/draw_wins.c index 59b7c3a..46ef8ed 100644 --- a/src/client/draw_wins.c +++ b/src/client/draw_wins.c @@ -38,19 +38,19 @@ static void add_line(struct Win * w, char * line, attr_t attri); */ static void draw_text_from_bottom(struct Win * win, char * text); -/* Return keybinding list line via "kb_pp", iterate pointer pointed to by it. */ -static char * get_kb_line_and_iterate(struct KeyBinding ** kb_pp); +/* Return a properly formatted keybinding list line for "kb". */ +static char * get_kb_line(struct KeyBinding * kb); /* Draw from line "start" on config view for keybindings defined at "kb". */ static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kb, uint8_t start); /* Draw into window "w" from line "start" on a "title" followed by an empty - * line followed by a list of all keybindings starting at kb_p. + * line followed by a list of all keybindings starting in "kbdb". */ static uint16_t draw_titled_keybinding_list(char * title, struct Win * w, uint16_t start, - struct KeyBinding * kb_p); + struct KeyBindingDB * kbdb); @@ -231,44 +231,40 @@ static void draw_text_from_bottom(struct Win * win, char * text) -static char * get_kb_line_and_iterate(struct KeyBinding ** kb_pp) +static char * get_kb_line(struct KeyBinding * kb) { - char * f_name = "get_kb_line_and_iterate()"; - struct KeyBinding * kb_p = * kb_pp; - char * keyname = get_keyname_to_keycode(kb_p->keycode); - struct Command * command = get_command_to_keycode(kb_p, kb_p->keycode); - uint16_t size = 9 + 1 + strlen(command->dsc_long) + 1; - char * line = try_malloc(size, f_name); - sprintf(line, "%-9s %s", keyname, command->dsc_long); + char * f_name = "get_kb_line()"; + char * keyname = get_keyname_to_keycode(kb->keycode); + uint16_t size = 9 + 1 + strlen(kb->command->dsc_long) + 1; + char * kb_line = try_malloc(size, f_name); + sprintf(kb_line, "%-9s %s", keyname, kb->command->dsc_long); free(keyname); - * kb_pp = kb_p->next; - return line; + return kb_line; } -static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kb, +static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kbdb, uint8_t start) { - if (0 == kb->kbs) + if (0 == kbdb->n_of_kbs) { add_line(w, "(none)", 0); return; } - struct KeyBinding * kb_p = kb->kbs; - uint16_t y; - for (y = start; 0 != kb_p; y++) + uint16_t y, kb_n; + for (y = start, kb_n = 0; kb_n < kbdb->n_of_kbs; y++, kb_n++) { attr_t attri = 0; - if (y - start == kb->select) + if (y - start == kbdb->select) { attri = A_REVERSE; - if (1 == kb->edit) + if (1 == kbdb->edit) { attri = attri | A_BLINK; } } - char * kb_line = get_kb_line_and_iterate(&kb_p); + char * kb_line = get_kb_line(&kbdb->kbs[kb_n]); add_line(w, kb_line, attri); free(kb_line); } @@ -278,21 +274,22 @@ static void draw_keybinding_config(struct Win * w, struct KeyBindingDB * kb, static uint16_t draw_titled_keybinding_list(char * title, struct Win * w, uint16_t start, - struct KeyBinding * kb_p) + struct KeyBindingDB * kbdb) { uint16_t y; uint8_t state = 0; - for (y = start; (0 == state || 0 != kb_p); y++) + uint16_t kb_n = 0; + for (y = start; (0 == state || kb_n < kbdb->n_of_kbs); y++, kb_n++) { if (0 == state) { add_line(w, title, 0); y++; add_line(w, " ", 0); - state = 1 + (0 == kb_p); + state = 1 + (0 == kbdb->n_of_kbs); continue; } - char * kb_line = get_kb_line_and_iterate(&kb_p); + char * kb_line = get_kb_line(&kbdb->kbs[kb_n]); add_line(w, kb_line, 0); free(kb_line); } @@ -379,24 +376,24 @@ extern void draw_win_inventory(struct Win * win) extern void draw_win_available_keybindings(struct Win * win) { char * title = "Active window's keybindings:"; - struct KeyBinding * kb_p; + struct KeyBindingDB * kbdb; struct Win * w = get_win_by_id(world.winDB.active); if (0 == w->view) { - kb_p = w->kb.kbs; + kbdb = &w->kb; } else if (1 == w->view) { - kb_p = world.kb_wingeom.kbs; + kbdb = &world.kb_wingeom; } else if (2 == w->view) { - kb_p = world.kb_winkeys.kbs; + kbdb = &world.kb_winkeys; } - uint16_t offset = draw_titled_keybinding_list(title, win, 0, kb_p); + uint16_t offset = draw_titled_keybinding_list(title, win, 0, kbdb); add_line(win, " ", 0); - struct KeyBinding * kbs_glo = world.kb_global.kbs; - draw_titled_keybinding_list("Global keybindings", win, offset + 1, kbs_glo); + draw_titled_keybinding_list("Global keybindings", win, offset + 1, + &world.kb_global); } diff --git a/src/client/keybindings.c b/src/client/keybindings.c index bad527f..f148afa 100644 --- a/src/client/keybindings.c +++ b/src/client/keybindings.c @@ -5,23 +5,18 @@ #include /* NULL */ #include /* uint8_t, uint16_t, uint32_t */ #include /* FILE, sprintf() */ -#include /* free(), atoi() */ +#include /* atoi() */ #include /* strlen(), strchr(), strcmp() */ #include "../common/err_try_fgets.h" /* err_try_fgets(), err_line() */ #include "../common/readwrite.h" /* try_fwrite()*/ #include "../common/try_malloc.h" /* try_malloc() */ #include "command_db.h" /* get_command() */ +#include "misc.h" /* array_append() */ #include "windows.h" /* draw_all_wins() */ #include "world.h" /* global world */ -/* Return "n"-th keybinding in keybindings chain from "kb_p" on. */ -static struct KeyBinding * get_keyb_of_n(struct KeyBinding * kb_p, uint16_t n); - -/* Return number of keybindings in keybindings chain from "kb_p" on. */ -static uint16_t get_n_of_keybs(struct KeyBinding * kb_p); - /* Return pointer to global keybindings or to keybindings for wingeometry config * (c = "g") or winkeys config (c = "k") or active window's keybindings ("w"). */ @@ -35,58 +30,24 @@ static uint8_t try_keycode(uint16_t keycode_given, char * keyname, -static struct KeyBinding * get_keyb_of_n(struct KeyBinding * kb_p, uint16_t n) -{ - uint16_t i = 0; - while (1) - { - if (n == i) - { - break; - } - i++; - kb_p = kb_p->next; - } - return kb_p; -} - - - -static uint16_t get_n_of_keybs(struct KeyBinding * kb_p) -{ - uint16_t i = 0; - while (1) - { - if (0 == kb_p) - { - break; - } - i++; - kb_p = kb_p->next; - } - return i; -} - - - static struct KeyBindingDB * char_selected_kb_db(char c) { - struct KeyBindingDB * kbd; - kbd = &world.kb_global; + struct KeyBindingDB * kbdb; + kbdb = &world.kb_global; if ('g' == c) { - kbd = &world.kb_wingeom; + kbdb = &world.kb_wingeom; } else if ('k' == c) { - kbd = &world.kb_winkeys; + kbdb = &world.kb_winkeys; } else if ('w' == c) { struct Win * w = get_win_by_id(world.winDB.active); - kbd = &w->kb; + kbdb = &w->kb; } - return kbd; + return kbdb; } @@ -104,16 +65,16 @@ static uint8_t try_keycode(uint16_t keycode_given, char * keyname, -extern struct Command * get_command_to_keycode(struct KeyBinding * kb_p, +extern struct Command * get_command_to_keycode(struct KeyBindingDB * kbdb, uint16_t keycode) { - while (0 != kb_p) + uint16_t n_kb; + for (n_kb = 0; n_kb < kbdb->n_of_kbs; n_kb++) { - if (keycode == kb_p->keycode) + if (keycode == kbdb->kbs[n_kb].keycode) { - return kb_p->command; + return kbdb->kbs[n_kb].command; } - kb_p = kb_p->next; } return NULL; } @@ -164,23 +125,21 @@ extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd) { char * f_name = "write_keybindings_to_file()"; uint16_t linemax = 0; - struct KeyBinding * kb_p = kbd->kbs; - while (0 != kb_p) + uint16_t n_kb; + for (n_kb = 0; n_kb < kbd->n_of_kbs; n_kb++) { - if (strlen(kb_p->command->dsc_short) > linemax) + if (strlen(kbd->kbs[n_kb].command->dsc_short) > linemax) { - linemax = strlen(kb_p->command->dsc_short); + linemax = strlen(kbd->kbs[n_kb].command->dsc_short); } - kb_p = kb_p->next; } linemax = linemax + 6; /* + 6 = + 3 digits + ' ' + '\n' + '\0' */ char line[linemax]; - kb_p = kbd->kbs; - while (0 != kb_p) + for (n_kb = 0; n_kb < kbd->n_of_kbs; n_kb++) { - sprintf(line, "%d %s\n", kb_p->keycode, kb_p->command->dsc_short); + sprintf(line, "%d %s\n", + kbd->kbs[n_kb].keycode, kbd->kbs[n_kb].command->dsc_short); try_fwrite(line, sizeof(char), strlen(line), file, f_name); - kb_p = kb_p->next; } try_fwrite(world.delim, strlen(world.delim), 1, file, f_name); } @@ -188,17 +147,15 @@ extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd) extern void read_keybindings_from_file(char * line, uint32_t linemax, - FILE * file, struct KeyBindingDB * kbd) + FILE * file, struct KeyBindingDB * kbdb) { - char * f_name = "read_keybindings_from_file()"; char * context = "Failed reading keybindings from interface config file. "; char * err_space = "Line illegally ends in whitespace."; char * err_nospace = "No whitespace found in line."; char * err_int = "Line starts not with a decimal number in digits."; char * err_toolarge = "Keycode number too large, must be below 1000."; char * err_cmd = "No such command in command DB."; - struct KeyBinding ** loc_last_ptr = &kbd->kbs; - * loc_last_ptr = 0; + kbdb->n_of_kbs = 0; while (1) { err_try_fgets(line, linemax, file, context, "0nf"); @@ -216,62 +173,46 @@ extern void read_keybindings_from_file(char * line, uint32_t linemax, err_line(line[i] < '0' || '9' < line[i], line, context, err_int); } err_line(i > 3, line, context, err_toolarge); - * loc_last_ptr = try_malloc(sizeof(struct KeyBinding), f_name); - struct KeyBinding * kb_p = * loc_last_ptr; - line[strlen(line) - 1] = '\0'; - kb_p->command = get_command(ptr_space + 1); - err_line(!(kb_p->command), line, context, err_cmd); - kb_p->next = 0; - kb_p->keycode = atoi(line); - loc_last_ptr = & kb_p->next; - } -} - - -extern void free_keybindings(struct KeyBinding * kb_start) -{ - if (0 == kb_start) - { - return; - } - struct KeyBinding * kb_p = kb_start->next; - if (0 != kb_p) - { - free_keybindings(kb_p); + struct KeyBinding kb; + line[strlen(line) - 1] = '\0'; + kb.command = get_command(ptr_space + 1); + err_line(!(kb.command), line, context, err_cmd); + kb.keycode = atoi(line); + array_append(kbdb->n_of_kbs, sizeof(struct KeyBinding), (void *) &kb, + (void **) kbdb); + kbdb->n_of_kbs++; } - free(kb_start); } extern void mod_selected_keyb(char kb_c) { - struct KeyBindingDB * kbd = char_selected_kb_db(kb_c); - kbd->edit = 1; + struct KeyBindingDB * kbdb = char_selected_kb_db(kb_c); + kbdb->edit = 1; draw_all_wins(); cbreak(); int keycode = getch(); halfdelay(world.halfdelay); if (keycode < 1000) { - struct KeyBinding * kb_p = get_keyb_of_n(kbd->kbs, kbd->select); - kb_p->keycode = keycode; + kbdb->kbs[kbdb->select].keycode = keycode; } - kbd->edit = 0; + kbdb->edit = 0; } extern void move_keyb_selection(char kb_c, char dir) { - struct KeyBindingDB * kbd = char_selected_kb_db(kb_c); - if ('u' == dir && kbd->select > 0) + struct KeyBindingDB * kbdb = char_selected_kb_db(kb_c); + if ('u' == dir && kbdb->select > 0) { - kbd->select--; + kbdb->select--; } - else if ('d' == dir && kbd->select < get_n_of_keybs(kbd->kbs) - 1) + else if ('d' == dir && kbdb->select < kbdb->n_of_kbs - 1) { - kbd->select++; + kbdb->select++; } } diff --git a/src/client/keybindings.h b/src/client/keybindings.h index 0d426e3..763ca56 100644 --- a/src/client/keybindings.h +++ b/src/client/keybindings.h @@ -14,7 +14,6 @@ struct Command; struct KeyBinding { - struct KeyBinding * next; uint16_t keycode; struct Command * command; /* command in command DB to which key is bound */ }; @@ -22,14 +21,15 @@ struct KeyBinding struct KeyBindingDB { struct KeyBinding * kbs; + uint16_t n_of_kbs; /* how many KeyBinding structs are stored below .kbs? */ uint16_t select; /* linear list index of keybinding selected for editing */ uint8_t edit; /* 1 if currently editing a keybinding, else 0 */ }; -/* Return command bound to keycode; NULL on failure. */ -extern struct Command * get_command_to_keycode(struct KeyBinding * kb_p, +/* Return command bound to "keycode" in "kbdb"; NULL if none found. */ +extern struct Command * get_command_to_keycode(struct KeyBindingDB * kbdb, uint16_t keycode); /* Return human-readable name (of maximum 9 chars) for "keycode" as matched by @@ -42,9 +42,6 @@ extern void write_keybindings_to_file(FILE * file, struct KeyBindingDB * kbd); extern void read_keybindings_from_file(char * line, uint32_t linemax, FILE * file, struct KeyBindingDB * kbd); -/* Free keybinding chain starting at "kb_start". */ -extern void free_keybindings(struct KeyBinding * kb_start); - /* Mark keybinding in KeybindingDB (char_selected_kb_db()-) selected by "kb_c" * as being edited, get user input to modify it, then unmark it again. Ensure * there are max. three digits in the ASCII string of the kecode read from user. diff --git a/src/client/misc.c b/src/client/misc.c index fcb53ec..9d7539e 100644 --- a/src/client/misc.c +++ b/src/client/misc.c @@ -14,7 +14,7 @@ #include "../common/rexit.h" /* exit_err() */ #include "../common/try_malloc.h" /* try_malloc() */ #include "cleanup.h" /* set_cleanup_flag() */ -#include "keybindings.h" /* free_keybindings(), read_keybindings_from_file(), +#include "keybindings.h" /* read_keybindings_from_file(), * write_keybindings_to_file() */ #include "map.h" /* map_center() */ @@ -79,7 +79,7 @@ extern void load_interface_conf() read_keybindings_from_file(line, linemax, file, &world.kb_winkeys); char active_tmp; char * order_tmp; - read_order_wins_visible_active(line, linemax, file, &order_tmp, &active_tmp); + read_order_wins_visible_active(line, linemax, file, &order_tmp,&active_tmp); while (read_winconf_from_file(line, linemax, file)); try_fclose(file, f_name); @@ -110,9 +110,12 @@ extern void load_interface_conf() extern void unload_interface_conf() { - free_keybindings(world.kb_global.kbs); - free_keybindings(world.kb_wingeom.kbs); - free_keybindings(world.kb_winkeys.kbs); + free(world.kb_global.kbs); + world.kb_global.kbs = NULL; + free(world.kb_wingeom.kbs); + world.kb_wingeom.kbs = NULL; + free(world.kb_winkeys.kbs); + world.kb_winkeys.kbs = NULL; while ('\0' != world.winDB.active) { toggle_window(world.winDB.active); diff --git a/src/client/windows.c b/src/client/windows.c index 674e6ad..763178b 100644 --- a/src/client/windows.c +++ b/src/client/windows.c @@ -23,7 +23,7 @@ * draw_win_keybindings_winconf_geometry(), * draw_win_keybindings_global() */ -#include "keybindings.h" /* free_keybindings(), write_keybidings_to_file(), +#include "keybindings.h" /* write_keybidings_to_file(), * read_keybindings_from_file() */ #include "misc.h" /* array_append() */ @@ -739,7 +739,8 @@ extern void free_winDB() { struct Win * wc = get_win_by_id(id); free(wc->title); - free_keybindings(wc->kb.kbs); + free(wc->kb.kbs); + wc->kb.kbs = NULL; } free(world.winDB.ids); /* NULL this too since add_win_to_winDB() checks */ world.winDB.ids = NULL; /* for it to detect its first post-DB-purge round.*/