| I'm afraid I'm restarting an old discussion, but I've had it on the | backburner, and now that I'm moving forward, I'm not quite sure how to | finish out the solution. | | >>>>> "AH" == Andy Hefner ahefner@gmail.com writes: | | AH> What I might do is run a separate thread from the GUI that monitors | AH> external conditions. It can close over your frame event queue, and | AH> communicate changes to the GUI via events as necessary. Just define | AH> your own event subclasses and write handle-event methods for them, | AH> which will run in the GUI thread and can perform the necessary | AH> updates. McCLIM itself already works in this fashion on threaded | AH> platforms, events are collected from CLX in a background thread which | AH> queues them up for the applications to handle. | | I think this is the right solution for control applications. One has | a second thread, which gets status updates and latches them into | slots in the application frame, and then we queue up an event. Here | are a couple of follow-ons, though: | | 1. Do I just make an event that will translate into setting | frame-needs-redisplay? |
I tried this approach in Lispworks CLIM and it seems to work pretty well.
Paul
~~~~~~~~~~~~~~~~~~~~~~~~~~ (in-package :clim-user)
(defclass thing () ((x :initarg :x) (y :initarg :y)) (:default-initargs :x (random 100) :y (random 100)))
(define-application-frame a-test () ((things :initform nil)) (:pointer-documentation nil) (:menu-bar nil) (:panes (p1 :application :width 300 :height 200 :end-of-line-action :allow :display-function 'p1df :incremental-redisplay t :display-time t )) (:layouts (default p1)))
(defun p1df (frame pane) (with-output-recording-options (pane :record t) (with-slots (things) frame (dolist (thing things) (with-slots (x y) thing (updating-output (pane :unique-id thing :cache-value (list x y) :cache-test #'equal) (draw-rectangle* pane x y (+ x 10) (+ y 10) :ink +blue+)))))))
(defvar *frame* nil)
(defun doit () ;; display A-TEST application (setq *frame* (make-application-frame 'a-test)) (run-frame-top-level *frame*))
(defclass my-event (device-event) ;; T-L-S seems to expect only device-event ;; Can't make application-pane see any yet ((pane :initarg :pane)))
(defmethod handle-event (client (event my-event)) (with-application-frame (frame) (with-slots (pane) event (redisplay-frame-pane frame pane))))
(defun stuffit (frame) ;; do something to "update the database" (let ((tls (frame-top-level-sheet frame)) (pane (frame-standard-output frame))) (with-slots (things) frame (with-output-recording-options (pane :record t) (push (make-instance 'thing) things)) (setf (pane-needs-redisplay pane) t)) (queue-event tls (make-instance 'my-event :sheet tls :pane pane :modifier-state 0))))