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

Re: update events from tight loops?

>I am creating a view item that increments or decrements a number when a
>button is clicked. I would like the button (inc and dec) to behave such
>that a click inc/decs by one, and holding the button continuously inc/decs
>(at some rate).
>I can get the behaviour, but the view does not update. The key part is the
>looping structure below:
>(defmethod view-click-event-handler ((self increment-button) where)
>  (declare (ignore where))
>  (let ((to-view (if (message-view self)
>                   (message-view self)
>                   (view-container self))))
>    (when to-view
>      (increment to-view)
>      (let ((start (rref *current-event* :EventRecord.when)))
>        ;; key bit
>        (loop
>          (unless (mouse-down-p)
>            (return))
>          (when (= (mod (- (#_TickCount) start) 20))
>            (increment to-view)
>            (WHAT GOES HERE????)))))))))
>The WHAT GOES HERE? is where I need something that will cause LISP to allow
>invalidated views to update themselves.

The easiest thing is:

(window-update-event-handler (view-window to-view))

You should NOT call WINDOW-UPDATE-EVENT-HANDLER from anywhere but
something that is called by EVENT-DISPATCH, however. Inside of

Another, slightly more Kosher way of doing this is to define a macro:

(defmacro with-event-processing-enabled (&body body)
  `(let ((ccl::*interrupt-level* 0)
         (ccl::*processing-events* nil))

Then in place of (WHAT GOES HERE????) you can say:


Make sure to do it with the macro or your code will cease to compile
correctly when MCL 2.1 is released. MCL 2.1 will have a different
implementation of WITH-EVENT-PROCESSING-ENABLED that will be
functionally equivalent.

Since you know which view needs to be redrawn, a third way to do
your updating is to do the drawing yourself:

(view-focus-and-draw-contents to-view)