Re: Nesting GTK main loops



On Tue, 20 Feb 2007 19:52:53 +1100
Andrew Cowie <andrew operationaldynamics com> wrote:

>Can anyone suggest _why_ you'd ever want to nest GTK main loops?
>
>
>Since inner main loops don't prevent things from being re-entered in
>what is, in effect, a recursive way, the ability to enter nested main
>loops seems a recipe for confusion. Is there something obvious I'm
>missing?
>Andrew Frederick Cowie

Hi, on the Gtk2-perl maillist awhile back, this was posted by 
(the very knowledgable) muppet. It suggests you can use
nested mainloops for a non-blocking delay. 

<quote>
If your code path is already convoluted, or breaking the
operation out into clean iterations is no so easy, you can retain linear
flow control by inserting a main-loop-based delay.  That is, use your
own mainloop to block at the current code point to run the
mainloop. I've found this works well in very deep, complicated things that
are already hard to understand and would only be made worse by
turning them into state machines --- highly interdependent cross cases,
lots of variables,
etc. 

sub non_blocking_delay{ 
   my $milliseconds =shift; 
   my $mainloop = Glib::MainLoop->new; 
         Glib::Timeout->add ($milliseconds, 
                            sub{ 
                                   $mainloop->quit;
                                   FALSE; 
                                  });
$mainloop->run; 
}                                                                                         
                                                                                          
The advantage is that your code flow stays rather linear.
The disadvantage is that if you need two such things to interleave,
this idiom will get very much in the way.  A real state machine allows
you to run arbitrary numbers of these timeouts cleanly.                     

On the other hand, if what you want isn't so much to run the
handler every so often, but to yield processing in order to break up a
long operation, an idle will make your app more responsive. 

sub handle_next_chunk{ 
   my $state =shift; 
   # dostuff... 
  return $n_chunks_remaining >0; 
}                                                                                 
...                                                                                       
Glib::Idle->add (handle_next_chunk,$state);

This accomplishes the same thing as Grant's example, but
doesn't insert a delay which is likely longer than necessary.  Idles are
non- recursive by default, so this will run whenever the mainloop is
idle until you run out of chunks.  I've seen this used to run a
"live video" mode that captures from a video source as fast as
possible, but still responds to gui events.    
</quote>


zentara

-- 
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]