Hello, It sounds a little weird to me that you use a synchronous call to the UI thread (via syncExec and not asyncExec), but then use an asynchronous call to an agent ?
I don't have repl here to test it, but could you make something simpler, like creating a mutable structure in the let - an array of one object - and during the sync call, place the result in the array ? Would this impure approach have some drawbacks I can't see right now ? It seems to me that this would be very local to the function, so maybe not that bad ? This is already an "impure" (in the functional sense) operation, since it's an IO operation, after all ? And also, you could optimize code in the macro by adding code to test if you are already in the UI thread, and if so, save the call via the runnable. And maybe, you could consider that the display is such a common thing in the application that making it a global var such as *out*, *in*, could help passing it as a parameter for the vast majority of functions ? Something named like *swt-display* ? So the macro could be (not tested) : (defmacro swt-sync-call "Ensures that the body is synchronously executed in *swt-display*'s UI thread. Returns the value of the last item of body. Does not create a Runnable if already called from within the right thread" [& body] `(let [running-thread-display (org.eclipse.swt.Display/getCurrent) already-ui-thread (= *swt-display* running-thread-display)] (if already-ui-thread (do ~...@body) (let [val-res# (make-array Object 1)] (. *swt-display* syncExec (proxy [Runnable] [] (run [] (aset val-res# 0 (do ~...@body))))) (aget val-res# 0))))) HTH, -- Laurent 2009/2/19 BerlinBrown <berlin.br...@gmail.com> > > > > On Feb 19, 11:58 am, BerlinBrown <berlin.br...@gmail.com> wrote: > > I am working with this SWT application. For most calls with SWT, if > > you want to request data from a widget, then you must do so through > > the syncExec or asynExec. These methods require an implementation of > > runnable as an argument. > > > > This works fine for 'setting' a value, but I have trouble when I need > > to get a value from a widget, like a Textarea. This is the macro that > > I created and it runs, but I don't think it is working properly. Does > > anyone have suggestions? > > > > Usage: > > term (get-sync-call disp (. box getText)) > > > > (defmacro get-sync-call > > "Synchronous execute call. Create a proxy Runnable object and then > > execute the > > body code" > > [disp & body] > > ;;;;;;;;;;;;;; > > `(let [val-res# (agent nil)] > > ;;(. ~disp syncExec > > (. ~disp syncExec (proxy [Runnable] [] (run [] (send val-res# (fn > > [_#] ~...@body))))) > > @val-res#)) > > > (defmacro get-sync-call > "Synchronous execute call. Create a proxy Runnable object and then > execute the > body code" > [disp & body] > ;;;;;;;;;;;;;; > `(let [val-res# (ref nil)] > ;;(. ~disp syncExec (proxy [Runnable] [] (run [] (send val-res# > (fn [_#] ~...@body))))) > (. ~disp syncExec (proxy [Runnable] [] (run [] (dosync (ref-set > val-res# ~...@body))))) > (. Thread sleep 50) > (deref val-res#))) > > OK, I added this, don't know why I added Thread. > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---