From: David Trudgett
Subject: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <m3fyoz19w2.fsf@rr.trudgett>
I have written a little line drawing demo program with an event loop
which waits for a mouse click or key press and then closes the window
and X connection. The event loop also redraws the graphics after
(event count zero) exposure events.

When I use the mouse to grab the bottom right window corner, and move
the mouse around the screen to continuously resize the window and
generate lots of exposure events, CPU usage goes to max and stays
there for many seconds after I finish twiddling the window. If I click
the mouse to close the window, it doesn't close until the CPU usage
falls off.

Now, what I believe must be happening (although I would have expected
to see screen flicker) is that hundreds of exposure events are being
generated and the CPU usage is caused by the continual redrawing of
the display. But it only takes an instant to render once, and there is
no screen flicker after I stop moving the window about. That's a bit
puzzling, and so I was wondering if it's actually the mechanics of
sending/receiving/processing/discarding events that is taking up most
of the processing time. I suspect it is, but it's a secondary issue
and I don't really want to get into profiling at this stage.

The primary question I have is about a strategy to deal with this
situation. For example, perhaps one might only process one exposure
event per second (and discarding all the others). Does anyone have any
tips for this?  Sample code? :-)

If you want to see what I'm talking about, you will find the main bits
of my code below. If you want to run it and see, the full code can be
found at: 

http://www.zeta.org.au/~wpower/dkt/programs/graphics.lisp


Here are the main bits:



