Eliminated warnings about static functions declared with G_GNUC_INTERNAL
[projects/chimara/chimara.git] / src / glk.c
index 47c28cb521a89b9a003922c00527b4e948873a07..c4f395441de42e7331bdc3cb3bf4be1bc9236ee7 100644 (file)
--- 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 <function>
+ * glk_main()</function> 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 <quote><computeroutput>Hit any key to 
+ * exit</computeroutput></quote> 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.)
  *
  * <note><para>
- *  You should only shut down your program with glk_exit() or by returning from
- *  your glk_main() function. If you call the ANSI <function>exit()</function> 
- *  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 <function>glk_main()</function> function. If you call the ANSI 
+ * <function>exit()</function> 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.
+ * </para></note>
+ * <note><title>Chimara</title>
+ * <para>
+ * 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 <emphasis>will</emphasis> happen if you use the ANSI
+ * <function>exit()</function>.
  * </para></note>
  */
 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.
+ *
+ * <note><para>
+ *   In a virtual machine interpreter, once per opcode is appropriate. In a
+ *   program with lots of computation, pick a comparable rate.
+ * </para></note>
  * 
  * 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 <link linkend="chimara-Events">Events</link>.
  * 
- * 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.
+ * <note>
+ *   <para>Captious critics have pointed out that in the sample program
+ *   <filename>model.c</filename>, I do not call glk_tick() at all. This is
+ *   because <filename>model.c</filename> 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.
+ *   </para>
+ *   <para>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.
+ *   </para>
+ *   <para>But the next version of <filename>model.c</filename> will have a
+ *   glk_tick() in the ornate printing loop of <function>verb_yada()</function>.
+ *   Just to make the point.
+ *   </para>
+ * </note>
  */
 void
 glk_tick()
@@ -66,3 +105,4 @@ glk_tick()
                gtk_main_iteration();
        gdk_threads_leave();
 }
+