Reply to topic  [ 8 posts ] 
Gtk wrapper around yorick command line 
Author Message
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Gtk wrapper around yorick command line
Hi,

Out of boredom as well as with real-life use cases in mind, I have tried implementing (as a yorick plug-in) a gtk interface for the yorick command line.

I get the impression that it is not possible at the moment to do it right.

Basically, I take a single line from a gtk entry and interpret it using:
Code:
yexec_include(line, 1)


This works fine, of course, as long as the interpreted code does not trigger an error.

Actually, I've been able to (mostly) silence simple errors by setting y_errorhook to a noop. SIGFPE still kicks me out of my GUI loop. What I miss most is:
  • the ability to plug yorick's stdout and / or stderr into widgets (presumably using handlers);
  • the ability to trap any error, including SIGFPE etc. too report errors from my interface and resume operation.

Is there currently a way to do that?

What I have in mind for the future is the ability to build simple interfaces from interpreted code, but still providing a command line in the interface since you can't access yorick's command line will the GUI is running. Of course I want to get rid of python in my Yorick GUIs, in the end.

Kind regards, Thibaut.


Last edited by thibaut on Wed Jun 05, 2013 3:49 am, edited 1 time in total.



Mon Apr 08, 2013 8:44 am
Profile WWW
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Re: Gtk wrapper around yoric kcommand line
Hi,

poking around, I figured I should use p_handler or p_xhandler. Is that right?

Anyway, I think I hit a bug trying that, please see:
http://yorick.sourceforge.net/phpBB3/viewtopic.php?f=6&t=394


Tue Apr 09, 2013 8:56 am
Profile WWW
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Re: Gtk wrapper around yoric kcommand line
Hi,

I've manage to do trap my errors by catching the error _inside_ the command I send to include():
Code:
include, strchar("if (catch(-1)) { return; } " + cmd), 1;


The good news is that even if we get a blocking GUI (meaning the Yorick prompt is blocked while the Gtk main loop is running), we can keep a command line somewhere to send arbitrary commands to Yorick.

I'm still interested in redirecting Yorick's output to a widget of my choice.

Kind regards, Thibaut.


Thu Apr 11, 2013 1:00 pm
Profile WWW
Yorick Master

Joined: Mon Nov 22, 2004 9:43 am
Posts: 354
Location: Livermore, CA, USA
Post Re: Gtk wrapper around yoric kcommand line
This is pretty neat, but it will take me some time to understand what you are doing.

There is no portable way to break into the yorick event handler; you have to do different things on unix and windows. My original plan was to write a complete GTK implementation of the play.h interface, to go in a separate directory gtk/ next to unix/ and win/ in the play/ directory. You need to use the u_event_src function in unix/playu.h to add the GTK file descriptor to the ones yorick is waiting for under unix. Under windows, it is w_add_input in win/playw.h. Unfortunately, I do not believe there is a way to prevent GTK from taking over the event loop. There may be equivalent routines in GTK (or glib) that allow you to add yorick's event handlers for input on stdin and its gist X11 windows.

Unless you figure out how to merge the two event loops, this is never going to work quite correctly. What you really want is for the GTK GUI to be running on a separate thread from the yorick interpreter. Without two threads, the GUI is always going to go dead while yorick is running. I'm not 100% sure this is possible without a specially rewritten play/gtk/ implementation as I had originally planned. Perhaps you can adapt the code you've already written to that more ambitious model?


Fri May 17, 2013 10:00 pm
Profile
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Re: Gtk wrapper around yoric kcommand line
Dear Dave,

This is my analysis of the situation, I have the impression you will agree with me:

I think we are pursuing two distinct, interrelated goals (please tell me if I misinterpreted your previous posts):
  • modernize Yorick:
    • create a cross-platform, built-in console;
    • get rid of Gist and direct X11 calls so that Yorick can use native windows on e.g. Mac OS, as well as MS Windows.
  • provide Yorick users with the ability to build GUIs directly from the Yorick prompt or Yorick scripts.

I'm already quite far in implementing the latter. My plug-in allows you to pop up a Gtk Window with very limited effort and connect widget event signals to interpreted Yorick functions quite easily. At the moment, I claim it is sufficiently advanced to port all the currently existing yorick/python/gtk packages around and get them to work at least as well as with python.

However, I am facing difficulties and ugliness that could perhaps disappear by implementing the former:
  • Yorick's display system requires the Yorick main loop to run (else the display is not updated!). I work around that by letting the Yorick main loop process on occasions, using set_idler to get back to the Gtk loop.
  • There is no easy way to pass mouse clicks to Yorick's builtin mouse() function while the Gtk loop is running. I work around that by reimplementing the mouse functionality in a more event-driven fashion. But to do that, I need to grab the mouse, which is particularly ugly and occasionally leads to situations where you need to kill Yorick from a virtual console. I also did not manage yet in setting the cursor or drawing a rubber band or rectangle when dragging the mouse. The other solution I have in mind would be to let Gist draw to a headless window and use rgb_read to copy the rendered graphics directly to a Gtk drawing area. This would be ugly, difficult, error prone, and slow. But perhaps less ugly than grabbing the mouse.
  • I need to be very careful in setting error handlers for all kinds of error conditions.
  • stdout still goes to the console or /dev/null, I don't know how to intercept it to display it to a specific widget (in addition or instead of the console).

