X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=src%2Fglk.c;h=c4f395441de42e7331bdc3cb3bf4be1bc9236ee7;hb=91214934fbcdfd363202a65c142194506604ff7b;hp=47c28cb521a89b9a003922c00527b4e948873a07;hpb=c6cb6dcf2f5e1c581a847e8619ee49f75b2ec979;p=projects%2Fchimara%2Fchimara.git diff --git a/src/glk.c b/src/glk.c index 47c28cb..c4f3954 100644 --- a/src/glk.c +++ b/src/glk.c @@ -4,56 +4,95 @@ #include "abort.h" #include "chimara-glk.h" #include "chimara-glk-private.h" +#include "gi_blorb.h" ChimaraGlkPrivate *glk_data = NULL; /** * glk_exit: * - * Shuts down the Glk program. This function does not return. + * If you want to shut down your program in the middle of your + * glk_main() function, you can call glk_exit(). + * + * This function does not return. * * If you print some text to a window and then shut down your program, you can - * assume that the player will be able to read it. + * assume that the player will be able to read it. Most likely the Glk library + * will give a Hit any key to + * exit prompt. (There are other possiblities, however. + * A terminal-window version of Glk might simply exit and leave the last screen + * state visible in the terminal window.) * * - * You should only shut down your program with glk_exit() or by returning from - * your glk_main() function. If you call the ANSI exit() - * function, bad things may happen. This Glk library is designed for multiple - * sessions, for example, and you would be cutting off all the sessions instead - * of just yours. You would also prevent final text from being visible to the - * player. + * You should only shut down your program with glk_exit() or by returning from + * your glk_main() function. If you call the ANSI + * exit() function, bad things may happen. Some versions of + * the Glk library may be designed for multiple sessions, for example, and you + * would be cutting off all the sessions instead of just yours. You would + * probably also prevent final text from being visible to the player. + * + * Chimara + * + * If there are any windows open at the time glk_exit() is called, then Chimara + * will leave them open. This way, the final text remains visible. Note that bad + * things most definitely will happen if you use the ANSI + * exit(). * */ void glk_exit(void) { + g_signal_emit_by_name(glk_data->self, "stopped"); + + /* Stop any timers */ + glk_request_timer_events(0); + + /* Close any open resource files */ + if(glk_data->resource_map != NULL) { + giblorb_destroy_map(glk_data->resource_map); + glk_stream_close(glk_data->resource_file, NULL); + } + + glk_data = NULL; g_thread_exit(NULL); - glk_data = NULL; } /** * glk_tick: * - * Many platforms have some annoying thing that has to be done every so often, - * or the gnurrs come from the voodvork out and eat your computer. - * - * Well, not really. But you should call glk_tick() every so often, just in - * case. It may be necessary to yield time to other applications in a - * cooperative-multitasking OS, or to check for player interrupts in an infinite - * loop. - * - * This call is fast; in fact, on average, it does nothing at all. So you can - * call it often. (In a virtual machine interpreter, once per opcode is - * appropriate. In a program with lots of computation, pick a comparable rate.) + * Carries out platform-dependent actions such as yielding time to the operating + * system and checking for interrupts. glk_tick() should be called every so + * often when there is a long interval between calls of glk_select() or + * glk_select_poll(). This call is fast; in fact, on average, it does nothing at + * all. So you can call it often. + * + * + * In a virtual machine interpreter, once per opcode is appropriate. In a + * program with lots of computation, pick a comparable rate. + * * * glk_tick() does not try to update the screen, or check for player input, or * any other interface task. For that, you should call glk_select() or - * glk_select_poll(). + * glk_select_poll(). See Events. * - * Basically, you must ensure there's some fixed upper bound on the amount of - * computation that can occur before a glk_tick() (or glk_select()) occurs. In a - * VM interpreter, where the VM code might contain an infinite loop, this is - * critical. In a C program, you can often eyeball it. + * + * Captious critics have pointed out that in the sample program + * model.c, I do not call glk_tick() at all. This is + * because model.c has no heavy loops. It does a bit of + * work for each command, and then cycles back to the top of the event loop. + * The glk_select() call, of course, blocks waiting for input, so it does all + * the yielding and interrupt-checking one could imagine. + * + * Basically, you must ensure there's some fixed upper bound on the + * amount of computation that can occur before a glk_tick() (or glk_select()) + * occurs. In a VM interpreter, where the VM code might contain an infinite + * loop, this is critical. In a C program, you can often eyeball it. + * + * But the next version of model.c will have a + * glk_tick() in the ornate printing loop of verb_yada(). + * Just to make the point. + * + * */ void glk_tick() @@ -66,3 +105,4 @@ glk_tick() gtk_main_iteration(); gdk_threads_leave(); } +