Re: [MacPerl-Toolbox] A difficulty with Mac-Events.pm
[email protected] (Alan Fry) Fri, 6 Apr 2001 12:42:02 +0100
| Newsgroups | perl.macperl.toolbox |
|---|---|
| Message-ID | <p05010401b6f34ab38d93@[158.152.146.73]> |
At 9:52 am +0200 05/04/01, Matthias Neeracher wrote: >In article <p05010400b6ef3fcf9e7a@[158.152.146.73]>, Alan Fry ><[email protected]> writes: > >> However in the case of the script involving the browser the problem >> does not seem to arise during the BEGIN sequence but later on as the > > script runs. For instance the script 'hangs' at the lines: > >Ah! Now that rings a bell (I haven't actually done much toolbox Perl >programming in a long time, so your first post didn't trigger much). Now, >though, I seem to remember that the issue is that the inclusion of >Mac::Events is the trigger for switching MacPerl from implicit event handling >(MacPerl does it for you) to explicit event handling (MacPerl avoids handling >events unless you call WaitNextEvent explicitly). Many thanks for the explanation. I suspected something of the kind might be up. In the application proposed a MacWindow would be used running alongside a browser window keeping a log of what was happening as the Perl scrip unfolded. The first problem is to find a way of keeping both the browser window and the MacPerl window alive to 'mouseDown' (and possibly other) events in their regions. A way of doing this is to interleave the window's 'WaitNextEvent' with the browser's 'listen'. In the particular application the browser's package is of the general form while(1) {[do stuff]} so we write in the 'while(1)' loop: while ( 1 ) { my $connection; while (!$connection) { $connection = $socket->accept; # has a 'x' second timeout $gui->pause; # has a 10 ticks timer $gui->{win}->redraw # to be sure the window updates } # $gui == reference to window object if ($connection) { ..... [program runs logging happenings] ..... } } and in the MacWindow package: sub pause { my ($ref) = @_; my $ticks = TickCount() + 10; while(TickCount() < $ticks){ WaitNextEvent } } This has the effect that the program cycles endlessly round listening for browser requests (for 'x' seconds) and looking for mouse clicks for (say) 10 ticks. If the socket timer is based on the four-element select() (which it is in IO::Socket) values of x shorter than 1 second are possible. Even with 1 second the arrangement feels reasonably 'comfortable'. Mouse events and browser requests are not lost if the program is away at the time so to speak, since it seems both will queue up. The second problem is more obscure, but it seems that opportunistic events (I suspect 'idle' events) occurring while the browser is composing a long (say 30K+) page will cut the connection. If that happens an incomplete page is the usual result. Netscape and MS InternetExplorer behave differently; sad to say IE gives a more graceful performance. That can be avoided by a timer loop giving adequate time for the page to be composed along the lines: my $del = int length($html)/250; # determine delay time print $connection $html; # download the page $html my $tim = TickCount() + $del; while (TickCount() < $tim) {WaitNextEvent}; # give browser time In this example the allowance is set to 250 bytes per 'tick' which seems (so far as one can tell visually) to give about a 25% safety margin on this machine at least. I suppose to be portable between Macs of various ages and speeds some enquiries ought to made from 'gestalt' to determine the appropriate allowance. It would be much nicer if one could get from the browser a 'finished writing' signal but I don't know how to do this if indeed it is possible. Quite how this timer loop functions is shrouded in mystery, but it does seem to be reliable. >I'm sorry if this is inconveniencing you, but I seem to remember that this >seemed like the only reasonable way to reconcile the needs of plain perl >scripts with the needs of fancy tooplbox clients. I'm sure you're right and it is pretty much a 'force majeure'. It poses some interesting questions however for MacWindows used in these kind of circumstances. Similar difficulties arise using MacWindows for 'progress bar' applications for instance. The 'interleaving' trick might be useful more widely than just the special case of a browser logging window so I hope this rather overlong message might be of some general interest. Alan Fry