Lisp HUG Maillist Archive

Process to refresh OpenGL panes

Hello people, i'm in need to share my problem:

I need to know how can i do, to write a simple function which updates a list of
OpenGL interfaces (placed in a global variable for example). These interfaces
take some time to be updated, so i thought it was a good idea to use a
background process to do this. I want this process in very low priority so i can
continue using the environment without problems. I readed some message which
recommended the function '#mp:process-send; i mean, make and queue a function
that when dequeued and executed refreshes every interface and enqueues it again
(to be processed again when possible without molesting interface usage). 

When i do this and i try to focus on main mdi interface of my application (which
contains an OpenGL interface children) the interface get freezed. This is the
code i tryed (and a lot more, but i think this should work). 

(defun execute-with-interface-when-idle (interface function &rest args)
  (let ((process (capi-internals:interface-process interface)))
    (if process
        (mp:process-send process (list function))
      (funcall function)))) 

(defun initialize-automatic-refresh ()
  (execute-with-interface-when-idle
   (interface *main-interface*)
   (lambda ()
     (dolist (i *graphical-interfaces*)
       (redisplay-canvas (graphic-part i)))
     (initialize-automatic-refresh)))) 

(initialize-automatic-refresh) 

I'm using LispWorks 5.1, i think this should work in this version; but maybe in
version 6.0 there is another way. 

Really dunno what to do, tried to use a timer, a infinite loop and many other
variants but the main MDI interface always get freezed. This is not an OpenGL
problem. I'd be happy to have such function working, doing something like
refreshing a CAPI interface as an animation or executing some heavy calculation
on background, when interface is idled.

Please tell me if it´s not clear, my english suxx sometimes. 

Recapitulation: What i need is a way to write a process that executes things
(like refreshing the UI) when interface is idled.. without bothering interface
usage. Just that.

Regards,
Sebastián



Re: Process to refresh OpenGL panes

Unable to parse email body. Email id is 11215

Re: Process to refresh OpenGL panes


* Paul Tarvydas <201108291708.17332.paul.tarvydas@rogers.com> :
Wrote on Mon, 29 Aug 2011 17:08:17 -0400:

|
| Every time a user types a character, (regenerate) is called.  This
| just sends a message to the updater process.
|
| The updater blocks on mp:mailbox-read until a message comes in.  Then,
| it regenerates the most-recent PDF image and displays it.  If, in the
| meantime, more regenerate messages pile up in the queue (i.e. the user
| types characters quickly), the updater simply goes into a loop to
| clear the queue (i.e. dumps the piled up messages) and then blocks
| again waiting for a mp:mailbox-read.

Does this work as expected?  If the `regenerate' events were generated
for a different interface, it would seem that dropping them would be
wrong, (I imagine it would be tough for a user to generate them
though...)


[GUI amateur here.  Recently I was trying to deal with duplicate events,
and a flood of events where the capi interfaces were only interested in
the last event.

In these cases it felt like I was working against the CAPI callback
model: I found myself wanting to maintain a queue of length 1 (one queue
for each event type) and have the `updater thread' poll these queues.
(This ends up being an adhoc bugridden reimplementation of serve-events,
a separate thread for each interface of interest.)

Anyway, I think the conflict with the CAPI callback model seems to be my
desire to make certain chains of dependent computations "lazy", as
opposed to the "eager" callback model.  On that note, I was wondering if
there was some undocumented hook into the thread (lisp process) for each
interface.  This could be exposed as a callback that gets called in the
gui loop for that process at some specified point.

Perhaps this might alleviate the situation where it is not profitable to have
another thread interrupt the gui thread with capi:execute-with-interface.]

--- 
Madhu


Re: Process to refresh OpenGL panes


* Paul Tarvydas <201108301425.26160.paul.tarvydas@rogers.com> :
Wrote on Tue, 30 Aug 2011 14:25:26 -0400:

| ...
|> Does this work as expected?  If the `regenerate' events were generated
|> for a different interface, it would seem that dropping them would be
|> wrong, (I imagine it would be tough for a user to generate them
|> though...)
|
| You would need a separate updater (update receiver) for each window
| and regenerate would shoot separate messages to each.  Or something
| like that.

[Yes, I misunderstood.  As the "message" being passed was the `intf'
object, and the code was then using that object when calling
capi:execute-with-interface, I assumed that the same updater thread was
servicing many interfaces.]


|> ...  On that note, I was wondering if there was some undocumented
|> hook into the thread (lisp process) for each interface.
|
| Look at the :top-level-hook initarg for the class capi:interface.

I think this gets called exactly once, before passing control to the
event loop for that interface's thread (the `continuation'.)  I was
wondering if there was a way to hook into the event loop itself:
i.e. specify code which is called each time the platform's event loop
loops.

(Thanks!)
-- Madhu


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