All Manuals > CAPI User Guide > 8 Modifying CAPI Windows > 8.6 Updating pane contents

NextPrevUpTopContentsIndex

8.6.1 Updating windows in real time

If your code needs to cause visible updates whilst continuing to do further computation, then you should run your computation in a separate thread which is not directly associated with the CAPI window.

Consider the following example where real work is represented by calls to sleep :

  1. Evaluate this code:
  2. (defun change-text (win text)
      (setf (title-pane-text win)
            text))
     
    (defun my-callback (win)
      (change-text win "Go")
      (loop
       for i from 0 to 20 do 
       (change-text win (format nil "~D" i))
       (sleep 0.1)))
     
    (defun test ()
      (let* ((p1 (make-instance 'title-pane
                                :text "init"))
             (p2 (make-instance
                  'button :text "Go"
                  :callback-type :none
                  :callback #'(lambda ()
                                (my-callback p1)))))
        (contain
         (make-instance 'row-layout :description (list p1 nil p2))
         :width 200 :height 200)))
  3. Run (test) and note that the updates do not appear until my-callback returns. This is because it uses only one thread.
  4. Now try this modified callback which uses a worker thread to perform the calculations:
  5. (defun my-work-function ()
      (let ((mbox (mp:ensure-process-mailbox)))
        ;; This should really have an error handler.
        (loop (let ((event (mp:process-read-event mbox
                            "Waiting for events")))
                (cond ((consp event)
                       (apply (car event) (cdr event)))
                      ((functionp event)
                       (funcall event)))))))
     
    (setf *worker*
          (mp:process-run-function "Worker process" ()
                                   'my-work-function))
     
    (defun change-text (win text)
      (apply-in-pane-process win
                             #'(setf title-pane-text)
                             text win))
     
    (defun my-callback (win)
      (mp:process-send
       *worker*
       #'(lambda ()
           (change-text win "Go")
           (loop
            for i from 0 to 20 do 
            (change-text win (format nil "~D" i))
            (sleep 0.1)))))
  6. Run (test) again: you should see the updates appear immediately.

A real application might also display an Abort button during the computation, with a callback that aborts the worker process.


CAPI User Guide (Macintosh version) - 30 Aug 2011

NextPrevUpTopContentsIndex