lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Inhibiting wxLog message buffering


From: Vadim Zeitlin
Subject: Re: [lmi] Inhibiting wxLog message buffering
Date: Wed, 8 Apr 2009 19:46:57 +0200

On Wed, 08 Apr 2009 14:19:27 +0000 Greg Chicares <address@hidden> wrote:

GC> I strive to flush wxLog messages immediately, because our users are
GC> unlikely to click "Details" when multiple warnings are presented in
GC> a single messagebox.

 I wonder if using wxLog is a good idea at all then because buffering is
one of the things it intentionally strives hard to do. I.e. why not just
use wxMessageBox directly if you know that you always want to show the
message immediately?

 The only reasons I can think of is that wxLog messages are

(a) suppressible
(b) redirectable

but I'm not sure if either of these reasons is important for LMI.

GC> - Load lmi, using the (greppable) 'One password to rule them all'
GC> - Test | Test floating point environment
GC> 
GC> After clicking through a few messages, this appears:
GC>   Expect a messagebox complaining about '0x007f', and \
GC>   'Resetting floating-point control word.' on statusbar.
GC> Then I'd like the two following messages to be shown in separate
GC> messageboxes:
GC>   The floating-point control word was unexpectedly '0x007f'...
GC> and
GC>   Expect statusbar to be cleared.
GC> However, they're shown together in the same messagebox.

 I haven't tested this yet but I'm almost sure I know why this happens:
wxLogGui::Flush() intentionally suspends logging while showing its own
dialog, see this comment there:

    // avoid showing other log dialogs until we're done with the dialog we're
    // showing right now: nested modal dialogs make for really bad UI!

And in this case timer callback probably happens while the previous dialog
is still shown. So the calls to wxLog::FlushActive() inside it are ignored
because FlushActive() checks the suspend count.

 Interestingly enough, wxLog::Flush() itself does not check it (probably
not intentionally but OTOH there is no need to change it now so it will
probably remain working like this...). So the minimal workaround you can
use is to replace FlushActive() call with this fragment

            wxLog * const log = wxLog::GetActiveTarget();
            if ( log )
                log->Flush();

and it should indeed show the nested dialogs (but I didn't have time to
test this yet so sorry in advance if I missed something).

GC> Is there an elegant way to force each to appear in its own messagebox?

 I think the only elegant way is to just call wxMessageBox() directly,
working around wxLog buffering mechanism will never be very elegant.

 If you do need to use wxLog because of (a) or (b) above (or some (c) which
I missed), the best would probably be to add wxLog::DisableBuffering() and
make it call Flush() after every logged message automatically -- this would
be functionally equivalent to but more certain to keep working in the
future versions than the hack mentioned above.

 Please let me know if you think it's worth adding such feature to wxLog
or if you prefer to just call wxMessageBox directly. A final alternative
I can think of would be to define your own log target and call wxMessageBox
from its DoLog() but, again, I don't really see any point in using wxLog if
you don't use any of its features so why bother?

 Regards,
VZ

reply via email to

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