Top |
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.
void
glk_tick (void
);
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. A more parsimonious approach would be once per branch and function call opcode; this guarantees it will be called inside loops. 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()
.
See Events.
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.