You also raised the problem of mutli-threading. Indeed, in general terms, it's good when the GUI loop runs in another loop than the number-crunching code. On the other hand, writing applications is easier in a single threaded environment. In the current situation, it is already possible (in principle, not tested) to use my plug-in together with the svipc plug-in to run a multi-process yorick:
  • one server process for number crunching,
  • one client process for the interface
  • optionally other clients, for instance one for a command line.
The yorick/python method using stdin and stdout can also be applied to yorick/yorick, but I don't like it: it's slow and unstable when too many events occur (stdin gets flooded). I did try to launch a second thread directly in Yorick and failed miserably. I'm afraid you're lost if both threads need to access the stack.

On the other hand, it's often fine to just keep a single thread or process. Yes, that means that the GUI freezes during long computations. This is true of Yorick's command line, too. It is possible to put some code in your long computation that will let the Gtk code process from time to time (say, every second or so) to catch an "abort" button press, for instance.

To conclude, yes, I'm willing to help with a Gtk port of Yorick's play interface, but we need to define the scope. In my opinion:
  • we can leave the multi-threading/multi-process part alone for now, there are known work-arounds already;
  • the ability to draw directly to a GtkDrawingArea widget would help a lot in cross-platform support and embedding;
  • if the Gtk loop needs to be running for the Yorick graphic windows, we also need a Gtk based command line, for which I have a prototype already.

Kind regards, Thibaut.


Wed May 22, 2013 4:19 am
Profile WWW
Yorick Master

Joined: Mon Nov 22, 2004 9:43 am
Posts: 354
Location: Livermore, CA, USA
Post Re: Gtk wrapper around yoric kcommand line
Thibaut,

I haven't had time to study what you are doing yet. The MFC branch of the code in play/win/ (all of the C++ code in.cpp files), already implements a two threaded yorick, with the GUI, command line, and graphics windows all running in a separate thread from the yorick interpreter. As you discovered, the yorick interpreter is not thread safe, so there is no way to have multi-threaded interpreted code. However, it is perfectly possible to split out the graphical interface in its entirety and run that in a separate thread, and the play/win MFC code is an example of how to do that. Inasmuch as GTK+ appears to be based on the Windows message passing model, I think that a GTK+ implementation of play can be heavily based on the existing MFC implementation. My plan was to replace the MFC rich text editor widgets used for the command line and file editor by Scintilla based GTK+ widgets.

The one structural thing the MFC interface does not do, which you want, is to permit interpreted callbacks for GUI events. To add that feature, you need to implement a separate message queue in the interpreted thread, which passes along the GUI events to the interpreter. If you are implementing the event loop in GTK+, you can do that portably (I think), so that your GUI will appear as a new event source for yorick -- it will be handled in the same way as stdin. In fact, you'll be integrating it into the on_stdin callback, which will ultimately have the same event source from your GUI command window.

You should not attempt to use yexec_include for this purpose, because the parser can be unavailable (for example, when the user has typed the first line of a multi-line command and is typing the second line after the cont> prompt). A better interface is the more limited funcdef/ypush_func interface, which does not rely on parser availability. The limited abilities of this interface were in fact designed to be used by callback functions. I'd leave any invocation of the include function to the final user's callback function (invoked by funcdef). That way the final user can be the one to discover the many ways in which the parser might not be available. This suggestion applies to your current gy package as well -- I strongly recommend you stick with ypush_func to invoke interpreted callbacks, and not use the scarce-resource-bound yexec_include function. The code you invoke with ypush_func can always call the interpreted include function if you really need it.


Thu May 30, 2013 1:18 pm
Profile
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Re: Gtk wrapper around yorick command line
Hi Dave,.

I have finally understood something about interleaving the two loops (in a single thread): it can indeed be done very simply using after(), since Gtk provides functions to query the event queue and step through it. I'm experimenting with it now (there is a reactivity vs. load optimum to be found).

Concerning using ypush_func instead of yexec_include, I'll try it. The callbacks need to have this sort of prototypes:
Code:
func callback(object1, object2..., objectn) {
....
[return boolean_value;]
}
i.e. some calbacks need to return a value and I don't see from the documentation whether or not it is easy to get the return value. a possibility is to use my own "return" function:
Code:
gyreturn, retval
if ypush_func does not allow retrieving the actual return value.

This also means that the callback needs to return before the calling compiled code (so the return value can be processed). My guess was that a function pushed with ypush_func would actually run after the compiled code returns.

Kind regards, Thibaut.


Wed Jun 05, 2013 4:02 am
Profile WWW
Yorick Master

Joined: Tue Mar 07, 2006 10:31 pm
Posts: 125
Location: Meudon, France
Post Re: Gtk wrapper around yorick command line
I checked that: indeed, a func pushed with ypush_func() is only processed after the calling function returns, which makes it unsuitable for my purpose.


Wed Jun 12, 2013 3:51 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 8 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.