From: Carl Worth Date: Sat, 28 Mar 2009 18:00:43 +0000 (-0700) Subject: Merge branch 'master' into image X-Git-Url: https://git.cworth.org/git?p=mnemon;a=commitdiff_plain;h=f8f80304015cb290a550fdb7624a2531d8a10b06;hp=-c Merge branch 'master' into image --- f8f80304015cb290a550fdb7624a2531d8a10b06 diff --combined mnemon.c index d0a9609,33f2c26..74eb2c0 --- a/mnemon.c +++ b/mnemon.c @@@ -55,11 -55,6 +55,11 @@@ typedef enum CATEGORY_ORDER_SEQUENTIAL } category_order_t; +typedef enum { + CHALLENGE_TYPE_TEXT, + CHALLENGE_TYPE_IMAGE +} challenge_type_t; + typedef struct _category { char *name; int items_size; @@@ -71,8 -66,6 +71,8 @@@ /* Support categories where responses are timed (0.0 == disable). */ double time_limit; int bin_zero_head; + /* Support challenges of non-text types (image, audio, etc.) */ + challenge_type_t challenge_type; } category_t; typedef struct _mnemon { @@@ -200,7 -193,6 +200,7 @@@ category_init (category_t *category category->order = CATEGORY_ORDER_RANDOM; category->time_limit = 0.0; category->bin_zero_head = 0; + category->challenge_type = CHALLENGE_TYPE_TEXT; } static void @@@ -270,17 -262,6 +270,17 @@@ category_print (category_t *category fprintf (file, "time = %f\n\n", category->time_limit); + fprintf (file, "challenge = "); + switch (category->challenge_type) { + case CHALLENGE_TYPE_TEXT: + fprintf (file, "text"); + break; + case CHALLENGE_TYPE_IMAGE: + fprintf (file, "image"); + break; + } + fprintf (file, "\n\n"); + for (i = 0; i < category->num_items; i++) { item = &category->items[i]; if (i != 0) @@@ -597,7 -578,7 +597,7 @@@ mnemon_load_category (mnemon_t *mnemon /* An initial digit means we hit an item. Trigger the * spaghetti machine. */ - if (*line >= '0' && *line <= '9') + if ((*line >= '0' && *line <= '9') || *line == '-') goto PARSE_BIN; equal = strchr (line, '='); @@@ -637,16 -618,6 +637,16 @@@ value, path, line_count); exit (1); } + } else if (strcmp (name, "challenge") == 0) { + if (strcmp (value, "text") == 0) { + category->challenge_type = CHALLENGE_TYPE_TEXT; + } else if (strcmp (value, "image") == 0) { + category->challenge_type = CHALLENGE_TYPE_IMAGE; + } else { + fprintf (stderr, "Unknown value for \"challenge\" option \"%s\" at %s:%d\n", + value, path, line_count); + exit (1); + } } else { fprintf (stderr, "Unknown option %s at %s:%d\n", name, path, line_count); @@@ -894,9 -865,20 +894,20 @@@ mnemon_select_item (mnemon_t *mnemon category_t *category; bin_index = rand_within_exponential (mnemon->num_bins); - bin = &mnemon->bins[bin_index]; + /* The most intuitive understanding of the to_introduce counter is + * that it's tracking never-before-learned items as they are + * pulled from the bin with score 0. But that bin can become + * empty. So the refined rule is that we decrement to_introduce + * whenever we pull from the lowest-indexed bin with a + * non-negative score. */ + if (mnemon->to_introduce && bin->score >=0 && + (bin_index == 0 || mnemon->bins[bin_index-1].score < 0)) + { + mnemon->to_introduce--; + } + item_index = rand_within (bin->num_items); item = bin->items[item_index]; @@@ -1131,35 -1113,6 +1142,35 @@@ mnemon_handle_response (mnemon_t *mnemo bin_add_item (bin, item); } +static void +mnemon_show_image (mnemon_t *mnemon, const char *filename) +{ + char *command; + + /* XXX: Yes, shelling out to system is total cheese. The planned + * fix here is to bring graphical display in process, (or at least + * have a custom external program that accepts image filenames on + * stdin. + */ + xasprintf (&command, "xli -gamma 2.2 %s >/dev/null 2>&1 &", + filename); + system (command); + free (command); +} + +static void +mnemon_hide_image (mnemon_t *mnemon) +{ + char * command; + + /* XXX: And this is just embarrassing (obviously wrong in several + * ways). Hopefully I'll amend away any commit that includes this. + */ + xasprintf (&command, "killall xli"); + system (command); + free (command); +} + static void mnemon_do_challenges (mnemon_t *mnemon) { @@@ -1206,38 -1159,18 +1217,35 @@@ mnemon_select_item (mnemon, &bin, &item_index, &category); item = bin->items[item_index]; - if (bin->score == 0) - mnemon->to_introduce--; - while (1) { if (category->time_limit > 0.0) { response = readline ("The next one is timed. Press enter when ready:"); free (response); } - - printf ("%s\n", item->challenge); + + switch (category->challenge_type) { + case CHALLENGE_TYPE_TEXT: + printf ("%s\n", item->challenge); + break; + case CHALLENGE_TYPE_IMAGE: + { + char *absolute_filename; + + xasprintf (&absolute_filename, "%s/%s", + mnemon->dir_name, item->challenge); + mnemon_show_image (mnemon, absolute_filename); + free (absolute_filename); + } + break; + } gettimeofday (&start, NULL); response = readline ("> "); gettimeofday (&end, NULL); + if (category->challenge_type == CHALLENGE_TYPE_IMAGE) + mnemon_hide_image (mnemon); + /* Terminate on EOF */ if (response == NULL) { printf ("\n");