From octave-graphics-request at bevo dot che dot wisc dot edu Thu Jun 27 22:16:23 2002 Subject: Re: GTK and Octave From: =?iso-8859-1?q?Jo=E3o=20Cardoso?= To: octave-graphics at bevo dot che dot wisc dot edu Date: Fri, 28 Jun 2002 04:18:16 +0100 On Thursday 27 June 2002 20:33, Paul Kienzle wrote: > On Thu, Jun 27, 2002 at 12:47:22PM -0500, John W. Eaton wrote: > > On 27-Jun-2002, =?iso-8859-10?q?Jo=E3o=20Cardoso?= wrote: > > | On Tuesday 25 June 2002 00:12, Ben Sapp wrote: > > | | Hello, > > | | > > | | I have written a class and some DLD functions to accompany the > > | | class that allow a person to bring up most GTK widgets from > > | | within Octave. I also have a callback implementation working. > > | > > | Hi, > > | > > | I didn't compile your gtk_octave, only quickly browse the code. > > | > > | Again an Octave deficiency arises, as the gtk main loop is only > > | called during "Octave idle time", i.e., while Octave (actually > > | readline) waits for user keyboard input: > > | > > | /* This is called during octave idle time */ > > | extern int > > | event_hook() > > | { > > | while (gtk_events_pending()) > > | gtk_main_iteration_do(FALSE); > > | > > | return 0; > > | } > > | > > | What happens if the user hits a button which deploys a lengthly > > | calculation that afterwards the user wants to cancel hitting > > | another button? Nothing, the current calculation has to finish > > | until the new button is recognized (or the user code has to > > | check regularly for the new gtk event, which is not a very clean > > | approach) > > Or you let Ctrl-C return you to the octave toplevel just as it does > now. Not as pretty as a Cancel button, but it is available now. I use keyboard() in that cases, so I can left the function in a know state, and not ruin the calculations already done. But there is a misunderstanding here, more on this latter. > With backing store on the graphs so that you can uncover and see > them while octave is busy, then maybe blocking the GUI during > callback isn't so bad. > > > | This can be avoided only if event_hook() is also called during > > | Octave processing. Without knowing enough about Octave > > | "insides", it looks to me that the only "safe" way of doing this > > | is for Octave to call event_hook() when the parser hits a > > | "terminal symbol". > > | What do you think about this? > > > > How would this help in the lengthy calculation example? In that > > case, Octave would be off processing some long-running calculation > > so there would be no terminal symbol for the parser to hit. > > I agree. Consider: > > octave:96> a=rand(300); b=rand(300); > octave:97> tic; a*b; toc > ans = 21.038 > > Do you really want to slow down BLAS code by putting an event check > in the matrix multiply? I didn't explain myself very well; with "lengthly calculations" I meant user calculations, like running a script that might require hundreds of iterations---e.g. until a certain problem dependent level of accuracy is attained, or a certain subjective quality criteria, reveled by a graphic map .e.g., is meat. Of course I don't want "primitive" operations like matrix multiplication or eigenvalues determination to poll the "cancel" status. If however the cancel button has an associated callback that has opportunity to be executed, it can signal the lengthy iteration through a global user structure. (And keep the GUI/graphics updated, without the need for the backing store.) > > > If you were designing Octave from scratch with event handling > > (keyboard input, mouse clicks, signals, something else?) in mind, > > how would you do it? Me? Designing Octave from scratch? I'm not competent for the task :-) > Since the atomic operations are so large, I agree that nothing can be done here. Even my approach means that user feedback is not instantaneous, if the user program does iterations with lengthly "atomic" operations. But the event will be recognized, and the user program can continue, perhaps with less stringent parameters. In such cases, I evaluate and print on each iteration the expected time that the operation will take to finish , based on a time measure of a few iterations, just in case the user hits the cancel button when only a few minutes are left to completion... If you see the "real work" screenshots of my tk_octave page, you will notice (if you understand Portuguese) that these "real work" GUIs imply distinct operations, in some cases lengthly ones, and in some cases with empirical parameter settings. I don't want to ruin an afternoon of work by hitting CTRL-C when something is taking too long; instead I want to restart the process where it was but with another parameters. > you can't do cooperative > multitasking in octave (i.e., by inserting process_event_loop calls > in your scripts), so you are left with preemptive multitasking > (i.e., threads), and all that that entails: > * each callback running in its own thread since you don't know > which callbacks are going to take a long time. > * managing a pool of threads because you don't want to create > and destroy one on every call. > * making sure that all static data is thread local (including > the stuff in libcruft --- aren't all fortran variables static > by default?) > * making sure all shared data is protected by mutex (including > file access, symbol table access, etc.) > * deciding what to do with state variables that modify octave's > behaviour. What if one thread wants colormap(gray) and another > wants colormap(ocean). > In fact you will have to deal with most of these issues even with > cooperative multitasking, assuming things like read process the > event queue until data is available instead of blocking the entire > process. I don't want to share variables between octave and the GUI, as you do in your tk_octave, and I don't want to have multiple octave processes running the same problem. Nice concept, but too complex. I just want to give an opportunity for the GUI event loop to run from time to time, so I can do done=0; while(!done) compute; ...and compute... endwhile where "done" is a variable shared between the cancel button callback and my lengthly function. That's why I say that evaluating callbacks when the parser reaches a terminal symbol is "safe", as (scalar) variables are in a consistent state. That's the way I always have done it, as I couldn't found other way... even a X program can be irresponsible it the user callbacks don't give an oportunity for the main event loop to run. That's all I desire. Joao > > Paul Kienzle > pkienzle at users dot sf dot net