Re: interrupting a big loop



Allin Cottrell <cottrell wfu edu> writes:

When my (gtk) app is engaged in a time-consuming loop process, I'd
like to offer the user the chance of breaking out if he/she loses
interest.  The pseudo-code is something like:

for (i=0; i<LARGE_NUMBER; i++) {
   if (break_condition()) break;
   /* do something complicated */
}

Another approach is to run the expensive calculation in an idle
handler:

struct 
{
     [put whatever state your expensive function needs here]
} State;

static gboolean
one_step_of_expensive_calculation (gpointer data)
{
        State *state = data;

        [do one step of the expensive thing here, reading and 
         writing the fields in the "state" variable]

        if (finished) 
        {
                g_free (state);
                return FALSE;
        }
        else
        {
                return TRUE;
        }
}

[...]
state = g_new (State, 1);

idle_id = g_idle_add (one_step_of_expensive_calculation, state);
[...]

The "click" callback can then just remove the idle handler using
g_source_remove (idle_id).
 
Doing things like this is a little more flexible as you can block the
mainloop for other purposes without stopping the calculation. With the
g_main_iteration() approach your calculation is driving the main loop
which means it can't really run "in the background" while other things
are still going on. However, the idle function is more complex to
implement correctly, so it's a tradeoff.


Søren



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