Octave/backend interface proposal

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Octave/backend interface proposal

Michael Goffioul
Hi,

Following a chat I had with Shai, we though we would need at some
point in time some kind of interaction between octave and any
graphics backend (to exchange some information). After some
discussions, we agreed on a scheme, whose skeleton would
be something like in the attached files.

The idea is to define a graphics_backend interface (that the
actual backend would implement) and attach to a figure the
backend to which it belongs, which serves as an entry point
for octave/backend interaction. This scheme should allow
multiple backends running at the same time.

Example of possible interaction are:
- closing a figure window
- getting font metric information
- getting drawing canvas size (useful to deal with normalized
units)
- other things we didn't think about yet

For the moment, only a gnuplot backend is defined and will
be used as default.

If you're OK with the concept (and the implementation), please
commit.

Michael.

graphics-backend.h (4K) Download Attachment
graphics-backend.cc (2K) Download Attachment
backend.diff (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Shai Ayal-2
On Jan 20, 2008 11:31 PM, Michael Goffioul <[hidden email]> wrote:

> Hi,
>
> Following a chat I had with Shai, we though we would need at some
> point in time some kind of interaction between octave and any
> graphics backend (to exchange some information). After some
> discussions, we agreed on a scheme, whose skeleton would
> be something like in the attached files.
>
> The idea is to define a graphics_backend interface (that the
> actual backend would implement) and attach to a figure the
> backend to which it belongs, which serves as an entry point
> for octave/backend interaction. This scheme should allow
> multiple backends running at the same time.
>
> Example of possible interaction are:
> - closing a figure window
> - getting font metric information
> - getting drawing canvas size (useful to deal with normalized
> units)
> - other things we didn't think about yet
>
> For the moment, only a gnuplot backend is defined and will
> be used as default.
>
> If you're OK with the concept (and the implementation), please
> commit.

I'm OK with the concept and implementation, however do we really need
to get the figure position from the backend this way? Can't the
backend just update the figure.position property? is this a
multithreading related problem?
Unless there is some real problem, I think this data exchange
mechanism should be only for things that have no corresponding
property -- i.e. font metrics

Shai
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Michael Goffioul
On Jan 21, 2008 5:52 AM, Shai Ayal <[hidden email]> wrote:
> I'm OK with the concept and implementation, however do we really need
> to get the figure position from the backend this way? Can't the
> backend just update the figure.position property? is this a
> multithreading related problem?

No, it's because I'm developing other code in parallel and I thought
I needed it, but in the end it was the canvas size I needed. So the
get_figure_position can be removed.

> Unless there is some real problem, I think this data exchange
> mechanism should be only for things that have no corresponding
> property -- i.e. font metrics

Indeed.

I also think that putting this class into a separated header will get me
into trouble, because of the classes dependencies. I think I'll put it
into graphics.h.in and generate a new patch. Any objection?

Michael.
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Muthiah Annamalai-3
In reply to this post by Michael Goffioul

> From: "Michael Goffioul" <[hidden email]>
> Subject: Re: Octave/backend interface proposal
> To: "Shai Ayal" <[hidden email]>
> Cc: Octave Maintainers List <[hidden email]>
> Message-ID:
> <[hidden email]>
> Content-Type: text/plain; charset="iso-8859-1"
>
> On Jan 21, 2008 9:58 AM, Michael Goffioul <[hidden email]> wrote:
>  
>> I also think that putting this class into a separated header will get me
>> into trouble, because of the classes dependencies. I think I'll put it
>> into graphics.h.in and generate a new patch. Any objection?
>>    
>
> Here's a completed (working) version of the patch. It defines the
> base_graphics_backend
> and graphics_backend classes, associate a backend with a figure, defines the
> default gnuplot backend and move drawnow to C++.
>
> I tested it and it seems to work OK.
>
> Michael.
>  
There maybe a possible oversight in your patch in the following lines,
from the function drawnow

+  if (h.ok () && h != 0)

you may have intended the checks the other way.

-Muthu


Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Michael Goffioul
In reply to this post by Michael Goffioul
On Jan 21, 2008 9:58 AM, Michael Goffioul <[hidden email]> wrote:
> I also think that putting this class into a separated header will get me
> into trouble, because of the classes dependencies. I think I'll put it
> into graphics.h.in and generate a new patch. Any objection?

Here's a completed (working) version of the patch. It defines the
base_graphics_backend
and graphics_backend classes, associate a backend with a figure, defines the
default gnuplot backend and move drawnow to C++.

I tested it and it seems to work OK.

Michael.

gnuplot_drawnow.m (7K) Download Attachment
graphics.diff (18K) Download Attachment
graphics.changelog (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal - Browser

BrowseOct
In reply to this post by Michael Goffioul
I'm working on a very limited and different approach to a GUI. Octave is a STDIN and STDOUT focused product. I'd like a functionalized library using browser based java scripting as an alternative. (It's crude in this form, but workable).
I've needed to use a browser as a front end to html GUIs in Octave with Stdin and Stdout. Both IE (4+) in windows and Firefox support console output. This is based on Gunter Born's wscript page. It stops octave in the process. I still support your scheme, but there is some browser based interaction that would add a lot to Octave.

I'm still working the firefox stuff and linux.


Yes, it's still very crude, but it offers some simple opportunities for easy development of GUI's with forms and browsers.

The below example should work...
In windows octave, a simple line like the following executes a cscript.
[Status,Output] = System("cscript octave2.js");

The cscript returns the wscript.echo entries from the cscript batch file.

octave2.js

//************************************************
// File:    Form1.js (WSH sample in JScript)
// Author:  (c) G. Born modified for octave
//
// Using Internet Explorer 4 or 5 to retrieve
// form input
//************************************************
var Text2 = "You entered:\n";

// Launch Internet Explorer, and connect event handler.
var oIE = WScript.CreateObject("InternetExplorer.Application", "IE_");

oIE.Left = 50;           // Window position and other properties
oIE.Top = 100;
oIE.Height = 100;
oIE.Width = 280;
oIE.MenuBar = 0;         // No menu
oIE.ToolBar = 0;
oIE.StatusBar = 0;
// Commented out because it causes a corrupted window border.
// oIE.Resizable = 0     // Disable resizing.
oIE.navigate(GetPath() + "Form1.htm");  // Load form.
oIE.Visible = 1;         // Keep visible.

// Important: Wait until IE is ready.
while (oIE.Busy) {WScript.Sleep(200)}  // Suspend

var ready = false;      // Form is still open.
   
// Wait until the user closes the form using
// the Close button in the upper right corner of the window.
// This sets ready to true in the onclose event.
while (!ready) {WScript.Sleep(500)}  // Suspend

// Display the data obtained in the event handling procedure.
WScript.Echo(Text2 + "\n" + name + "\n" + age);

// We're ready now. The sample script terminates.
// Here you can add script-specific code.

// Event handler and helper

function IE_OnQuit()
{
    // Event handler is called if IE terminates.
    // This happens if the user clicks the Close button.
    // Retrieve the values.
    name = "Name: " + oIE.Document.ValidForm.fName.value;
    age = "Age: " + oIE.Document.ValidForm.fAge.value;
    ready = true;        // Indicate form is closed.
}

function GetPath()
{
    // Get script path because form (HTML file)
    // must be in the same folder.
    var path = WScript.ScriptFullName;
    path = path.substr(0, path.lastIndexOf("\\") + 1);
    return path;
}

//*** End


and the form form1.htm which returns to the script on close.

<HTML>
<form name="ValidForm">
    <p>
        Name:  
        <input type="text" size="5" name="fName">  
        Age:  
        <input type="text" size="3" name="fAge">
        <br>

        Password:  
        <input type="password" size="12" maxlength="8" name="fPassw">
           
        <input type="button" name="Button1" value="OK">
        <br>

        <input type="checkbox" name="fPrinter" value="1" checked>
        Printer  
        <input type="checkbox" name="fScreen" value="2">
        Screen
        <br>

        Remarks:
        <br> 

        <textarea cols="40" rows="5" name="fRemark">
        </textarea>
    </p>
</form>
</HTML>







Michael Goffioul-2 wrote
Hi,

Following a chat I had with Shai, we though we would need at some
point in time some kind of interaction between octave and any
graphics backend (to exchange some information). After some
discussions, we agreed on a scheme, whose skeleton would
be something like in the attached files.

The idea is to define a graphics_backend interface (that the
actual backend would implement) and attach to a figure the
backend to which it belongs, which serves as an entry point
for octave/backend interaction. This scheme should allow
multiple backends running at the same time.

Example of possible interaction are:
- closing a figure window
- getting font metric information
- getting drawing canvas size (useful to deal with normalized
units)
- other things we didn't think about yet

For the moment, only a gnuplot backend is defined and will
be used as default.

If you're OK with the concept (and the implementation), please
commit.

Michael.
Thanks J H
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal - Browser

BrowseOct
All,
Mostly, I developed this from current sources and code in an hour. Many Octave users could use a scripting/ browser GUI interface that's easy to code, if not elegant.

The solution would need to be a functionalized package for platform and browser independence. As both IE and Firefox support STDOUT in some manner from windows 98 to Linux, I think this is a workable GUI front end enhancement. Clearly it is not a replacement for a an integrated GUI.  I did get it to work in MATLAB.

Of primary importance in an adoptable model is the functionalizing of the .m file and text stream approach and a fork method to keep the browser from modally freezing the console.

Not at all hard considering for 3 hours browsing, borrrowing and testing.

Still thinking about the framework approach...

function SetBrowserParams(...);
function GetBrowserParams(...);
function SetBrowser(string Browser);
function SetBrowserEnv("LINUX","Firefox");
[Status,Output] = ModalBrowser("formname.html",...);

.... etc.

Will try this on firefox using -console and PClinux this weekend.

Best




BrowseOct wrote
I'm working on a very limited and different approach to a GUI. Octave is a STDIN and STDOUT focused product. I'd like a functionalized library using browser based java scripting as an alternative. (It's crude in this form, but workable).
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

John W. Eaton-6
In reply to this post by Muthiah Annamalai-3
On 22-Jan-2008, Muthiah Annamalai wrote:

| There maybe a possible oversight in your patch in the following lines,
| from the function drawnow
|
| +  if (h.ok () && h != 0)
|
| you may have intended the checks the other way.

I think it is OK.  H is not a pointer.  H == 0 is the "root figure",
not an actual figure.

jwe
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Muthiah Annamalai-3
John W. Eaton wrote:

> On 22-Jan-2008, Muthiah Annamalai wrote:
>
> | There maybe a possible oversight in your patch in the following lines,
> | from the function drawnow
> |
> | +  if (h.ok () && h != 0)
> |
> | you may have intended the checks the other way.
>
> I think it is OK.  H is not a pointer.  H == 0 is the "root figure",
> not an actual figure.
>
> jwe
>
>  
I'll have to be careful before I can hazard a guess, next time.
Thanks,
-Muthu

Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

John W. Eaton-6
In reply to this post by Michael Goffioul
On 22-Jan-2008, Michael Goffioul wrote:

| On Jan 21, 2008 9:58 AM, Michael Goffioul <[hidden email]> wrote:
| > I also think that putting this class into a separated header will get me
| > into trouble, because of the classes dependencies. I think I'll put it
| > into graphics.h.in and generate a new patch. Any objection?
|
| Here's a completed (working) version of the patch. It defines the
| base_graphics_backend
| and graphics_backend classes, associate a backend with a figure, defines the
| default gnuplot backend and move drawnow to C++.
|
| I tested it and it seems to work OK.

I applied the patch and checked it in.

I also made the following additional changes to avoid some calls to
eval and feval, and to (I think) properly protect the
drawnow_executing variable and the __drawnow_request__ state.

Thanks,

jwe



src/ChangeLog:

2008-01-22  John W. Eaton  <[hidden email]>

        * graphics.cc (clear_drawnow_request): New function.
        (Fdrawnow): Add it to the unwind_protect stack.

        * input.cc (Vdrawnow_requested): No longer static.
        * input.h: Provide decl.
        * graphics.cc (Fdrawnow, Fset, make_graphics_object):
        Use Vdrawnow_requested directly.

        * toplev.cc (octave_add_atexit_function,
        octave_remove_atexit_function): New functions.
        (Fatexit): Use them.
        * graphics.cc (Fdrawnow): Call octave_add_atexit_function instead
        of using eval.
        * toplev.h (octave_add_atexit_function,
        octave_remove_atexit_function): Provide decls.


Index: src/graphics.cc
===================================================================
RCS file: /cvs/octave/src/graphics.cc,v
retrieving revision 1.77
diff -u -u -w -r1.77 graphics.cc
--- src/graphics.cc 22 Jan 2008 19:42:48 -0000 1.77
+++ src/graphics.cc 22 Jan 2008 20:27:11 -0000
@@ -34,17 +34,20 @@
 #include <set>
 #include <string>
 
+#include "file-ops.h"
+#include "file-stat.h"
+
 #include "defun.h"
 #include "error.h"
 #include "graphics.h"
+#include "input.h"
 #include "ov.h"
 #include "oct-obj.h"
 #include "oct-map.h"
 #include "ov-fcn-handle.h"
 #include "parse.h"
+#include "toplev.h"
 #include "unwind-prot.h"
-#include "file-ops.h"
-#include "file-stat.h"
 
 static void
 gripe_set_invalid (const std::string& pname)
@@ -1194,7 +1197,7 @@
       feval ("gnuplot_drawnow", args);
     }
 
-  Matrix get_canvas_size (const graphics_handle& fh) const
+  Matrix get_canvas_size (const graphics_handle&) const
     { return Matrix (1, 2, 0.0); }
 };
 
@@ -1955,7 +1958,7 @@
             }
 
   if (! error_state && request_drawnow)
-    feval ("__request_drawnow__");
+    Vdrawnow_requested = true;
         }
       else
         error ("set: expecting graphics handle as first argument");
