Lisp HUG Maillist Archive

capi:apply-in-pane-process

Hello all,

I'm doing some work with OpenGL and Lispworks (on OS X).  I have a slot in my
opengl-pane called redraw-p  which is non-nil when the pane needs to be redrawn.
I've written a function, post-redisplay, which does the following:

(defun post-redisplay (pane rect)  ;; rect is the region to be redrawn.
  "Redisplays the pane, but only if the request has not already been made."
  (with-slots (redraw-p redraw-rect) pane
    (if redraw-p
      (setf redraw-rect (rectangle-union redraw-rect rect))  ;;
include rect in the area to be redrawn
      (progn
        (setf redraw-p    t
              redraw-rect  rect)
        (capi:apply-in-pane-process pane #'redraw-pane pane)))))

The idea, here, is that if I made two calls to post-redisplay before
the redraw-pane function was called, then rather than redrawing two
regions consecutively, I could combine the two regions into one and
draw them both at the same time.

The problem that I've run into, is that I had (perhaps incorrectly)
assumed that a call to capi:apply-in-pane-process would put the
draw-object call into some sort of queue of actions to perform so that
the following *could* have the desired behavior of not making
consecutive calls to redraw-pane

(progn
  (post-redisplay p 10 50 10 10)
  (post-redisplay p 100 100 10 10))

It seems, however, that appy-in-pane-process when called from the same
process that it will be applied into has the effect of executing
immediately.  Is this the correct behaviour?  And if so, might you
have any suggestions for achieving the desired results (without
creating a new process to watch for the redraw-p slot to change)

Thanks!
Andrew


Re: capi:apply-in-pane-process

On Jul 25, 2006, at 2:55 PM, Andrew Shilliday wrote:

>
> Hello all,
>
> I'm doing some work with OpenGL and Lispworks (on OS X).  I have a  
> slot in my
> opengl-pane called redraw-p  which is non-nil when the pane needs  
> to be redrawn.
> I've written a function, post-redisplay, which does the following:
>
> (defun post-redisplay (pane rect)  ;; rect is the region to be  
> redrawn.
>  "Redisplays the pane, but only if the request has not already been  
> made."
>  (with-slots (redraw-p redraw-rect) pane
>    (if redraw-p
>      (setf redraw-rect (rectangle-union redraw-rect rect))  ;;
> include rect in the area to be redrawn
>      (progn
>        (setf redraw-p    t
>              redraw-rect  rect)
>        (capi:apply-in-pane-process pane #'redraw-pane pane)))))
>
> The idea, here, is that if I made two calls to post-redisplay before
> the redraw-pane function was called, then rather than redrawing two
> regions consecutively, I could combine the two regions into one and
> draw them both at the same time.
>
> The problem that I've run into, is that I had (perhaps incorrectly)
> assumed that a call to capi:apply-in-pane-process would put the
> draw-object call into some sort of queue of actions to perform so that
> the following *could* have the desired behavior of not making
> consecutive calls to redraw-pane
>
> (progn
>  (post-redisplay p 10 50 10 10)
>  (post-redisplay p 100 100 10 10))
>
> It seems, however, that appy-in-pane-process when called from the same
> process that it will be applied into has the effect of executing
> immediately.  Is this the correct behaviour?  And if so, might you
> have any suggestions for achieving the desired results (without
> creating a new process to watch for the redraw-p slot to change)

That's the intended effect.

In InspireData, we used the following function to always ensure that  
operations are queued:

   ;;; Invokes FUNCTION on ARGS in the process of INTERFACE like  
CAPI:EXECUTE-WITH-INTERFACE
   ;;; but always queues the execution request.  Consequently, if  
this is called from code
   ;;; which is already running in INTERFACE's process, the execution  
of FUNCTION will be
   ;;; deferred until the interface is idle.

   (defun execute-with-interface-when-idle (interface function &rest  
args)
     (let ((process (capi-internals:interface-process interface)))
       (if process
         (mp:process-send process (list (invoke-with-tabletop- 
toplevel-error-handlers ()
                                          (apply function args))))
         (apply function args))))

   - Gary Palter
     Principal Software Engineer
     Clozure Associates
     Cell:  617-947-0536


Re: capi:apply-in-pane-process

Thanks, the use of mp:send-message was exactly what I was looking for.
 I would have thought I would get the same behavior with
apply-in-pane-process, but I suppose I don't understand the inner
workings of that function.

Again, thanks
Andrew

On 7/25/06, Gary Palter <palter@clozure.com> wrote:
> On Jul 25, 2006, at 2:55 PM, Andrew Shilliday wrote:
>
> >
> > Hello all,
> >
> > I'm doing some work with OpenGL and Lispworks (on OS X).  I have a
> > slot in my
> > opengl-pane called redraw-p  which is non-nil when the pane needs
> > to be redrawn.
> > I've written a function, post-redisplay, which does the following:
> >
> > (defun post-redisplay (pane rect)  ;; rect is the region to be
> > redrawn.
> >  "Redisplays the pane, but only if the request has not already been
> > made."
> >  (with-slots (redraw-p redraw-rect) pane
> >    (if redraw-p
> >      (setf redraw-rect (rectangle-union redraw-rect rect))  ;;
> > include rect in the area to be redrawn
> >      (progn
> >        (setf redraw-p    t
> >              redraw-rect  rect)
> >        (capi:apply-in-pane-process pane #'redraw-pane pane)))))
> >
> > The idea, here, is that if I made two calls to post-redisplay before
> > the redraw-pane function was called, then rather than redrawing two
> > regions consecutively, I could combine the two regions into one and
> > draw them both at the same time.
> >
> > The problem that I've run into, is that I had (perhaps incorrectly)
> > assumed that a call to capi:apply-in-pane-process would put the
> > draw-object call into some sort of queue of actions to perform so that
> > the following *could* have the desired behavior of not making
> > consecutive calls to redraw-pane
> >
> > (progn
> >  (post-redisplay p 10 50 10 10)
> >  (post-redisplay p 100 100 10 10))
> >
> > It seems, however, that appy-in-pane-process when called from the same
> > process that it will be applied into has the effect of executing
> > immediately.  Is this the correct behaviour?  And if so, might you
> > have any suggestions for achieving the desired results (without
> > creating a new process to watch for the redraw-p slot to change)
>
> That's the intended effect.
>
> In InspireData, we used the following function to always ensure that
> operations are queued:
>
>    ;;; Invokes FUNCTION on ARGS in the process of INTERFACE like
> CAPI:EXECUTE-WITH-INTERFACE
>    ;;; but always queues the execution request.  Consequently, if
> this is called from code
>    ;;; which is already running in INTERFACE's process, the execution
> of FUNCTION will be
>    ;;; deferred until the interface is idle.
>
>    (defun execute-with-interface-when-idle (interface function &rest
> args)
>      (let ((process (capi-internals:interface-process interface)))
>        (if process
>          (mp:process-send process (list (invoke-with-tabletop-
> toplevel-error-handlers ()
>                                           (apply function args))))
>          (apply function args))))
>
>    - Gary Palter
>      Principal Software Engineer
>      Clozure Associates
>      Cell:  617-947-0536
>
>


Updated at: 2020-12-10 08:48 UTC