(defmacro with-drawing-window (&body body)
  (flet ((do-stuff () `(progn ,@body (display-finish-output *display*))))
    `(unwind-protect 
	 (progn
	   (show-drawing-window)
	   (event-case
	    (*display* :force-output-p t :discard-p t)
	    (:button-press ()
			   t)
	    (:key-press ()
			t)
	    (:exposure ()
		       ,(do-stuff)
		       nil)))
       (close-display *display*)
       (setf *drawing-window* nil)
       (setf *graphics-context* nil)
       (setf *display* nil)
       (setf *screen* nil))))



(defun create-drawing-window () 
  (unless (null *drawing-window*)
    (destroy-window *drawing-window*))
  (when (null *display*)
    (setf *display* (open-display ""))
    (setf *screen* (first (display-roots *display*))))
  (let ((bg-colour (screen-black-pixel *screen*)) 
	(fg-colour (screen-white-pixel *screen*)))
    (setf *drawing-window* 
	(create-window :parent (screen-root *screen*) 
		       :class :input-output 
		       :x 0              ;temporary value 
		       :y 0              ;temporary value 
		       :width 640        ;temporary value 
		       :height 480       ;temporary value 
		       :border-width 2 
		       :border fg-colour 
		       :background bg-colour 
		       :save-under :on 
		       :event-mask (make-event-mask :button-press
						    :key-press
						    :exposure)))
    (set-window-title *drawing-window* "CG Drawing Window")
    (create-graphics-context bg-colour 
			     (alloc-color 
			      (window-colormap (screen-root *screen*))
			      'yellow))))



(defun draw-pixel-line-1 (p1 p2)
  (let* ((x1 (first p1))
	 (y1 (second p1))
	 (x2 (first p2))
	 (y2 (second p2))
	 (steps (- x2 x1))
	 (slope (/ (- y2 y1) steps)))
    (do ((i 1 (1+ i)) 
	 (x x1 (1+ x)) 
	 (y y1 (+ y1 (round (* i slope)))))
	((> i steps))
      (draw-point *drawing-window* *graphics-context* x y))
    (draw-point *drawing-window* *graphics-context* x2 y2)))



(defun pixel-line-1 () 
  (with-drawing-window
   (draw-glyphs *drawing-window* 
		*graphics-context* 
		50 50 
		"PIXEL-LINE-1")
   (draw-glyphs *drawing-window* 
		*graphics-context* 
		50 250 
		"XLIB:DRAW-LINE")
   (do ((x-inc 50)
	(x 150 (+ x x-inc))
	(y1 200 (- y1 10))
	(y2 400 (- y2 10)))
       ((< y1 50))
     (draw-pixel-line-1 '(100 100) (list x y1))
     (draw-line *drawing-window* *graphics-context* 100 300 x y2)
     (when (>= x 590)
       (setq x-inc (- x-inc))))))


Cheers,

David


-- 

David Trudgett
http://www.zeta.org.au/~wpower/

But how can men be united in the truth or even approximate to it, if
they do not even express the truth they know, but hold that there is
no need to do so, and pretend to regard as truth what they believe to
be false?

    -- Leo Tolstoy, "The Kingdom of God is Within You"

From: Ulrich Hobelmann
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <403rrjF15t6h5U1@individual.net>
David Trudgett wrote:
> The primary question I have is about a strategy to deal with this
> situation. For example, perhaps one might only process one exposure
> event per second (and discarding all the others). Does anyone have any
> tips for this?  Sample code? :-)

Hm, it's been a while since I did any X window.  Wasn't there an event 
count associated with each sort of event.  I remember reading something 
about that if some count > 0, you simply discard the event, so that you 
only redraw after the last resize/expose/... was received.

-- 
If you have to ask what jazz is, you'll never know.
	Louis Armstrong
From: David Trudgett
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <m3acf7hwll.fsf@rr.trudgett>
Hi Ulrich,

I tried your suggestion, but its behaviour is still the same. See
below.


Ulrich Hobelmann <···········@web.de> writes:

> David Trudgett wrote:
>> The primary question I have is about a strategy to deal with this
>> situation. For example, perhaps one might only process one exposure
>> event per second (and discarding all the others). Does anyone have any
>> tips for this?  Sample code? :-)
>
> Hm, it's been a while since I did any X window.  Wasn't there an event
> count associated with each sort of event.  I remember reading
> something about that if some count > 0, you simply discard the event,
> so that you only redraw after the last resize/expose/... was received.

I thought I was doing that, but I looked at the code and realised I
must have accidentally deleted it somewhere along the line. In any
case, I put it back in, but the behaviour is just the same. I assume
it must be generating lots of exposure events with count equal to
zero.

Anyway, here is the corrected bit:

(defmacro with-drawing-window (&body body)
  (flet ((do-stuff () `(progn ,@body (display-finish-output *display*))))
    `(unwind-protect 
	 (progn
	   (show-drawing-window)
	   (event-case
	    (*display* :force-output-p t :discard-p t)
	    (:button-press ()
			   t)
	    (:key-press ()
			t)
	    (:exposure (count)
		       (when (zerop count)
			 ,(do-stuff))
		       nil)))
       (close-display *display*)
       (setf *drawing-window* nil)
       (setf *graphics-context* nil)
       (setf *display* nil)
       (setf *screen* nil))))


and a sample expansion:

(UNWIND-PROTECT
    (PROGN
     (SHOW-DRAWING-WINDOW)
     (EVENT-CASE (*DISPLAY* :FORCE-OUTPUT-P T :DISCARD-P T)
                 (:BUTTON-PRESS NIL T)
                 (:KEY-PRESS NIL T)
                 (:EXPOSURE (COUNT)
                  (WHEN (ZEROP COUNT)
                    (PROGN
                     (DRAW-GLYPHS *DRAWING-WINDOW*
                                  *GRAPHICS-CONTEXT*
                                  50
                                  50
                                  "DRAW-PIXEL-LINE-1")
                     (DRAW-GLYPHS *DRAWING-WINDOW*
                                  *GRAPHICS-CONTEXT*
                                  50
                                  250
                                  "XLIB:DRAW-LINE")
                     (DO ((X-INC 50)
                          (X 150 (+ X X-INC))
                          (Y1 200 (- Y1 10))
                          (Y2 400 (- Y2 10)))
                         ((< Y1 50))
                       (DRAW-PIXEL-LINE-1 '(100 100) (LIST X Y1))
                       (DRAW-LINE *DRAWING-WINDOW*
                                  *GRAPHICS-CONTEXT*
                                  100
                                  300
                                  X
                                  Y2)
                       (WHEN (>= X 590) (SETQ X-INC (- X-INC))))
                     (DISPLAY-FINISH-OUTPUT *DISPLAY*)))
                  NIL)))
  (CLOSE-DISPLAY *DISPLAY*)
  (SETF *DRAWING-WINDOW* NIL)
  (SETF *GRAPHICS-CONTEXT* NIL)
  (SETF *DISPLAY* NIL)
  (SETF *SCREEN* NIL))


Thanks anyway, you managed to catch an omission I wasn't aware of.

David




-- 

David Trudgett
http://www.zeta.org.au/~wpower/

Beware of bugs in the above code; 
I have only proved it correct, not tried it.
  
    -- Donald Knuth (1977)
From: Ulrich Hobelmann
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <404uk7F1866pqU1@individual.net>
David Trudgett wrote:
>> Hm, it's been a while since I did any X window.  Wasn't there an event
>> count associated with each sort of event.  I remember reading
>> something about that if some count > 0, you simply discard the event,
>> so that you only redraw after the last resize/expose/... was received.
> 
> I thought I was doing that, but I looked at the code and realised I
> must have accidentally deleted it somewhere along the line. In any
> case, I put it back in, but the behaviour is just the same. I assume
> it must be generating lots of exposure events with count equal to
> zero.

Hm, maybe you should stick a FORMAT or a counter somewhere in there, or 
something that measures the time between subsequent events of a kind.

I just looked through the Xlib code I wrote (in C), and noticed that you 
don't have any ConfigureNotify-events in there.  They are the ones that 
contain resizing information about your window.

(from Xlib.h)
typedef struct {
         int type;
         unsigned long serial;   /* # of last request processed by server */
         Bool send_event;        /* true if this came from a SendEvent 
request */
         Display *display;       /* Display the event was read from */
         Window event;
         Window window;
         int x, y;
         int width, height;
         int border_width;
         Window above;
         Bool override_redirect;
} XConfigureEvent;

I only used width and height for a simple example, but window might be 
interesting too if you have more than one.  Unfortunately I'm not 
exactly familiar with CLX, so I can't tell what exactly is going on in 
your code.

I'm not sure what modern window-managers do; if they really send lots of 
expose-events, or mostly configure-notifies.  In any case it shouldn't 
be *that* many.

> Anyway, here is the corrected bit:
> 
> (defmacro with-drawing-window (&body body)
>   (flet ((do-stuff () `(progn ,@body (display-finish-output *display*))))
>     `(unwind-protect 
> 	 (progn
> 	   (show-drawing-window)
> 	   (event-case
> 	    (*display* :force-output-p t :discard-p t)

What do force-output-p and discard-p do?  Maybe this is some kind of 
Sync option that slows down the server connection?

>                        (DRAW-LINE *DRAWING-WINDOW*
>                                   *GRAPHICS-CONTEXT*
>                                   100
>                                   300
>                                   X
>                                   Y2)
>                        (WHEN (>= X 590) (SETQ X-INC (- X-INC))))

>                      (DISPLAY-FINISH-OUTPUT *DISPLAY*)))

XSync()?

At least in the C version, all the X-commands you do are placed in a 
buffer, and only XNextEvent() flushes the buffer to the server, goes 
fetch new events, and gives you the first one.  Subsequent XNextEvents 
probably don't even make new round-trips (at least when you don't create 
new commands for the server; and probably your resize-handlers, and the 
expose-handler with count > 0 won't do that), but just fetch the next 
event in the client's buffer.

(so in C you almost never need to call anything like XSync().  Not sure 
what your DISPLAY-FINISH-OUTPUT does.)

Not sure what takes so long here...

-- 
If you have to ask what jazz is, you'll never know.
	Louis Armstrong
From: David Trudgett
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <m38xuqdom1.fsf@rr.trudgett>
Ulrich Hobelmann <···········@web.de> writes:

> David Trudgett wrote:
>>> Hm, it's been a while since I did any X window.  Wasn't there an event
>>> count associated with each sort of event.  I remember reading
>>> something about that if some count > 0, you simply discard the event,
>>> so that you only redraw after the last resize/expose/... was received.
>> I thought I was doing that, but I looked at the code and realised I
>> must have accidentally deleted it somewhere along the line. In any
>> case, I put it back in, but the behaviour is just the same. I assume
>> it must be generating lots of exposure events with count equal to
>> zero.
>
> Hm, maybe you should stick a FORMAT or a counter somewhere in there,
> or something that measures the time between subsequent events of a
> kind.

Well, I put a format in to see what was happening regarding numbers of
exposure events, and it confirms what I suspected:

(defmacro with-drawing-window (&body body)
  `(unwind-protect
       (let ((exposures 0)
	     (redraws 0))
       (progn
	 (show-drawing-window)
	 (event-case
	  (*display* :force-output-p t :discard-p t)
	  (:button-press ()
			 t)
	  (:key-press ()
		      t)
	  (:exposure (count)
		     (incf exposures)
		     (when (zerop count)
		       (incf redraws)
		       ,@body)
		     nil)))
       (format t "~&Exposures: ~D~%Redraws: ~D" exposures redraws))
     (close-display *display*)
     (setf *drawing-window* nil)
     (setf *graphics-context* nil)
     (setf *display* nil)
     (setf *screen* nil)))

Output:

    Exposures: 5047
    Redraws: 1568

after a few seconds of resizing the window. 

Far too many redraws. Taking the ,@body out removes the problem, so it
would appear that the CPU usage is caused by the continual redrawing,
even though the image doesn't flicker as I thought it might. So I need
to come up with a way to reduce the number of redraws. I suppose I
will have to either time or extract time info from the events and base
a redraw decision on that.



>
> I just looked through the Xlib code I wrote (in C), and noticed that
> you don't have any ConfigureNotify-events in there.  They are the ones
> that contain resizing information about your window.

I haven't had time to look into that yet. But I don't think that's it
because of the above.


>
> I only used width and height for a simple example, but window might be
> interesting too if you have more than one.  Unfortunately I'm not
> exactly familiar with CLX, so I can't tell what exactly is going on in
> your code.

No problem, but I do appreciate your suggestions.


>
> I'm not sure what modern window-managers do; if they really send lots
> of expose-events, or mostly configure-notifies.  In any case it
> shouldn't be *that* many.

Oh, well, a few thousand exposure events in my case, but I was
deliberately stress testing it. Under normal use you wouldn't get that
many. As far as configure-notifies are concerned, I won't get those in
this particular program, because the window was created with an event
mask of (:BUTTON-PRESS :KEY-PRESS :EXPOSURE).



>
>> Anyway, here is the corrected bit:
>> (defmacro with-drawing-window (&body body)
>>   (flet ((do-stuff () `(progn ,@body (display-finish-output *display*))))
>>     `(unwind-protect 	 (progn
>> 	   (show-drawing-window)
>> 	   (event-case
>> 	    (*display* :force-output-p t :discard-p t)
>
> What do force-output-p and discard-p do?  Maybe this is some kind of
> Sync option that slows down the server connection?

Well, it doesn't seem to work without the :FORCE-OUTPUT-P, which does
something analogous to DISPLAY-FINISH-OUTPUT (XSync?), i.e., keeps
response snappy by ensuring the command queue is regularly flushed.

:DISCARD-P is also necessary in order to remove "unprocessed events"
from the queue, where "unprocessed" means those that I return NIL for
in the EVENT-CASE loop (returning T terminates the loop).



>
>>                        (DRAW-LINE *DRAWING-WINDOW*
>>                                   *GRAPHICS-CONTEXT*
>>                                   100
>>                                   300
>>                                   X
>>                                   Y2)
>>                        (WHEN (>= X 590) (SETQ X-INC (- X-INC))))
>
>>                      (DISPLAY-FINISH-OUTPUT *DISPLAY*)))
>
> XSync()?

Probably... has the right ring to it ;-) (I haven't used xlib in C) It
flushes command output to the display. It's not usually needed, but
sometimes it is, and it is (apparently) easy to get caught trying to
debug something when the only problem is that the queue hasn't been
flushed as expected and therefore the screen hasn't been updated.


>
> At least in the C version, all the X-commands you do are placed in a
> buffer, and only XNextEvent() 

CLX seems to shield one from having to call XNextEvent().



> flushes the buffer to the server, goes fetch new events, and gives
> you the first one.  Subsequent XNextEvents probably don't even make
> new round-trips (at least when you don't create new commands for the
> server; and probably your resize-handlers, and the expose-handler
> with count > 0 won't do that), but just fetch the next event in the
> client's buffer.
>
> (so in C you almost never need to call anything like XSync().  Not
> sure what your DISPLAY-FINISH-OUTPUT does.)

Same with DISPLAY-FINISH-OUTPUT, you almost never need to call it. But
occasionally you'll get caught out... ;-)


>
> Not sure what takes so long here...

Seems to be hundreds of redraws.



>
> -- 
> If you have to ask what jazz is, you'll never know.
> 	Louis Armstrong

You into Jazz? 



Cheers,

David


-- 

David Trudgett
http://www.zeta.org.au/~wpower/

Fearlessness is the first requisite of spirituality. Cowards can never
be moral.

    -- Mohandas Gandhi
From: Ulrich Hobelmann
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <406gmhF190i16U1@individual.net>
David Trudgett wrote:
>> If you have to ask what jazz is, you'll never know.
>> 	Louis Armstrong
> 
> You into Jazz? 

I like almost every kind of music, except some techno, most rap, and 
folk music of most nationalities.  Jazz is great, but in Germany it 
seems to be rare for some reason.  Maybe it's strictly American, just 
like Chanson is strictly French.

-- 
If you have to ask what jazz is, you'll never know.
	Louis Armstrong
From: Edi Weitz
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <u1x0hhmew.fsf@agharta.de>
On Tue, 13 Dec 2005 00:50:40 +0100, Ulrich Hobelmann <···········@web.de> wrote:

> Jazz is great, but in Germany it seems to be rare for some reason.

That's complete nonsense.

Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Ulrich Hobelmann
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <4076gbF18o1vjU1@individual.net>
Edi Weitz wrote:
> On Tue, 13 Dec 2005 00:50:40 +0100, Ulrich Hobelmann <···········@web.de> wrote:
> 
>> Jazz is great, but in Germany it seems to be rare for some reason.
> 
> That's complete nonsense.

Maybe you're lucky and know the right persons.  My impression in the USA 
was that Jazz is much more part of regular culture than it is here. 
They play lots of jazz at college, where Germany has mostly just 
classical music; I was actually surprised.

Of course that's just the parts of the world I've experienced.  YMMV.

-- 
If you have to ask what jazz is, you'll never know.
	Louis Armstrong
From: Alan Crowe
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <86k6e8nam6.fsf@cawtech.freeserve.co.uk>
David Trudgett <······@zeta.org.au.nospamplease> writes:
> Output:
> 
>     Exposures: 5047
>     Redraws: 1568

That looks like trouble. It makes me think of 12-127 in
the CLX Programmer's Reference

motion-events ...

    Many X server implementations maintain a more precise
    history of pointer motion between event
    notifications. The pointer position at each pointer
    hardware interrupt can be stored into a buffer for later
    retrieval. This is called the motion history buffer. A
    paint program for example may want to have a precise
    history of where the pointer traveled, even though for
    most other applications this amount of detail is grossly
    excessive.

Sounds as though you are getting all the motion events
I don't know what to do about this.

> Well, it doesn't seem to work without the :FORCE-OUTPUT-P, which does
> something analogous to DISPLAY-FINISH-OUTPUT (XSync?), i.e., keeps
> response snappy by ensuring the command queue is regularly flushed.
> 

There are two "flush the buffer" commands
see page 2-29

display-force-output - forces any buffered output to be sent
                       to the X server

display-finish-output - Forces buffered output and waits
                        until all requests have been
                        received and processed. Any errors
                        ...

So force is the one you mustn't forget about, least you ask
"why hasn't my drawing appeared?" when it is sitting in the
output queue waiting to be sent to the X server.

finish might be handy for debugging, to make sure that your
program waits to see if its requests generate errors, but it
makes everything a round trip, and I would expect it to slow
your program down.

By the way, alan.crowe.name is down.
My small attempt at a CLX tutorial is at

http://www.cawtech.freeserve.co.uk/clx/simple/

in the html file. I've broken all the links to the source
code moving it, and will not be fixing this until my health
picks up again.

Checking, I notice that I've used display-finish-output, when
display-force-output is all that is needed. Hmm. I've
changed the wording around display-finish-output.

Please say what you think of the new wording.

Alan Crowe
Edinburgh
Scotland
From: David Trudgett
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <m3pso091l2.fsf@rr.trudgett>
Hi Alan,

Hope you get well soon. Not frost-bitten feet, I hope ;-)

Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> David Trudgett <······@zeta.org.au.nospamplease> writes:
>> Output:
>> 
>>     Exposures: 5047
>>     Redraws: 1568
>
> That looks like trouble. It makes me think of 12-127 in
> the CLX Programmer's Reference
>
> motion-events ...
>
>     Many X server implementations maintain a more precise
>     history of pointer motion between event
>     notifications. The pointer position at each pointer
>     hardware interrupt can be stored into a buffer for later
>     retrieval. This is called the motion history buffer. A
>     paint program for example may want to have a precise
>     history of where the pointer traveled, even though for
>     most other applications this amount of detail is grossly
>     excessive.
>
> Sounds as though you are getting all the motion events
> I don't know what to do about this.

Well, I've modified my code thusly, and it seems to do the trick:

(defmacro with-drawing-window (&body body)
  `(unwind-protect
       (let ((redraw-count 0)
	     (last-redraw-time 0)
	     (itups internal-time-units-per-second))
	 (show-drawing-window)
	 (event-case
	  (*display* :force-output-p t :discard-p t)
	  (:button-press ()
			 t)
	  (:key-press ()
		      t)
	  (:exposure (count)
		     (when (zerop count)
		       (when (> (- (get-internal-real-time) 
				   last-redraw-time) 
				itups )
			 (setf redraw-count 0))
		       (when (< redraw-count 10)
			 (incf redraw-count)
			 ,@body
			 (setf last-redraw-time 
			       (get-internal-real-time))))
		     nil)))
     (close-display *display*)
     (setf *drawing-window* nil)
     (setf *graphics-context* nil)
     (setf *display* nil)
     (setf *screen* nil)))


If I haven't made a logic error (perish the very thought), the effect
of that should be to limit the number of redraws to ten per second.


>
>> Well, it doesn't seem to work without the :FORCE-OUTPUT-P, which does
>> something analogous to DISPLAY-FINISH-OUTPUT (XSync?), i.e., keeps
>> response snappy by ensuring the command queue is regularly flushed.
>> 
>
> There are two "flush the buffer" commands
> see page 2-29
>
> display-force-output - forces any buffered output to be sent
>                        to the X server
>
> display-finish-output - Forces buffered output and waits
>                         until all requests have been
>                         received and processed. Any errors
>                         ...

OK, thanks for that. I wasn't aware that there were two of the little
beasties out there... :-)


>
> So force is the one you mustn't forget about, least you ask
> "why hasn't my drawing appeared?" when it is sitting in the
> output queue waiting to be sent to the X server.
>
> finish might be handy for debugging, to make sure that your
> program waits to see if its requests generate errors, but it
> makes everything a round trip, and I would expect it to slow
> your program down.

I did notice an increase in speed when I removed it from the loop.


>
> By the way, alan.crowe.name is down.
> My small attempt at a CLX tutorial is at
>
> http://www.cawtech.freeserve.co.uk/clx/simple/
>
> in the html file. I've broken all the links to the source
> code moving it, and will not be fixing this until my health
> picks up again.
>
> Checking, I notice that I've used display-finish-output, when
> display-force-output is all that is needed. Hmm. I've
> changed the wording around display-finish-output.
>
> Please say what you think of the new wording.

OK, I'll have a look at it when I get a chance. Thanks.

David



-- 

David Trudgett
http://www.zeta.org.au/~wpower/

Centralization as a system is inconsistent with nonviolent structure
of society.

    -- Mohandas Gandhi
From: David Trudgett
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <m3lkyo91ar.fsf@rr.trudgett>
David Trudgett <······@zeta.org.au.nospamplease> writes:

> Well, I've modified my code thusly, and it seems to do the trick:
>
> (defmacro with-drawing-window (&body body)
>   `(unwind-protect
>        (let ((redraw-count 0)
> 	     (last-redraw-time 0)
> 	     (itups internal-time-units-per-second))
> 	 (show-drawing-window)
> 	 (event-case
> 	  (*display* :force-output-p t :discard-p t)

... although, I may have a problem with variable capture here. Do I
need to use gensym or something here?

David

-- 

David Trudgett
http://www.zeta.org.au/~wpower/

The individual has a soul, but as the State is a soulless machine, it
can never be weaned from violence to which it owes its very existence.

    -- Mohandas Gandhi
From: David Trudgett
Subject: Re: CLX/CMUCL: Event processing speed
Date: 
Message-ID: <m38xuo8q98.fsf@rr.trudgett>
David Trudgett <······@zeta.org.au.nospamplease> writes:

>> Well, I've modified my code thusly, and it seems to do the trick:

It didn't quite do the trick, so I tweaked it a bit more and added
gensyms while I was at it. So, now I've got:

(defmacro with-drawing-window (&body body)
  (let ((redraw-count (gensym))
	(redraw-interval (gensym))
	(last-redraw-time (gensym)))
    `(unwind-protect
	 (let ((,redraw-count 0)
	       (,redraw-interval (round (/ 
					 internal-time-units-per-second 
					 10)))
	       (,last-redraw-time 0))
	   (declare (type fixnum ,redraw-count))
	   (show-drawing-window)
	   (event-case
	    (*display* :force-output-p t :discard-p t)
	    (:button-press ()
			   t)
	    (:key-press ()
			t)
	    (:exposure (count)
		       (when (zerop count)
			 (when (> (- (get-internal-real-time)
				     ,last-redraw-time)
				  ,redraw-interval)
			   (setf ,redraw-count 0))
			 (when (< ,redraw-count 20)
			   (incf ,redraw-count)
			   ,@body
			   (setf ,last-redraw-time 
				 (get-internal-real-time))))
		       nil)))
       (close-display *display*)
       (setf *drawing-window* nil)
       (setf *graphics-context* nil)
       (setf *display* nil)
       (setf *screen* nil))))


David



-- 

David Trudgett
http://www.zeta.org.au/~wpower/

When I inquired of one of the governors why they made use of this kind
of torture when people had already submitted and soldiers were
stationed in the village, he replied with the important air of a man
who thoroughly understands all the subtleties of statecraft, that if
the peasants were not thoroughly subdued by flogging, they would begin
offering opposition to the decisions of authorities again. When some
of them had been thoroughly tortured, the authority of the state would
be secured forever among them.

    -- Leo Tolstoy, "The Kingdom of God is Within You"