[racket] Threads, Windows, and World

From: Drew Hess (drew.hess at gmail.com)
Date: Thu Mar 3 12:26:56 EST 2011

Hi all,

While I've got everyone's attention with this play-sound issue, here's
a related problem I'm having.

Another thing I added to my version of the Bootstrap teachpack, in
addition to customizable sounds, is the ability to play
background songs while the game is running. The students really liked
this functionality -- in fact, I think it's fair to say that playing
back sounds and songs was probably the most enthusiastic reaction I
got from my students since they learned to draw images.

Anyway, the only way I could figure out how to do it, in
the limited time I had available, was to start a separate thread in
the initialization procedure that loops through all of the sound files
provided in a list of songs, which is supplied by the student. I
was going to try to prepare a simple example of this, but since
I've already bundled the Bootstrap teachpack up, along with a
working game, I might as well just reference the actual
implementation. Here is the expression that kicks things off
in the Bootstrap teachpack's start procedure:

    (begin
      (big-bang 640 480 .1 world true)
      (on-redraw draw-world)
      (on-tick-event update-world)
      (on-key-event keypress*)
      (when (not (null? song-list))
        (thread (lambda ()
                  (letrec ((loop-songs
                            (lambda ()
                              (begin
                                (map
                                 (lambda (filename) (play-sound filename #f))
                                 song-list)
                                (loop-songs)))))
                    (loop-songs))))))))

This background song-playing thread works fine on Mac OS X, except
for the annoying fact that when you quit the game, the songs keep
playing (i.e., the background thread is not killed when the World
window is closed).

It does *not* work on Windows. The thread appears to block the GUI
when it starts playing the first song in the list, and though the
song plays back fine, the GUI never updates again. This behavior
is unrelated to the DrRacket porting issues I ran into, as it's
reproducible in DrScheme 4.2.5 on Windows, too, though I could
have sworn it used to work.

I would love to get some opinions on this, if someone has time to
look into it. I know that Bootstrap is developed externally, but
I don't think it's a Bootstrap issue, per se, as much as it is
an issue with World and threads on Windows. It's easy to reproduce:
just download the package I made available for the other issues
I'm having:

http://drewhess.com/drew-bootstrap.zip

Add a couple of WAV file names to the song-list variable in
drew-game.ss, make sure they're in the same directory as drew-game.ss,
and run the program on Mac OS X. Observe that songs play back fine
while the game is running (except that, as I mentioned above,
they keep playing when the game window is closed; I would love to
know how to hook a window-closed event so that I can kill the thread
when this happens).

Now try the same program on Windows, and observe that the songs play,
but the GUI window never refreshes.

I'm not married to the implementation I came up with -- it's a
total hack that never really worked properly because of the
unclean shutdown, anyway, so if there's a better way to do this,
I'm all ears.

thanks!
d


Posted on the users mailing list.