diff libinterp/corefcn/event-manager.h @ 27263:99aa1bcb8848

rename octave_link and octave_link_events classes, move inside octave namespace * event-manager.h, event-manager.cc: Rename from octave-link.h and octave-link.cc. (class event_manager): Rename from octave_link. Move inside octave namespace. Change all uses. (class interpreter_events): Rename from octave_link_events. Move inside octave namespace. Change all uses. * libinterp/corefcn/module.mk: Update. * qt-interpreter-events.h, qt-interpreter-events.cc: Rename from octave-qt-link.h and octave-qt-link.cc. (class qt_interpreter_events): Rename from octave_qt_link_events Change all uses. * libgui/src/module.mk: Update. Change all interpreter functions that uses octave_link in their names to use event_manager instead.
author John W. Eaton <jwe@octave.org>
date Thu, 18 Jul 2019 11:23:22 -0400
parents libinterp/corefcn/octave-link.h@d67f369b3074
children 378d3c91f85b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/event-manager.h	Thu Jul 18 11:23:22 2019 -0400
@@ -0,0 +1,548 @@
+/*
+
+Copyright (C) 2013-2019 John W. Eaton
+Copyright (C) 2011-2019 Jacob Dawid
+Copyright (C) 2011-2019 John P. Swensen
+
+This file is part of Octave.
+
+Octave is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<https://www.gnu.org/licenses/>.
+
+*/
+
+#if ! defined (octave_event_manager_h)
+#define octave_event_manager_h 1
+
+#include "octave-config.h"
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "oct-mutex.h"
+#include "octave.h"
+#include "event-queue.h"
+#include "uint8NDArray.h"
+
+class octave_value;
+class string_vector;
+
+namespace octave
+{
+  class symbol_info_list;
+
+  class interpreter_events
+  {
+  public:
+
+    interpreter_events (void) = default;
+
+    interpreter_events (const interpreter_events&) = default;
+
+    interpreter_events& operator = (const interpreter_events&) = default;
+
+    virtual ~interpreter_events (void) = default;
+
+    virtual bool do_confirm_shutdown (void) { return false; }
+
+    virtual bool do_copy_image_to_clipboard (const std::string& /*file*/)
+    {
+      return false;
+    }
+
+    virtual bool do_edit_file (const std::string& /*file*/) { return false; }
+
+    virtual bool do_prompt_new_edit_file (const std::string& /*file*/)
+    {
+      return false;
+    }
+
+    virtual std::string
+    do_question_dialog (const std::string& /*msg*/,
+                        const std::string& /*title*/,
+                        const std::string& /*btn1*/,
+                        const std::string& /*btn2*/,
+                        const std::string& /*btn3*/,
+                        const std::string& /*btndef*/)
+    {
+      return "";
+    }
+
+    virtual std::pair<std::list<int>, int>
+    do_list_dialog (const std::list<std::string>& /*list*/,
+                    const std::string& /*mode*/,
+                    int /*width*/, int /*height*/,
+                    const std::list<int>& /*initial_value*/,
+                    const std::string& /*name*/,
+                    const std::list<std::string>& /*prompt*/,
+                    const std::string& /*ok_string*/,
+                    const std::string& /*cancel_string*/)
+    {
+      return std::pair<std::list<int>, int> ();
+    }
+
+    virtual std::list<std::string>
+    do_input_dialog (const std::list<std::string>& /*prompt*/,
+                     const std::string& /*title*/,
+                     const std::list<float>& /*nr*/,
+                     const std::list<float>& /*nc*/,
+                     const std::list<std::string>& /*defaults*/)
+    {
+      return std::list<std::string> ();
+    }
+
+    typedef std::list<std::pair<std::string, std::string>> filter_list;
+
+    virtual std::list<std::string>
+    do_file_dialog (const filter_list& /*filter*/,
+                    const std::string& /*title*/,
+                    const std::string& /*filename*/,
+                    const std::string& /*dirname*/,
+                    const std::string& /*multimode*/)
+    {
+      return std::list<std::string> ();
+    }
+
+    virtual int
+    do_debug_cd_or_addpath_error (const std::string& /*file*/,
+                                  const std::string& /*dir*/,
+                                  bool /*addpath_option*/)
+    {
+      return -1;
+    }
+
+    virtual void do_change_directory (const std::string& /*dir*/) { }
+
+    virtual void do_file_remove (const std::string& /*old_name*/,
+                                 const std::string& /*new_name*/)
+    { }
+
+    virtual void do_file_renamed (bool) { }
+
+    virtual void
+    do_execute_command_in_terminal (const std::string& /*command*/) { }
+
+    virtual uint8NDArray do_get_named_icon (const std::string& /*icon_name*/)
+    {
+      return uint8NDArray ();
+    }
+
+    virtual void do_set_workspace (bool /*top_level*/, bool /*debug*/,
+                                   const octave::symbol_info_list& /*syminfo*/,
+                                   bool /*update_variable_editor*/)
+    { }
+
+    virtual void do_clear_workspace (void) { }
+
+    virtual void do_set_history (const string_vector& /*hist*/) { }
+
+    virtual void do_append_history (const std::string& /*hist_entry*/) { }
+
+    virtual void do_clear_history (void) { }
+
+    virtual void do_pre_input_event (void) { }
+
+    virtual void do_post_input_event (void) { }
+
+    virtual void
+    do_enter_debugger_event (const std::string& /*file*/, int /*line*/) { }
+
+    virtual void
+    do_execute_in_debugger_event (const std::string& /*file*/, int /*line*/) { }
+
+    virtual void do_exit_debugger_event (void) { }
+
+    virtual void do_update_breakpoint (bool /*insert*/,
+                                       const std::string& /*file*/,
+                                       int /*line*/, const std::string& /*cond*/)
+    { }
+
+    virtual void do_show_preferences (void) { }
+
+    virtual std::string do_gui_preference (const std::string& /*key*/,
+                                           const std::string& /*value*/)
+    {
+      return "";
+    }
+
+    virtual void do_show_doc (const std::string& /*file*/) { }
+
+    virtual void do_register_doc (const std::string& /*file*/) { }
+
+    virtual void do_unregister_doc (const std::string& /*file*/) { }
+
+    virtual void do_edit_variable (const std::string& /*name*/,
+                                   const octave_value& /*val*/)
+    { }
+  };
+
+  //! Provides threadsafe access to octave.
+  //! @author Jacob Dawid
+  //!
+  //! This class is a wrapper around octave and provides thread safety by
+  //! buffering access operations to octave and executing them in the
+  //! readline event hook, which lives in the octave thread.
+
+  class
+  OCTINTERP_API
+  event_manager
+  {
+    public:
+
+    event_manager (void);
+
+    // No copying!
+
+    event_manager (const event_manager&) = delete;
+
+    event_manager&
+    operator = (const event_manager&) = delete;
+
+    virtual ~event_manager (void);
+
+    // OBJ should be an object of a class that is derived from the base
+    // class interpreter_events, or nullptr to disconnect and delete the
+    // previous link.
+
+    void connect_link (const std::shared_ptr<interpreter_events>& obj);
+
+    bool enable (void);
+
+    bool disable (void)
+    {
+      bool retval = link_enabled;
+      link_enabled = false;
+      return retval;
+    }
+
+    bool enabled (void) const
+    {
+      return link_enabled;
+    }
+
+    // If disable is TRUE, then no additional events will be processed
+    // other than exit.
+
+    void process_events (bool disable = false);
+
+    void discard_events (void);
+
+    bool confirm_shutdown (void)
+    {
+      bool retval = true;
+
+      if (enabled ())
+        retval = instance->do_confirm_shutdown ();
+
+      return retval;
+    }
+
+    template <typename F, typename... Args>
+    void post_event (F&& fcn, Args&&... args)
+    {
+      if (enabled ())
+        gui_event_queue.add (fcn, std::forward<Args> (args)...);
+    }
+
+    template <typename T, typename... Params, typename... Args>
+    void post_event (T *obj, void (T::*method) (Params...), Args&&... args)
+    {
+      if (enabled ())
+        gui_event_queue.add_method (obj, method, std::forward<Args> (args)...);
+    }
+
+    void post_exception (const std::exception_ptr& p)
+    {
+      if (enabled ())
+        post_event (this, &event_manager::rethrow_exception_callback, p);
+    }
+
+    bool copy_image_to_clipboard (const std::string& file)
+    {
+      return enabled () ? instance->do_copy_image_to_clipboard (file) : false;
+    }
+
+    bool edit_file (const std::string& file)
+    {
+      return enabled () ? instance->do_edit_file (file) : false;
+    }
+
+    bool prompt_new_edit_file (const std::string& file)
+    {
+      return enabled () ? instance->do_prompt_new_edit_file (file) : false;
+    }
+
+    std::string
+    question_dialog (const std::string& msg, const std::string& title,
+                     const std::string& btn1, const std::string& btn2,
+                     const std::string& btn3, const std::string& btndef)
+    {
+      return enabled () ? instance->do_question_dialog (msg, title, btn1,
+                                                        btn2, btn3, btndef) : "";
+    }
+
+    std::pair<std::list<int>, int>
+    list_dialog (const std::list<std::string>& list,
+                 const std::string& mode,
+                 int width, int height,
+                 const std::list<int>& initial_value,
+                 const std::string& name,
+                 const std::list<std::string>& prompt,
+                 const std::string& ok_string,
+                 const std::string& cancel_string)
+    {
+      return (enabled ()
+              ? instance->do_list_dialog (list, mode, width, height,
+                                          initial_value, name, prompt,
+                                          ok_string, cancel_string)
+              : std::pair<std::list<int>, int> ());
+    }
+
+    std::list<std::string>
+    input_dialog (const std::list<std::string>& prompt,
+                  const std::string& title,
+                  const std::list<float>& nr,
+                  const std::list<float>& nc,
+                  const std::list<std::string>& defaults)
+    {
+      return (enabled ()
+              ? instance->do_input_dialog (prompt, title, nr, nc, defaults)
+              : std::list<std::string> ());
+    }
+
+    typedef std::list<std::pair<std::string, std::string>> filter_list;
+
+    std::list<std::string>
+    file_dialog (const filter_list& filter, const std::string& title,
+                 const std::string& filename, const std::string& dirname,
+                 const std::string& multimode)
+    {
+      return (enabled ()
+              ? instance->do_file_dialog (filter, title, filename, dirname,
+                                          multimode)
+              : std::list<std::string> ());
+    }
+
+    int debug_cd_or_addpath_error (const std::string& file,
+                                   const std::string& dir, bool addpath_option)
+    {
+      return (enabled ()
+              ? instance->do_debug_cd_or_addpath_error (file, dir, addpath_option)
+              : 0);
+    }
+
+    void change_directory (const std::string& dir)
+    {
+      if (enabled ())
+        instance->do_change_directory (dir);
+    }
+
+    // Methods for removing/renaming files which might be open in editor
+    void file_remove (const std::string& old_name, const std::string& new_name)
+    {
+      if (octave::application::is_gui_running () && enabled ())
+        instance->do_file_remove (old_name, new_name);
+    }
+
+    void file_renamed (bool load_new)
+    {
+      if (octave::application::is_gui_running () && enabled ())
+        instance->do_file_renamed (load_new);
+    }
+
+    // Preserves pending input.
+    void execute_command_in_terminal (const std::string& command)
+    {
+      if (enabled ())
+        instance->do_execute_command_in_terminal (command);
+    }
+
+    uint8NDArray get_named_icon (const std::string& icon_name)
+    {
+      return (enabled () ?
+              instance->do_get_named_icon (icon_name) : uint8NDArray ());
+    }
+
+    void set_workspace (void);
+
+    void set_workspace (bool top_level, const octave::symbol_info_list& syminfo,
+                        bool update_variable_editor = true)
+    {
+      if (enabled ())
+        instance->do_set_workspace (top_level, debugging, syminfo,
+                                    update_variable_editor);
+    }
+
+    void clear_workspace (void)
+    {
+      if (enabled ())
+        instance->do_clear_workspace ();
+    }
+
+    void set_history (const string_vector& hist)
+    {
+      if (enabled ())
+        instance->do_set_history (hist);
+    }
+
+    void append_history (const std::string& hist_entry)
+    {
+      if (enabled ())
+        instance->do_append_history (hist_entry);
+    }
+
+    void clear_history (void)
+    {
+      if (enabled ())
+        instance->do_clear_history ();
+    }
+
+    void pre_input_event (void)
+    {
+      if (enabled ())
+        instance->do_pre_input_event ();
+    }
+
+    void post_input_event (void)
+    {
+      if (enabled ())
+        instance->do_post_input_event ();
+    }
+
+    void enter_debugger_event (const std::string& file, int line)
+    {
+      if (enabled ())
+        {
+          debugging = true;
+
+          instance->do_enter_debugger_event (file, line);
+        }
+    }
+
+    void execute_in_debugger_event (const std::string& file, int line)
+    {
+      if (enabled ())
+        instance->do_execute_in_debugger_event (file, line);
+    }
+
+    void exit_debugger_event (void)
+    {
+      if (enabled () && debugging)
+        {
+          debugging = false;
+
+          instance->do_exit_debugger_event ();
+        }
+    }
+
+    void update_breakpoint (bool insert, const std::string& file,
+                            int line, const std::string& cond = "")
+    {
+      if (enabled ())
+        instance->do_update_breakpoint (insert, file, line, cond);
+    }
+
+    bool show_preferences (void)
+    {
+      if (enabled ())
+        {
+          instance->do_show_preferences ();
+          return true;
+        }
+      else
+        return false;
+    }
+
+    std::string gui_preference (const std::string& key, const std::string& value)
+    {
+      if (enabled ())
+        {
+          return instance->do_gui_preference (key, value);
+        }
+      else
+        return "";
+    }
+
+    bool show_doc (const std::string& file)
+    {
+      if (enabled ())
+        {
+          instance->do_show_doc (file);
+          return true;
+        }
+      else
+        return false;
+    }
+
+    bool register_doc (const std::string& file)
+    {
+      if (enabled ())
+        {
+          instance->do_register_doc (file);
+          return true;
+        }
+      else
+        return false;
+    }
+
+    bool unregister_doc (const std::string& file)
+    {
+      if (enabled ())
+        {
+          instance->do_unregister_doc (file);
+          return true;
+        }
+      else
+        return false;
+
+    }
+
+    bool edit_variable (const std::string& name, const octave_value& val)
+    {
+      if (enabled ())
+        {
+          instance->do_edit_variable (name, val);
+          return true;
+        }
+      else
+        return false;
+    }
+
+    private:
+
+    // Using a shared_ptr to manage the link_events object ensures that it
+    // will be valid until it is no longer needed.
+
+    std::shared_ptr<interpreter_events> instance;
+
+    protected:
+
+    // Semaphore to lock access to the event queue.
+    octave::mutex *event_queue_mutex;
+
+    // Event Queue.
+    octave::event_queue gui_event_queue;
+
+    bool debugging;
+    bool link_enabled;
+
+    void rethrow_exception_callback (const std::exception_ptr& p)
+    {
+      std::rethrow_exception (p);
+    }
+  };
+}
+
+#endif