home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book HomeMastering Perl/TkSearch this book

15.9. Coexisting with Other GUI Main Loops

It's perfectly possible to have more than one GUI main loop running concurrently. It's a simple matter of cooperation and balance. By balance, we mean how the events are portioned out. It's very easy for one main loop to "take control" and "starve" the other loop of processing time. In this section, we'll demonstrate how to use both OpenGL and Tk widgets in the same application. We've found that, generally, to keep Tk events flowing, it's sufficient to call update once in a while. If update starves OpenGL, we fall back to DoOneEvent.

DoOneEvent allows us to fine tune a Tk event loop by processing only selected events, which we specify by bit pattern. We can inclusively OR the following symbols together and define the desired bit pattern: WINDOW_EVENTS, FILE_EVENTS, TIMER_EVENTS, and IDLE_EVENTS. To specify all possible events, use ALL_EVENTS, and to make the DoOneEvent call nonblocking, add DONT_WAIT.

When passed ALL_EVENTS, DoOneEvent processes events as they arise and puts the application to sleep when no further events are outstanding. DoOneEvent first looks for a window or I/O event and, if found, calls the handler and returns. If there is no window or I/O event, it looks for a single timer event, invokes the callback, and returns. If no window, I/O, or timer event is ready, all pending idle callbacks are executed, if any. In all cases, DoOneEvent returns 1.

When passed DONT_WAIT, DoOneEvent works as described, except that, if there are no events to process, it returns immediately with a value of 0, indicating it didn't find any work to do.

It's actually rather difficult to find a use for DoOneEvent. One example is the bouncing ball widget demonstration, although it might have been better written using timer callbacks. But it is simulating a simulation, and simulations typically want to run as fast as possible, so we can't fault the implementation.

Even games don't usually require DoOneEvent. Here are two scenarios in which you might use it. Example one probably never reaches the MainLoop statement. It runs as fast as possible, consuming all available CPU time, and depends on update to process events.

&run;
MainLoop;

sub run {
    while (1) {
        &dogame;
        $mw->update;
    }
}

Example two establishes a repeating timer event, then enters MainLoop to process events. The game progresses at a more or less stately speed, with an update occurring every 50 milliseconds. Unlike example one, this example does not consume all available CPU time.

$mw->repeat(50 => \&run);
MainLoop;

sub run {
    &dogame;
    $mw->update;
}


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.