changeset 9215:1500d0197484

allow multiple input event hook functions to be installed simultaneously
author John W. Eaton <jwe@octave.org>
date Tue, 19 May 2009 12:37:57 -0400
parents 0839df1694ae
children 9d4b84b14bf0
files NEWS src/ChangeLog src/input.cc
diffstat 3 files changed, 87 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue May 19 11:47:46 2009 +0200
+++ b/NEWS	Tue May 19 12:37:57 2009 -0400
@@ -295,6 +295,10 @@
     function imfinfo provides information about an image file (size,
     type, colors, etc.)
 
+ ** The input_event_hook function has been replaced by the pair of
+    functions add_input_event_hook and remove_input_event_hook so that
+    more than one hook function may be installed at a time.
+
  ** Other miscellaneous new functions.
 
       addtodate          hypot                       reallog
--- a/src/ChangeLog	Tue May 19 11:47:46 2009 +0200
+++ b/src/ChangeLog	Tue May 19 12:37:57 2009 -0400
@@ -1,3 +1,9 @@
+2009-05-19  John W. Eaton  <jwe@octave.org>
+
+	* input.cc (Finput_event_hook): Delete.
+	(input_event_hook): Handle set of functions instead of just one.
+	(Fadd_input_event_hook, Fremove_input_event_hook): New functions.
+
 2009-05-19  Jaroslav Hajek  <highegg@gmail.com>
 
 	* Makefile.in: Add X11_LIBS to OCTINTERP_LINK_DEPS.
--- a/src/input.cc	Tue May 19 11:47:46 2009 +0200
+++ b/src/input.cc	Tue May 19 12:37:57 2009 -0400
@@ -1166,83 +1166,117 @@
   return retval;
 }
 
-static std::string hook_fcn;
-static octave_value user_data;
+typedef std::map<std::string, octave_value> hook_fcn_map_type;
+
+static hook_fcn_map_type hook_fcn_map;
 
 static int
 input_event_hook (void)
 {
-  if (is_valid_function (hook_fcn))
+  hook_fcn_map_type::iterator p = hook_fcn_map.begin ();
+
+  while (p != hook_fcn_map.end ())
     {
-      if (user_data.is_defined ())
-	feval (hook_fcn, user_data, 0);
+      std::string hook_fcn = p->first;
+      octave_value user_data = p->second;
+
+      p++;
+
+      if (is_valid_function (hook_fcn))
+	{
+	  if (user_data.is_defined ())
+	    feval (hook_fcn, user_data, 0);
+	  else
+	    feval (hook_fcn, octave_value_list (), 0);
+	}
       else
-	feval (hook_fcn, octave_value_list (), 0);
+	hook_fcn_map.erase (p);
     }
-  else
-    {
-      hook_fcn = std::string ();
-      user_data = octave_value ();
 
-      command_editor::remove_event_hook (input_event_hook);
-    }
+  if (hook_fcn_map.empty ())
+    command_editor::remove_event_hook (input_event_hook);
 
   return 0;
 }
 
-DEFUN (input_event_hook, args, ,
+DEFUN (add_input_event_hook, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{ofcn}, @var{odata}] =} input_event_hook (@var{fcn}, @var{data})\n\
-Given the name of a function as a string and any Octave value object,\n\
-install @var{fcn} as a function to call periodically, when Octave is\n\
-waiting for input.  The function should have the form\n\
+@deftypefn {Built-in Function} {} add_input_event_hook (@var{fcn}, @var{data})\n\
+Add the named function @var{fcn} to the list of functions to call\n\
+periodically when Octave is waiting for input.  The function should\n\
+have the form\n\
 @example\n\
 @var{fcn} (@var{data})\n\
 @end example\n\
 \n\
 If @var{data} is omitted, Octave calls the function without any\n\
-arguments.  If both @var{fcn} and @var{data} are omitted, Octave\n\
-clears the hook.  In all cases, the name of the previous hook function\n\
-and the user data are returned.\n\
+arguments.\n\
+@seealso{remove_input_event_hook}\n\
 @end deftypefn")
 {
   octave_value_list retval;
 
   int nargin = args.length ();
 
-  if (nargin > 2)
-    print_usage ();
-  else
+  if (nargin == 1 || nargin == 2)
     {
-      octave_value tmp_user_data;
+      octave_value user_data;
+
+      if (nargin == 2)
+	user_data = args(1);
+
+      std::string hook_fcn = args(0).string_value ();
 
-      std::string tmp_hook_fcn;
+      if (! error_state)
+	{
+	  if (hook_fcn_map.empty ())
+	    command_editor::add_event_hook (input_event_hook);
 
-      if (nargin > 1)
-	tmp_user_data = args(1);
+	  hook_fcn_map[hook_fcn] = user_data;
+	}
+      else
+	error ("add_input_event_hook: expecting string as first arg");
+    }
+  else
+    print_usage ();
 
-      if (nargin > 0)
-	{
-	  tmp_hook_fcn = args(0).string_value ();
+  return retval;
+}
 
-	  if (error_state)
-	    {
-	      error ("input_event_hook: expecting string as first arg");
-	      return retval;
-	    }
+DEFUN (remove_input_event_hook, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} remove_input_event_hook (@var{fcn})\n\
+Remove the named function @var{fcn} to the list of functions to call\n\
+periodically when Octave is waiting for input.\n\
+@seealso{add_input_event_hook}\n\
+@end deftypefn")
+{
+  octave_value_list retval;
 
-	  command_editor::add_event_hook (input_event_hook);
-	}
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string hook_fcn = args(0).string_value ();
 
-      if (nargin == 0)
-	command_editor::remove_event_hook (input_event_hook);
+      if (! error_state)
+	{
+	  hook_fcn_map_type::iterator p = hook_fcn_map.find (hook_fcn);
 
-      retval(1) = user_data;
-      retval(0) = hook_fcn;
+	  if (p != hook_fcn_map.end ())
+	    hook_fcn_map.erase (p);
+	  else
+	    error ("remove_input_event_hook: %s not found in list",
+		   hook_fcn.c_str ());
 
-      hook_fcn = tmp_hook_fcn;
-      user_data = tmp_user_data;
+	  if (hook_fcn_map.empty ())
+	    command_editor::remove_event_hook (input_event_hook);
+	}
+      else
+	error ("remove_input_event_hook: expecting string as first arg");
     }
+  else
+    print_usage ();
 
   return retval;
 }