Updating a CAPI GUI during phases of heavy computation
Unable to parse email body. Email id is 7800
Unable to parse email body. Email id is 7800
Edi Weitz wrote on Mon, 03 Mar 2008 11:24:26 +0100 13:24: | I have an application with a somewhat complicated GUI from which you | can start a heavy computation. What I want is that the intermediate | results of the computation are reported in the main interface while a | little window pops up which shows the overall progress and also | provides a button to stop the computation. The attached code is a | gross simplification of the actual situation, but it should hopefully | be enough to illustrate my problem. |...snip...| In my version of progress-dialog packed within ywidgets and based on Michal Krupka's code, I am running heavy computation in the process of the progress popup window itself. I have basically tested this with the simplest progress function only updating the popup's meter. IIRC, updating the caller window also worked. -- Sincerely, Dmitriy Ivanov lisp.ystok.ru
On Mar 3, 2008, at 4:24 AM, Edi Weitz wrote: > Am I missing a solution that's substantially better? Why do I only > have to wait for the progress window and not for the main window? Why > do (TEST :WAIT T :SEPARATE-THREAD T) and (TEST :WAIT T) behave the > same? > > BTW, all this might be specific to Windows as each top-level interface > has its own thread there. My approach to this is to run the operation in a separate faceless process which calls back to the interface with progress information. The interface switches to a progress display with a cancel button that can be used to kill the computation process. This works for me on both Mac and Windows. John DeSoi, Ph.D.
On Mon, 3 Mar 2008 09:14:21 -0600, John DeSoi <desoi@pgedit.com> wrote: > My approach to this is to run the operation in a separate faceless > process which calls back to the interface with progress information. > The interface switches to a progress display with a cancel button > that can be used to kill the computation process. Yes, that's what I'm also doing in my example code (see the :SEPARATE-THREAD keyword). Except that I don't want to MP:PROCESS-KILL the background process at some random point. That seems too big a hammer for my taste. > This works for me on both Mac and Windows. My impression is that this only works reliably if the background procress isn't able to saturate the CPU (core) for a longer period. Or if there are enough places in the background process where LW releases the "big lock".
In this kind of situation I force the computation to slow down with some calls to process-wait-with-time-out (rather than process-allow-scheduling). This let a chance to the display operations to run. The problem is to find the good delay. Here, with a delay of one millisecond it's run on my intel Mac : (defun test-in-separate-threads () (let* ((update-callback (lambda (iteration text) (mp:process-wait-with-timeout nil 0.001) (update-output-pane text) (update-progress-pane iteration))) (start-function (lambda () (mp:process-run-function "worker" nil (lambda () (work update-callback)))))) (setq *test-interface* (make-instance 'test-interface :button-args `(:callback ,start-function))) (capi:display *test-interface*))) Naturally it's probably not the faster way... Best Denis Le 3/03/08 11:24, « [NOM] » <[ADRESSE]> a écrit : > [Attention: Running this test code might lock up your Lisp image!] > > I have an application with a somewhat complicated GUI from which you > can start a heavy computation. What I want is that the intermediate > results of the computation are reported in the main interface while a > little window pops up which shows the overall progress and also > provides a button to stop the computation. The attached code is a > gross simplification of the actual situation, but it should hopefully > be enough to illustrate my problem. > > My first approach was to just do it in a straightforward way. Update > the GUI whenever there's a reason to update it. That's what you get > if you run (TEST). If you do that, the progress window is updated, > but the "main" window is kind of dead - try to move the progress > window around and you'll note that the main window isn't repainted. > > Not good. So I thought that this happened because the heavy > computation runs in the thread of the main window and prevents it from > taking care of windoing events. The next thing I tried was equivalent > to (TEST :SEPARATE-THREAD T). If I try this, everything locks up, no > progress is reported at all. If you're lucky, you can find the > "worker" process in the Process Browser and kill it. > > Hmmm. I tend to think that this wouldn't happen (see previous > discussions), if we had real SMP. Anyway, I tried a third solution. > That'd be (TEST :WAIT T). In this case, the computation thread > actually waits until the progress window has been updated. This > doesn't seem like an ideal solution to me as it kind of serializes the > events and takes all the fun out of multi-threading, but at least it > works. More or less, that is, as the whole computation now has to > halt when you move the progress window around and only continues once > you stop moving it... :( > > Am I missing a solution that's substantially better? Why do I only > have to wait for the progress window and not for the main window? Why > do (TEST :WAIT T :SEPARATE-THREAD T) and (TEST :WAIT T) behave the > same? > > BTW, all this might be specific to Windows as each top-level interface > has its own thread there. > ------------------------------------------------------- Denis Pousseur 70 rue de Wansijn 1180 Bruxelles, Belgique Tel : 32 (0)2 219 31 09 Mail : denis.pousseur@gmail.com -------------------------------------------------------
Is there a ready-made way to unit test the windowed output of functions (for Windows)? I have scanned the unit test libraries here (http://www.cl-user.net/asp/BK9t6/sdataQIrH-xEyOeShDQjr-br2cQTk8yBX8yBX8oQ5Ss9v-ujg$Np5/sdataQu3F$sSHnB==) and have started using lisp-unit, but that doesn't have anything along those lines. Mitch Berkson
Mitch Berkson <mitch@bermita.com> writes: > Is there a ready-made way to unit test the windowed output of > functions (for Windows)? As the earlier poster said, if you want to do automated testing of a GUI you'll need some sort of record and replay software. As far as I know there is no good software where you can write gui tests in Common Lisp as you would for "normal" unit tests. I've used http://en.wikipedia.org/wiki/HP_QuickTest_Professional in a previous project for this purpose. That was a web-based app in Scheme (about 75k loc if I remember right), but it's the same idea for any gui. Cheers, Chris Dean P.S. If you ever switch to a web-based app, there are now some JavaScript based testing frameworks available.