lmi
[Top][All Lists]
Advanced

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

Re: [lmi] [lmi-commits] master 489f0a2 1/2: Show busy cursor when cuttin


From: Greg Chicares
Subject: Re: [lmi] [lmi-commits] master 489f0a2 1/2: Show busy cursor when cutting and pasting
Date: Tue, 26 Jun 2018 00:36:27 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

On 2018-06-25 21:55, Vadim Zeitlin wrote:
> On Mon, 25 Jun 2018 09:14:19 -0400 (EDT) Greg Chicares <address@hidden> wrote:
> 
> GC> branch: master
> GC> commit 489f0a265f13b421fb846d18084a2d491191a75b
> GC> Author: Gregory W. Chicares <address@hidden>
> GC> Commit: Gregory W. Chicares <address@hidden>
> GC> 
> GC>     Show busy cursor when cutting and pasting
> GC>     
> GC>     These operations take a noticeable amount of time for large censuses.
> 
>  But unfortunately when they do not take a noticeable amount of time, this
> probably just results in annoying cursor flickering. I really wish there
> were a simple way to only show some indicator of the program being busy
> only if some operation takes longer than some (configurable but with a
> reasonable default value, e.g. 100 or maybe 200ms) time. Of course, we
> can't make it as simple as just wxBusyCursor or wxBusyInfo as it would have
> to be updated during the long operation, but for both UponPasteCensus() and
> DoCopyCensus() it's not really a problem, as they both contain loops and it
> would be easy to add a call to some update_busy_indicator() function to
> them.
I agree.

First, let me explain why I committed this change. I was testing some new
copy-paste code with a large census, and noticed two problems:

 (1) These operations can take so long that a user might think lmi has
     frozen and needs to be terminated.

 (2) It was possible to issue other commands (e.g., Census | Add cell) while
     these operations were underway.

Experimentally, I instantiated each of these three classes:
  wxBusyCursor
  wxWindowDisabler
  wxWindowUpdateLocker
at the beginning of the copy and paste member functions, and a quick test
suggested that I had prevented (2). But this seemed like overkill, so I
chose not to commit it without asking your advice; instead, I just added a
wxBusyCursor instance to each. To my surprise, that seemed to prevent (2),
although I thought it couldn't. OTOH, if (2) is prevented only by tight
loops that prevent events from being processed, I don't understand how I
was ever able to provoke (2) in the first place; I just didn't have enough
time to investigate that carefully.

Anyway, the normal code freeze date for the impending release was Saturday,
and I wanted to show my experimental new code to Kim right away, so I
committed it with just wxBusyCursor, right after designating commit 3995b4ea
as a release candidate. And it turns out that we'll release that candidate
as is, because we aren't yet satisfied with the experimental new code.

Now that the release pressure is gone, let's consider what to do about
commands that may take a while to execute. At least until we rewrite lmi to
use threading, it seems pretty important to prevent a new command from being
issued while an old one is still executing; is that what wxWindowDisabler is
for? And it's a good idea to give some visual indication that the program is
doing something: ideally, by showing a progress dialog or a running count on
the statusbar, but probably also by displaying a busy cursor. Ideally, though,
the cursor would wait some fraction of a second before changing, because
pasting two cells into an "empty" census takes so little time that changing
the cursor is just annoying.

Can all this be done with a single class, which we might then instantiate at
the beginning of every event handler? I'm not sure it's possible to make a
class as simple as wxBusyCursor do that: it can't know when the threshold
time (100msec, e.g.) has passed unless it either
 - sets a wx timer...but that won't work because a tight loop would prevent
   events from being processed; or
 - creates a timing thread...but if we use multiple threads, this issue no
   longer exists;
so I guess we'd need to call a BusyLocker::Update() function to check a timer
on every iteration, which arguably makes this not worth doing everywhere.

AFAICT, wxWindowUpdateLocker is not applicable here: we'd use it only when
we want to prevent wx from repainting anything.

BTW, when we use the statusbar to show progress thus:
    status() << "Added cell number " << cells.size() << '.' << std::flush;
    wxSafeYield();
I see a "choppy" count: it counts up to 22 in a blur, then stalls for a
decisecond, shows 57, stalls for another few centiseconds, then shows 67;
on another run, the stalls occur at different times, and I see 12, 89, 125
on the statusbar. Shouldn't the wxSafeYield() call ensure a smooth update,
such as I see as a result of this code:
    status() << "Read " << ++counter << " cells." << std::flush;
(which doesn't call wxSafeYield()) elsewhere?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]