@@ -2119,7 +2122,7 @@
       retval = h.value ();
 
       if (! error_state)
- feval ("__request_drawnow__");
+ Vdrawnow_requested = true;
     }
   else
     error ("__go%s__: unable to create graphics handle",
@@ -2365,6 +2368,12 @@
   return octave_value (gh_manager::figure_handle_list ());
 }
 
+static void
+clear_drawnow_request (void *)
+{
+  Vdrawnow_requested = false;
+}
+
 DEFUN (drawnow, args, ,
    "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} __go_drawnow__ ()\n\
@@ -2377,19 +2386,20 @@
 
   octave_value retval;
 
-  if (drawnow_executing >= 1)
-    return retval;
+  unwind_protect::begin_frame ("Fdrawnow");
+  unwind_protect::add (clear_drawnow_request);
+
+  unwind_protect_int (drawnow_executing);
 
+  if (++drawnow_executing <= 1)
+    {
   if (! __go_close_all_registered__)
     {
-      // FIXME: is there a C++ way to do this?
-      int parse_status;
-      eval_string ("atexit (\"__go_close_all__\")", true, parse_status);
+  octave_add_atexit_function ("__go_close_all__");
+
       __go_close_all_registered__ = true;
     }
 
-  ++drawnow_executing;
-
   if (args.length () == 0)
     {
       Matrix hlist = gh_manager::figure_handle_list ();
@@ -2431,7 +2441,7 @@
 
   if (! error_state)
     {
-      int pos = file.find_last_of (file_ops::dir_sep_chars);
+  size_t pos = file.find_last_of (file_ops::dir_sep_chars);
 
       if (pos != NPOS)
  {
@@ -2456,6 +2466,7 @@
       if (h.ok ())
  {
   graphics_object go = gh_manager::get_object (h);
+
   figure::properties& fprops = dynamic_cast<figure::properties&> (go.get_properties ());
 
   fprops.get_backend ()
@@ -2478,13 +2489,9 @@
     }
   else
     print_usage ();
+    }
 
-  // FIXME: is there a C++ way to do this?
-  octave_value_list fargs;
-  fargs(0) = false;
-  feval ("__request_drawnow__", fargs);
-
-  --drawnow_executing;
+  unwind_protect::run_frame ("Fdrawnow");
 
   return retval;
 }
Index: src/input.cc
===================================================================
RCS file: /cvs/octave/src/input.cc,v
retrieving revision 1.191
diff -u -u -w -r1.191 input.cc
--- src/input.cc 28 Dec 2007 20:56:56 -0000 1.191
+++ src/input.cc 22 Jan 2008 20:27:11 -0000
@@ -141,7 +141,7 @@
 
 // TRUE if the plotting system has requested a call to drawnow at
 // the next user prompt.
-static bool Vdrawnow_requested = false;
+bool Vdrawnow_requested = false;
 
 // TRUE if we are running in the Emacs GUD mode.
 static bool Vgud_mode = false;
Index: src/input.h
===================================================================
RCS file: /cvs/octave/src/input.h,v
retrieving revision 1.45
diff -u -u -w -r1.45 input.h
--- src/input.h 12 Oct 2007 21:27:30 -0000 1.45
+++ src/input.h 22 Jan 2008 20:27:11 -0000
@@ -84,6 +84,10 @@
 // TRUE after a call to completion_matches.
 extern bool octave_completion_matches_called;
 
+// TRUE if the plotting system has requested a call to drawnow at
+// the next user prompt.
+extern bool Vdrawnow_requested;
+
 extern std::string gnu_readline (const std::string& s, bool force_readline = false);
 
 extern void initialize_command_input (void);
Index: src/toplev.cc
===================================================================
RCS file: /cvs/octave/src/toplev.cc,v
retrieving revision 1.211
diff -u -u -w -r1.211 toplev.cc
--- src/toplev.cc 12 Jan 2008 07:50:55 -0000 1.211
+++ src/toplev.cc 22 Jan 2008 20:27:11 -0000
@@ -663,6 +663,32 @@
     }
 }
 
+void
+octave_add_atexit_function (const std::string& fname)
+{
+  octave_atexit_functions.push_front (fname);
+}
+
+bool
+octave_remove_atexit_function (const std::string& fname)
+{
+  bool found = false;
+
+  for (std::list<std::string>::iterator p = octave_atexit_functions.begin ();
+       p != octave_atexit_functions.end (); p++)
+    {
+      if (*p == fname)
+ {
+  octave_atexit_functions.erase (p);
+  found = true;
+  break;
+ }
+    }
+
+  return found;
+}
+
+
 DEFUN (atexit, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} atexit (@var{fcn})\n\
@@ -723,22 +749,10 @@
           if (! error_state)
     {
       if (add_mode)
- octave_atexit_functions.push_front (arg);
+ octave_add_atexit_function (arg);
       else
  {
-  bool found = false;
-  std::list<std::string>::iterator it;
-
-  for (std::list<std::string>::iterator p = octave_atexit_functions.begin ();
-       p != octave_atexit_functions.end (); p++)
-    {
-      if (*p == arg)
- {
-  octave_atexit_functions.erase (p);
-  found = true;
-  break;
- }
-    }
+  bool found = octave_remove_atexit_function (arg);
 
   if (nargout > 0)
     retval(0) = found;
Index: src/toplev.h
===================================================================
RCS file: /cvs/octave/src/toplev.h,v
retrieving revision 1.62
diff -u -u -w -r1.62 toplev.h
--- src/toplev.h 4 Dec 2007 18:12:33 -0000 1.62
+++ src/toplev.h 22 Jan 2008 20:27:11 -0000
@@ -46,6 +46,12 @@
 extern OCTINTERP_API void
 do_octave_atexit (void);
 
+extern OCTINTERP_API void
+octave_add_atexit_function (const std::string& fname);
+
+extern OCTINTERP_API bool
+octave_remove_atexit_function (const std::string& fname);
+
 // Current command to execute.
 extern OCTINTERP_API tree_statement_list *global_command;
 
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Shai Ayal-2
On Jan 22, 2008 10:31 PM, John W. Eaton <[hidden email]> wrote:

>
> On 22-Jan-2008, Michael Goffioul wrote:
>
> | On Jan 21, 2008 9:58 AM, Michael Goffioul <[hidden email]> wrote:
> | > I also think that putting this class into a separated header will get me
> | > into trouble, because of the classes dependencies. I think I'll put it
> | > into graphics.h.in and generate a new patch. Any objection?
> |
> | Here's a completed (working) version of the patch. It defines the
> | base_graphics_backend
> | and graphics_backend classes, associate a backend with a figure, defines the
> | default gnuplot backend and move drawnow to C++.
> |
> | I tested it and it seems to work OK.
>
> I applied the patch and checked it in.
>
> I also made the following additional changes to avoid some calls to
> eval and feval, and to (I think) properly protect the
> drawnow_executing variable and the __drawnow_request__ state.

drawnow.m needs to be removed from scripts/plot/Makefile.in

Shai
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

John W. Eaton-6
On 23-Jan-2008, Shai Ayal wrote:

| drawnow.m needs to be removed from scripts/plot/Makefile.in

It's not in my copy.

jwe
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

Michael Goffioul
In reply to this post by John W. Eaton-6
On Jan 22, 2008 9:31 PM, John W. Eaton <[hidden email]> wrote:
> I applied the patch and checked it in.
>
> I also made the following additional changes to avoid some calls to
> eval and feval, and to (I think) properly protect the
> drawnow_executing variable and the __drawnow_request__ state.

Thanks. Concerning Vdrawnow_requested, I think it'd be better to also
export it (use OCTINTERP_API tag), as it migth be useful for 3rd-party
backend. Could you add this?

Michael.
Reply | Threaded
Open this post in threaded view
|

Re: Octave/backend interface proposal

John W. Eaton-6
On 23-Jan-2008, Michael Goffioul wrote:

| Thanks. Concerning Vdrawnow_requested, I think it'd be better to also
| export it (use OCTINTERP_API tag), as it migth be useful for 3rd-party
| backend. Could you add this?

OK.

jwe