Mercurial > octave
changeset 27260:5ac60319575b
separate octave_link event queue from events and actions
* octave-link.h, octave-link.cc (octave_link_events): New class
containing the virtual functions from octave_link that are intended to
be overridden. The octave_link class now manages the queue of events
and provides static wrappers to call these event functions (or skip
calling them if the link is disabled).
(octave_link::event_queue_mutex, octave_link::gui_event_queue,
octave_link::debugging, octave_link::link_enabled): Now static.
Change all uses to match.
(octave_link::instance): Now pointer to octave_link_events object.
* octave-qt-link.h, octave-qt-link.cc (octave_qt_link_events):
Rename from octave_qt_link and derive from octave_link_events instead
of octave_link. Change all uses.
* interpreter-qobject.h, interpreter-qobject.cc
(interpreter_qobject::m_qt_link): Now pointer to
octave_qt_link_events. Change all uses to match.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 18 Jul 2019 01:15:21 -0400 |
parents | a42821748671 |
children | dccdc3b001a2 |
files | libgui/src/interpreter-qobject.cc libgui/src/interpreter-qobject.h libgui/src/m-editor/file-editor-tab.cc libgui/src/main-window.cc libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libinterp/corefcn/octave-link.cc libinterp/corefcn/octave-link.h |
diffstat | 8 files changed, 374 insertions(+), 330 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/interpreter-qobject.cc Thu Jul 18 00:08:07 2019 -0400 +++ b/libgui/src/interpreter-qobject.cc Thu Jul 18 01:15:21 2019 -0400 @@ -37,7 +37,7 @@ { interpreter_qobject::interpreter_qobject (base_qobject *oct_qobj) : QObject (), m_octave_qobject (oct_qobj), - m_qt_link (new octave_qt_link ()) + m_qt_link (new octave_qt_link_events ()) { octave_link::connect_link (m_qt_link);
--- a/libgui/src/interpreter-qobject.h Thu Jul 18 00:08:07 2019 -0400 +++ b/libgui/src/interpreter-qobject.h Thu Jul 18 01:15:21 2019 -0400 @@ -29,7 +29,7 @@ namespace octave { class base_qobject; - class octave_qt_link; + class octave_qt_link_events; class interpreter_qobject : public QObject { @@ -41,7 +41,7 @@ ~interpreter_qobject (void) = default; - octave_qt_link * qt_link (void) { return m_qt_link; } + octave_qt_link_events * qt_link (void) { return m_qt_link; } void confirm_shutdown (bool closenow); @@ -60,7 +60,7 @@ base_qobject *m_octave_qobject; - octave_qt_link *m_qt_link; + octave_qt_link_events *m_qt_link; }; }
--- a/libgui/src/m-editor/file-editor-tab.cc Thu Jul 18 00:08:07 2019 -0400 +++ b/libgui/src/m-editor/file-editor-tab.cc Thu Jul 18 01:15:21 2019 -0400 @@ -1113,7 +1113,7 @@ bp_table::intmap line_info; line_info[0] = info.line; - if (octave_qt_link::file_in_path (info.file, info.dir)) + if (octave_qt_link_events::file_in_path (info.file, info.dir)) { bp_table& bptab = __get_bp_table__ ("file_editor_tab::handle_request_remove_breakpoint"); @@ -1193,7 +1193,7 @@ octave_link::post_event ([info] (void) { - if (octave_qt_link::file_in_path (info.file, info.dir)) + if (octave_qt_link_events::file_in_path (info.file, info.dir)) { bp_table& bptab = __get_bp_table__ ("file_editor_tab::remove_all_breakpoints"); @@ -1325,7 +1325,7 @@ bp_table::intmap line_info; line_info[0] = info.line; - if (octave_qt_link::file_in_path (info.file, info.dir)) + if (octave_qt_link_events::file_in_path (info.file, info.dir)) { bp_table& bptab = __get_bp_table__ ("file_editor_tab::add_breakpoint_event");
--- a/libgui/src/main-window.cc Thu Jul 18 00:08:07 2019 -0400 +++ b/libgui/src/main-window.cc Thu Jul 18 01:15:21 2019 -0400 @@ -514,7 +514,7 @@ { interpreter_qobject *interp_qobj = m_octave_qobj.interpreter_qobj (); - octave_qt_link *qt_link = interp_qobj->qt_link (); + octave_qt_link_events *qt_link = interp_qobj->qt_link (); // Wait for worker to suspend qt_link->lock (); @@ -1046,7 +1046,7 @@ std::string path = info.absolutePath ().toStdString (); - if (octave_qt_link::file_in_path (file_path, path)) + if (octave_qt_link_events::file_in_path (file_path, path)) command_editor::replace_line (function_name.toStdString ()); } else @@ -1882,7 +1882,7 @@ interpreter_qobject *interp_qobj = m_octave_qobj.interpreter_qobj (); - octave_qt_link *qt_link = interp_qobj->qt_link (); + octave_qt_link_events *qt_link = interp_qobj->qt_link (); connect (qt_link, SIGNAL (edit_variable_signal (const QString&, @@ -2069,7 +2069,7 @@ { interpreter_qobject *interp_qobj = m_octave_qobj.interpreter_qobj (); - octave_qt_link *qt_link = interp_qobj->qt_link (); + octave_qt_link_events *qt_link = interp_qobj->qt_link (); connect (qt_link, SIGNAL (set_workspace_signal (bool, bool, const symbol_info_list&)), @@ -2674,7 +2674,7 @@ interpreter_qobject *interp_qobj = m_octave_qobj.interpreter_qobj (); - octave_qt_link *qt_link = interp_qobj->qt_link (); + octave_qt_link_events *qt_link = interp_qobj->qt_link (); // Wait for worker to suspend qt_link->lock ();
--- a/libgui/src/octave-qt-link.cc Thu Jul 18 00:08:07 2019 -0400 +++ b/libgui/src/octave-qt-link.cc Thu Jul 18 01:15:21 2019 -0400 @@ -54,14 +54,14 @@ namespace octave { - octave_qt_link::octave_qt_link (void) - : octave_link (), m_shutdown_confirm_result (false) + octave_qt_link_events::octave_qt_link_events (void) + : octave_link_events (), m_shutdown_confirm_result (false) { qRegisterMetaType<octave_value> ("octave_value"); qRegisterMetaType<symbol_info_list> ("symbol_info_list"); } - bool octave_qt_link::do_confirm_shutdown (void) + bool octave_qt_link_events::do_confirm_shutdown (void) { // Lock the mutex before emitting signal. lock (); @@ -78,21 +78,21 @@ return m_shutdown_confirm_result; } - bool octave_qt_link::do_copy_image_to_clipboard (const std::string& file) + bool octave_qt_link_events::do_copy_image_to_clipboard (const std::string& file) { emit copy_image_to_clipboard_signal (QString::fromStdString (file), true); return true; } - bool octave_qt_link::do_edit_file (const std::string& file) + bool octave_qt_link_events::do_edit_file (const std::string& file) { emit edit_file_signal (QString::fromStdString (file)); return true; } - bool octave_qt_link::do_prompt_new_edit_file (const std::string& file) + bool octave_qt_link_events::do_prompt_new_edit_file (const std::string& file) { QSettings *settings = resource_manager::get_settings (); @@ -126,7 +126,7 @@ return (answer == tr ("Create")); } - uint8NDArray octave_qt_link::do_get_named_icon (const std::string& icon_name) + uint8NDArray octave_qt_link_events::do_get_named_icon (const std::string& icon_name) { uint8NDArray retval; QIcon icon = resource_manager::icon (QString::fromStdString (icon_name)); @@ -152,7 +152,7 @@ return retval; } - std::string octave_qt_link::do_question_dialog (const std::string& msg, + std::string octave_qt_link_events::do_question_dialog (const std::string& msg, const std::string& title, const std::string& btn1, const std::string& btn2, @@ -237,7 +237,7 @@ } std::pair<std::list<int>, int> - octave_qt_link::do_list_dialog (const std::list<std::string>& list, + octave_qt_link_events::do_list_dialog (const std::list<std::string>& list, const std::string& mode, int width, int height, const std::list<int>& initial, @@ -272,7 +272,7 @@ } std::list<std::string> - octave_qt_link::do_input_dialog (const std::list<std::string>& prompt, + octave_qt_link_events::do_input_dialog (const std::list<std::string>& prompt, const std::string& title, const std::list<float>& nr, const std::list<float>& nc, @@ -305,7 +305,7 @@ } std::list<std::string> - octave_qt_link::do_file_dialog (const filter_list& filter, + octave_qt_link_events::do_file_dialog (const filter_list& filter, const std::string& title, const std::string& filename, const std::string& dirname, @@ -347,7 +347,7 @@ // This uses a QMessageBox unlike other functions in this file, // because uiwidget_creator.waitcondition.wait hangs when called from // file_editor_tab::handle_context_menu_break_condition(). (FIXME: why hang?) - int octave_qt_link::do_debug_cd_or_addpath_error (const std::string& file, + int octave_qt_link_events::do_debug_cd_or_addpath_error (const std::string& file, const std::string& dir, bool addpath_option) { @@ -400,12 +400,12 @@ return retval; } - void octave_qt_link::do_change_directory (const std::string& dir) + void octave_qt_link_events::do_change_directory (const std::string& dir) { emit change_directory_signal (QString::fromStdString (dir)); } - void octave_qt_link::do_file_remove (const std::string& old_name, + void octave_qt_link_events::do_file_remove (const std::string& old_name, const std::string& new_name) { // Lock the mutex before signaling @@ -420,18 +420,18 @@ unlock (); } - void octave_qt_link::do_file_renamed (bool load_new) + void octave_qt_link_events::do_file_renamed (bool load_new) { emit file_renamed_signal (load_new); } - void octave_qt_link::do_execute_command_in_terminal + void octave_qt_link_events::do_execute_command_in_terminal (const std::string& command) { emit execute_command_in_terminal_signal (QString::fromStdString (command)); } - void octave_qt_link::do_set_workspace (bool top_level, bool debug, + void octave_qt_link_events::do_set_workspace (bool top_level, bool debug, const symbol_info_list& syminfo, bool update_variable_editor) { @@ -444,12 +444,12 @@ emit refresh_variable_editor_signal (); } - void octave_qt_link::do_clear_workspace (void) + void octave_qt_link_events::do_clear_workspace (void) { emit clear_workspace_signal (); } - void octave_qt_link::do_set_history (const string_vector& hist) + void octave_qt_link_events::do_set_history (const string_vector& hist) { QStringList qt_hist; @@ -459,27 +459,27 @@ emit set_history_signal (qt_hist); } - void octave_qt_link::do_append_history (const std::string& hist_entry) + void octave_qt_link_events::do_append_history (const std::string& hist_entry) { emit append_history_signal (QString::fromStdString (hist_entry)); } - void octave_qt_link::do_clear_history (void) + void octave_qt_link_events::do_clear_history (void) { emit clear_history_signal (); } - void octave_qt_link::do_pre_input_event (void) + void octave_qt_link_events::do_pre_input_event (void) { } - void octave_qt_link::do_post_input_event (void) + void octave_qt_link_events::do_post_input_event (void) { } - void octave_qt_link::do_enter_debugger_event (const std::string& file, + void octave_qt_link_events::do_enter_debugger_event (const std::string& file, int line) { interpreter& interp = __get_interpreter__ ( - "octave_qt_link::do_enter_debugger_event"); + "octave_qt_link_events::do_enter_debugger_event"); octave_value_list fct = F__which__ (interp, ovl (file),0); octave_map map = fct(0).map_value (); @@ -492,20 +492,20 @@ emit enter_debugger_signal (); } - void octave_qt_link::do_execute_in_debugger_event (const std::string& file, + void octave_qt_link_events::do_execute_in_debugger_event (const std::string& file, int line) { do_delete_debugger_pointer (file, line); } - void octave_qt_link::do_exit_debugger_event (void) + void octave_qt_link_events::do_exit_debugger_event (void) { emit exit_debugger_signal (); } // Display (if @insert true) or remove the appropriate symbol for a breakpoint // in @file at @line with condition @cond. - void octave_qt_link::do_update_breakpoint (bool insert, + void octave_qt_link_events::do_update_breakpoint (bool insert, const std::string& file, int line, const std::string& cond) @@ -514,7 +514,52 @@ line, QString::fromStdString (cond)); } - bool octave_qt_link::file_in_path (const std::string& file, + void octave_qt_link_events::do_show_preferences (void) + { + emit show_preferences_signal (); + } + + std::string octave_qt_link_events::do_gui_preference (const std::string& key, + const std::string& value) + { + QString pref_value; + + // Lock the mutex before signaling + lock (); + + // Emit the signal for changing or getting a preference + emit gui_preference_signal (QString::fromStdString (key), + QString::fromStdString (value), &pref_value); + + // Wait for the GUI and unlock when resumed + wait (); + unlock (); + + return pref_value.toStdString (); + } + + void octave_qt_link_events::do_show_doc (const std::string& file) + { + emit show_doc_signal (QString::fromStdString (file)); + } + + void octave_qt_link_events::do_register_doc (const std::string& file) + { + emit register_doc_signal (QString::fromStdString (file)); + } + + void octave_qt_link_events::do_unregister_doc (const std::string& file) + { + emit unregister_doc_signal (QString::fromStdString (file)); + } + + void octave_qt_link_events::do_edit_variable (const std::string& expr, + const octave_value& val) + { + emit edit_variable_signal (QString::fromStdString (expr), val); + } + + bool octave_qt_link_events::file_in_path (const std::string& file, const std::string& dir) { @@ -527,7 +572,7 @@ ok = true; else { - load_path& lp = __get_load_path__ ("octave_qt_link::file_in_path"); + load_path& lp = __get_load_path__ ("octave_qt_link_events::file_in_path"); bool dir_in_load_path = lp.contains_canonical (dir); @@ -563,7 +608,7 @@ if (! ok) { - int action = debug_cd_or_addpath_error (file, dir, addpath_option); + int action = octave_link::debug_cd_or_addpath_error (file, dir, addpath_option); switch (action) { case 1: @@ -573,7 +618,7 @@ case 2: { - load_path& lp = __get_load_path__ ("octave_qt_link::file_in_path"); + load_path& lp = __get_load_path__ ("octave_qt_link_events::file_in_path"); lp.prepend (dir); ok = true; @@ -588,59 +633,14 @@ return ok; } - void octave_qt_link::do_show_preferences (void) - { - emit show_preferences_signal (); - } - - std::string octave_qt_link::do_gui_preference (const std::string& key, - const std::string& value) - { - QString pref_value; - - // Lock the mutex before signaling - lock (); - - // Emit the signal for changing or getting a preference - emit gui_preference_signal (QString::fromStdString (key), - QString::fromStdString (value), &pref_value); - - // Wait for the GUI and unlock when resumed - wait (); - unlock (); - - return pref_value.toStdString (); - } - - void octave_qt_link::do_show_doc (const std::string& file) - { - emit show_doc_signal (QString::fromStdString (file)); - } - - void octave_qt_link::do_register_doc (const std::string& file) - { - emit register_doc_signal (QString::fromStdString (file)); - } - - void octave_qt_link::do_unregister_doc (const std::string& file) - { - emit unregister_doc_signal (QString::fromStdString (file)); - } - - void octave_qt_link::do_edit_variable (const std::string& expr, - const octave_value& val) - { - emit edit_variable_signal (QString::fromStdString (expr), val); - } - - void octave_qt_link::do_insert_debugger_pointer (const std::string& file, - int line) + void octave_qt_link_events::do_insert_debugger_pointer (const std::string& file, + int line) { emit insert_debugger_pointer_signal (QString::fromStdString (file), line); } - void octave_qt_link::do_delete_debugger_pointer (const std::string& file, - int line) + void octave_qt_link_events::do_delete_debugger_pointer (const std::string& file, + int line) { emit delete_debugger_pointer_signal (QString::fromStdString (file), line); }
--- a/libgui/src/octave-qt-link.h Thu Jul 18 00:08:07 2019 -0400 +++ b/libgui/src/octave-qt-link.h Thu Jul 18 01:15:21 2019 -0400 @@ -50,27 +50,28 @@ //! buffering access operations to octave and executing them in the //! readline event hook, which lives in the octave thread. - class octave_qt_link : public QObject, public octave_link + class octave_qt_link_events : public QObject, public octave_link_events { Q_OBJECT public: - octave_qt_link (void); + octave_qt_link_events (void); // No copying! - octave_qt_link (const octave_qt_link&) = delete; + octave_qt_link_events (const octave_qt_link_events&) = delete; - octave_qt_link& operator = (const octave_qt_link&) = delete; + octave_qt_link_events& operator = (const octave_qt_link_events&) = delete; - ~octave_qt_link (void) = default; + ~octave_qt_link_events (void) = default; bool do_confirm_shutdown (void); bool do_copy_image_to_clipboard (const std::string& file); bool do_edit_file (const std::string& file); + bool do_prompt_new_edit_file (const std::string& file); std::string @@ -122,46 +123,58 @@ void do_clear_workspace (void); void do_set_history (const string_vector& hist); + void do_append_history (const std::string& hist_entry); + void do_clear_history (void); void do_pre_input_event (void); + void do_post_input_event (void); void do_enter_debugger_event (const std::string& file, int line); + void do_execute_in_debugger_event (const std::string& file, int line); + void do_exit_debugger_event (void); void do_update_breakpoint (bool insert, const std::string& file, int line, const std::string& cond); - static bool file_in_path (const std::string& file, const std::string& dir); - void do_show_preferences (void); std::string do_gui_preference (const std::string& key, const std::string& value); void do_show_doc (const std::string& file); + void do_register_doc (const std::string& file); + void do_unregister_doc (const std::string& file); void do_edit_variable (const std::string& name, const octave_value& val); void shutdown_confirmation (bool sd) { m_shutdown_confirm_result = sd; } + static bool file_in_path (const std::string& file, const std::string& dir); + void lock (void) { m_mutex.lock (); } + void wait (void) { m_waitcondition.wait (&m_mutex); } + void unlock (void) { m_mutex.unlock (); } + void wake_all (void) { m_waitcondition.wakeAll (); } private: void do_insert_debugger_pointer (const std::string& file, int line); + void do_delete_debugger_pointer (const std::string& file, int line); bool m_shutdown_confirm_result; QMutex m_mutex; + QWaitCondition m_waitcondition; signals: @@ -173,6 +186,7 @@ void change_directory_signal (const QString& dir); void file_remove_signal (const QString& old_name, const QString& new_name); + void file_renamed_signal (bool load_new); void execute_command_in_terminal_signal (const QString& command); @@ -183,16 +197,20 @@ void clear_workspace_signal (void); void set_history_signal (const QStringList& hist); + void append_history_signal (const QString& hist_entry); + void clear_history_signal (void); void enter_debugger_signal (void); + void exit_debugger_signal (void); void update_breakpoint_marker_signal (bool insert, const QString& file, int line, const QString& cond); void insert_debugger_pointer_signal (const QString&, int); + void delete_debugger_pointer_signal (const QString&, int); void show_preferences_signal (void);
--- a/libinterp/corefcn/octave-link.cc Thu Jul 18 00:08:07 2019 -0400 +++ b/libinterp/corefcn/octave-link.cc Thu Jul 18 01:15:21 2019 -0400 @@ -46,20 +46,85 @@ return 0; } -octave_link *octave_link::instance = nullptr; +octave_link_events *octave_link::instance = nullptr; + +octave::mutex *octave_link::event_queue_mutex = new octave::mutex (); + +octave::event_queue octave_link::gui_event_queue; + +bool octave_link::debugging = false; + +bool octave_link::link_enabled = true; octave_link::octave_link (void) - : event_queue_mutex (new octave::mutex ()), gui_event_queue (), - debugging (false), link_enabled (true) -{ - octave::command_editor::add_event_hook (octave_readline_hook); -} +{ } octave_link::~octave_link (void) { delete event_queue_mutex; } +// OBJ should be an object of a class that is derived from the base +// class octave_link, or 0 to disconnect the link. It is the +// responsibility of the caller to delete obj. + +void +octave_link::connect_link (octave_link_events *obj) +{ + if (obj && instance) + error ("octave_link is already linked!"); + + instance = obj; + + octave::command_editor::add_event_hook (octave_readline_hook); +} + +octave_link_events * +octave_link::disconnect_link (bool delete_instance) +{ + if (delete_instance) + { + delete instance; + instance = nullptr; + return nullptr; + } + else + { + octave_link_events *retval = instance; + instance = nullptr; + return retval; + } +} + +void +octave_link::process_events (bool disable_flag) +{ + if (enabled ()) + { + if (disable_flag) + disable (); + + event_queue_mutex->lock (); + + gui_event_queue.run (); + + event_queue_mutex->unlock (); + } +} + +void +octave_link::discard_events (void) +{ + if (enabled ()) + { + event_queue_mutex->lock (); + + gui_event_queue.discard (); + + event_queue_mutex->unlock (); + } +} + void octave_link::set_workspace (void) { @@ -68,45 +133,11 @@ octave::tree_evaluator& tw = octave::__get_evaluator__ ("octave_link::set_workspace"); - instance->do_set_workspace (tw.at_top_level (), - instance->debugging, + instance->do_set_workspace (tw.at_top_level (), debugging, tw.get_symbol_info (), true); } } -// OBJ should be an object of a class that is derived from the base -// class octave_link, or 0 to disconnect the link. It is the -// responsibility of the caller to delete obj. - -void -octave_link::connect_link (octave_link *obj) -{ - if (obj && instance) - error ("octave_link is already linked!"); - - instance = obj; -} - -void -octave_link::do_process_events (void) -{ - event_queue_mutex->lock (); - - gui_event_queue.run (); - - event_queue_mutex->unlock (); -} - -void -octave_link::do_discard_events (void) -{ - event_queue_mutex->lock (); - - gui_event_queue.discard (); - - event_queue_mutex->unlock (); -} - DEFUN (__octave_link_enabled__, , , doc: /* -*- texinfo -*- @deftypefn {} {} __octave_link_enabled__ ()
--- a/libinterp/corefcn/octave-link.h Thu Jul 18 00:08:07 2019 -0400 +++ b/libinterp/corefcn/octave-link.h Thu Jul 18 01:15:21 2019 -0400 @@ -43,6 +43,152 @@ class symbol_info_list; } +class +octave_link_events +{ +public: + + octave_link_events (void) = default; + + octave_link_events (const octave_link_events&) = default; + + octave_link_events& operator = (const octave_link_events&) = default; + + virtual ~octave_link_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 //! @@ -68,25 +214,35 @@ virtual ~octave_link (void); + static void connect_link (octave_link_events *obj); + + static octave_link_events * disconnect_link (bool delete_instance = true); + + static bool enable (void) + { + bool retval = link_enabled; + link_enabled = true; + return retval; + } + + static bool disable (void) + { + bool retval = link_enabled; + link_enabled = false; + return retval; + } + + static bool enabled (void) + { + return link_enabled; + } + // If disable is TRUE, then no additional events will be processed // other than exit. - static void process_events (bool disable = false) - { - if (enabled ()) - { - if (disable) - instance->do_disable (); + static void process_events (bool disable_arg = false); - instance->do_process_events (); - } - } - - static void discard_events (void) - { - if (enabled ()) - instance->do_discard_events (); - } + static void discard_events (void); static bool confirm_shutdown (void) { @@ -103,7 +259,7 @@ post_event (F&& fcn, Args&&... args) { if (enabled ()) - instance->do_post_event (fcn, std::forward<Args> (args)...); + gui_event_queue.add (fcn, std::forward<Args> (args)...); } template <typename T, typename... Params, typename... Args> @@ -111,14 +267,14 @@ post_event (T *obj, void (T::*method) (Params...), Args&&... args) { if (enabled ()) - instance->do_post_event (obj, method, std::forward<Args> (args)...); + gui_event_queue.add_method (obj, method, std::forward<Args> (args)...); } static void post_exception (const std::exception_ptr &p) { if (enabled ()) - instance->do_post_exception (p); + post_event (&octave_link::rethrow_exception_callback, p); } static bool @@ -240,7 +396,7 @@ bool update_variable_editor = true) { if (enabled ()) - instance->do_set_workspace (top_level, instance->debugging, syminfo, + instance->do_set_workspace (top_level, debugging, syminfo, update_variable_editor); } @@ -284,7 +440,7 @@ { if (enabled ()) { - instance->debugging = true; + debugging = true; instance->do_enter_debugger_event (file, line); } @@ -298,9 +454,9 @@ static void exit_debugger_event (void) { - if (enabled () && instance->debugging) + if (enabled () && debugging) { - instance->debugging = false; + debugging = false; instance->do_exit_debugger_event (); } @@ -314,53 +470,6 @@ instance->do_update_breakpoint (insert, file, line, cond); } - static void connect_link (octave_link *); - - static octave_link * disconnect_link (bool delete_instance = true) - { - if (delete_instance) - { - delete instance; - instance = nullptr; - return nullptr; - } - else - { - octave_link *retval = instance; - instance = nullptr; - return retval; - } - } - - static bool enable (void) - { - return instance_ok () ? instance->do_enable () : false; - } - - static bool disable (void) - { - return instance_ok () ? instance->do_disable () : false; - } - - bool do_enable (void) - { - bool retval = link_enabled; - link_enabled = true; - return retval; - } - - bool do_disable (void) - { - bool retval = link_enabled; - link_enabled = false; - return retval; - } - - static bool enabled (void) - { - return instance_ok () ? instance->link_enabled : false; - } - static bool show_preferences () { @@ -436,139 +545,25 @@ private: - static octave_link *instance; + static octave_link_events *instance; static bool instance_ok (void) { return instance != nullptr; } protected: // Semaphore to lock access to the event queue. - octave::mutex *event_queue_mutex; + static octave::mutex *event_queue_mutex; // Event Queue. - octave::event_queue gui_event_queue; - - bool debugging; - bool link_enabled; - - void do_process_events (void); - void do_discard_events (void); + static octave::event_queue gui_event_queue; - template <typename F, typename... Args> - void do_post_event (F&& fcn, Args&&... args) - { - gui_event_queue.add (fcn, std::forward<Args> (args)...); - } + static bool debugging; + static bool link_enabled; - template <typename T, typename... Params, typename... Args> - void do_post_event (T *obj, void (T::*method) (Params...), Args&&... args) - { - gui_event_queue.add_method (obj, method, std::forward<Args> (args)...); - } - - void - rethrow_exception_callback (const std::exception_ptr &p) + static void rethrow_exception_callback (const std::exception_ptr &p) { std::rethrow_exception (p); } - - void - do_post_exception (const std::exception_ptr &p) - { - do_post_event (this, &octave_link::rethrow_exception_callback, p); - } - - void do_entered_readline_hook (void) { } - void do_finished_readline_hook (void) { } - - virtual bool do_confirm_shutdown (void) = 0; - - virtual bool do_copy_image_to_clipboard (const std::string& file) = 0; - - virtual bool do_edit_file (const std::string& file) = 0; - virtual bool do_prompt_new_edit_file (const std::string& file) = 0; - 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) = 0; - - 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) = 0; - - 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) = 0; - - 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) = 0; - - virtual int - do_debug_cd_or_addpath_error (const std::string& file, - const std::string& dir, - bool addpath_option) = 0; - - virtual void do_change_directory (const std::string& dir) = 0; - - virtual void do_file_remove (const std::string& old_name, - const std::string& new_name) = 0; - virtual void do_file_renamed (bool) = 0; - - virtual void do_execute_command_in_terminal (const std::string& command) = 0; - - virtual uint8NDArray - do_get_named_icon (const std::string& icon_name) = 0; - - virtual void - do_set_workspace (bool top_level, bool debug, - const octave::symbol_info_list& syminfo, - bool update_variable_editor) = 0; - - virtual void do_clear_workspace (void) = 0; - - virtual void do_set_history (const string_vector& hist) = 0; - virtual void do_append_history (const std::string& hist_entry) = 0; - virtual void do_clear_history (void) = 0; - - virtual void do_pre_input_event (void) = 0; - virtual void do_post_input_event (void) = 0; - - virtual void - do_enter_debugger_event (const std::string& file, int line) = 0; - - virtual void - do_execute_in_debugger_event (const std::string& file, int line) = 0; - - virtual void do_exit_debugger_event (void) = 0; - - virtual void do_update_breakpoint (bool insert, - const std::string& file, int line, - const std::string& cond) = 0; - - virtual void do_show_preferences (void) = 0; - - virtual std::string do_gui_preference (const std::string& key, - const std::string& value) = 0; - - virtual void do_show_doc (const std::string& file) = 0; - - virtual void do_register_doc (const std::string& file) = 0; - - virtual void do_unregister_doc (const std::string& file) = 0; - - virtual void - do_edit_variable (const std::string& name, const octave_value& val) = 0; }; #endif