# HG changeset patch # User John W. Eaton # Date 1347512635 14400 # Node ID eec0d1fcba4f070e6de36dc56a3fb91a8ca04aeb # Parent 8355fddce8152e9afe4abf0c07a74a06da7ade52 use Octave singleton style for octave_link class * octave-link.h, octave-link.cc (class octave_link): Update style to match other singleton classes in Octave. Change all uses. * history-dockwidget.cc, file-editor-tab.cc, main-window.cc, octave-link.cc, workspace-model.cc: Change all uses. diff --git a/libgui/src/history-dockwidget.cc b/libgui/src/history-dockwidget.cc --- a/libgui/src/history-dockwidget.cc +++ b/libgui/src/history-dockwidget.cc @@ -161,8 +161,7 @@ void history_dock_widget::request_history_model_update () { - octave_link::instance () - ->post_event (new octave_update_history_event (*this)); + octave_link::post_event (new octave_update_history_event (*this)); } void diff --git a/libgui/src/m-editor/file-editor-tab.cc b/libgui/src/m-editor/file-editor-tab.cc --- a/libgui/src/m-editor/file-editor-tab.cc +++ b/libgui/src/m-editor/file-editor-tab.cc @@ -312,11 +312,9 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::instance ()->post_event - (new octave_add_breakpoint_event (*this, - path.toStdString (), - function_name.toStdString (), - line)); + octave_link::post_event (new octave_add_breakpoint_event + (*this, path.toStdString (), + function_name.toStdString (), line)); } void @@ -329,11 +327,9 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::instance ()->post_event - (new octave_remove_breakpoint_event (*this, - path.toStdString (), - function_name.toStdString (), - line)); + octave_link::post_event (new octave_remove_breakpoint_event + (*this, path.toStdString (), + function_name.toStdString (), line)); } void @@ -501,10 +497,9 @@ // We have to cut off the suffix, because octave appends it. function_name.chop (file_info.suffix ().length () + 1); - octave_link::instance ()->post_event - (new octave_remove_all_breakpoints_event (*this, - path.toStdString (), - function_name.toStdString ())); + octave_link::post_event (new octave_remove_all_breakpoints_event + (*this, path.toStdString (), + function_name.toStdString ())); } void @@ -713,7 +708,7 @@ if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) { QString directory = QString::fromStdString - (octave_link::instance ()->get_last_working_directory ()); + (octave_link::last_working_directory ()); if (directory.isEmpty ()) { @@ -751,8 +746,8 @@ QFileInfo file_info (_file_name); QString path = file_info.absolutePath (); - //QString current_path = QString::fromStdString - (octave_link::instance ()->get_last_working_directory ()); + QString current_path + = QString::fromStdString (octave_link::last_working_directory ()); QString function_name = file_info.fileName (); // We have to cut off the suffix, because octave appends it. @@ -760,8 +755,8 @@ _file_editor->terminal ()->sendText (QString ("cd \'%1\'\n%2\n") .arg(path).arg (function_name)); // TODO: Sending a run event crashes for long scripts. Find out why. - // octave_link::instance () - // ->post_event (new octave_run_file_event (*this, _file_name.toStdString ())); + // octave_link::post_event (new octave_run_file_event + // (*this, _file_name.toStdString ())); } void diff --git a/libgui/src/main-window.cc b/libgui/src/main-window.cc --- a/libgui/src/main-window.cc +++ b/libgui/src/main-window.cc @@ -46,7 +46,7 @@ { // We have to set up all our windows, before we finally launch octave. construct (); - octave_link::instance ()->launch_octave(); + octave_link::launch_octave (); } main_window::~main_window () @@ -105,9 +105,8 @@ resource_manager::get_home_path ()); if (!selectedFile.isEmpty ()) { - octave_link::instance () - ->post_event (new octave_save_workspace_event (*this, - selectedFile.toStdString())); + octave_link::post_event (new octave_save_workspace_event + (*this, selectedFile.toStdString ())); } } @@ -119,24 +118,21 @@ resource_manager::get_home_path ()); if (!selectedFile.isEmpty ()) { - octave_link::instance () - ->post_event (new octave_load_workspace_event (*this, - selectedFile.toStdString())); + octave_link::post_event (new octave_load_workspace_event + (*this, selectedFile.toStdString ())); } } void main_window::handle_clear_workspace_request () { - octave_link::instance () - ->post_event (new octave_clear_workspace_event (*this)); + octave_link::post_event (new octave_clear_workspace_event (*this)); } void main_window::handle_clear_history_request() { - octave_link::instance () - ->post_event (new octave_clear_history_event (*this)); + octave_link::post_event (new octave_clear_history_event (*this)); } void @@ -237,18 +233,16 @@ if (!selectedDirectory.isEmpty ()) { - octave_link::instance () - ->post_event (new octave_change_directory_event (*this, - selectedDirectory.toStdString ())); + octave_link::post_event (new octave_change_directory_event + (*this, selectedDirectory.toStdString ())); } } void main_window::set_current_working_directory (const QString& directory) { - octave_link::instance () - ->post_event (new octave_change_directory_event (*this, - directory.toStdString ())); + octave_link::post_event (new octave_change_directory_event + (*this, directory.toStdString ())); } void @@ -366,36 +360,31 @@ void main_window::debug_continue () { - octave_link::instance () - ->post_event (new octave_debug_continue_event (*this)); + octave_link::post_event (new octave_debug_continue_event (*this)); } void main_window::debug_step_into () { - octave_link::instance () - ->post_event (new octave_debug_step_into_event (*this)); + octave_link::post_event (new octave_debug_step_into_event (*this)); } void main_window::debug_step_over () { - octave_link::instance () - ->post_event (new octave_debug_step_over_event (*this)); + octave_link::post_event (new octave_debug_step_over_event (*this)); } void main_window::debug_step_out () { - octave_link::instance () - ->post_event (new octave_debug_step_out_event (*this)); + octave_link::post_event (new octave_debug_step_out_event (*this)); } void main_window::debug_quit () { - octave_link::instance () - ->post_event (new octave_debug_quit_event (*this)); + octave_link::post_event (new octave_debug_quit_event (*this)); } void @@ -425,7 +414,7 @@ main_window::closeEvent (QCloseEvent *e) { e->ignore (); - octave_link::instance ()->post_event (new octave_exit_event (*this)); + octave_link::post_event (new octave_exit_event (*this)); } void @@ -888,7 +877,7 @@ read_settings (); _octave_qt_event_listener = new octave_qt_event_listener (); - octave_link::instance ()->register_event_listener (_octave_qt_event_listener); + octave_link::register_event_listener (_octave_qt_event_listener); connect (_octave_qt_event_listener, SIGNAL (current_directory_has_changed_signal (QString)), diff --git a/libgui/src/octave-adapter/octave-link.cc b/libgui/src/octave-adapter/octave-link.cc --- a/libgui/src/octave-adapter/octave-link.cc +++ b/libgui/src/octave-adapter/octave-link.cc @@ -28,140 +28,165 @@ #include "cmd-edit.h" #include "oct-env.h" #include "oct-mutex.h" +#include "singleton-cleanup.h" #include "symtab.h" #include "toplev.h" #include "octave-link.h" -int octave_readline_hook () +static int +octave_readline_hook (void) { - octave_link::instance ()->entered_readline_hook (); - octave_link::instance ()->generate_events (); - octave_link::instance ()->process_events (); - octave_link::instance ()->finished_readline_hook (); + octave_link::entered_readline_hook (); + octave_link::generate_events (); + octave_link::process_events (); + octave_link::finished_readline_hook (); + return 0; } -void octave_exit_hook (int status) +static void +octave_exit_hook (int) { - (void) status; - octave_link::instance ()->about_to_exit (); + octave_link::about_to_exit (); } -octave_link octave_link::_singleton; +octave_link *octave_link::instance = 0; -octave_link::octave_link () +octave_link::octave_link (void) + : event_listener (0), event_queue_mutex (new octave_mutex ()), + event_queue (), last_cwd (), debugging (false) +{ } + +void +octave_link::do_launch_octave (void) { - _event_queue_mutex = new octave_mutex (); - _last_working_directory = ""; - _debugging_mode_active = false; -} + // Create both threads. + main_thread = new octave_main_thread (); + + command_editor::add_event_hook (octave_readline_hook); -octave_link::~octave_link () -{ + octave_exit = octave_exit_hook; + + // Start the first one. + main_thread->start (); } void -octave_link::launch_octave () +octave_link::do_register_event_listener (octave_event_listener *el) { - // Create both threads. - _octave_main_thread = new octave_main_thread (); - command_editor::add_event_hook (octave_readline_hook); - octave_exit = octave_exit_hook; - - // Start the first one. - _octave_main_thread->start (); + event_listener = el; } void -octave_link::register_event_listener (octave_event_listener *oel) -{ _octave_event_listener = oel; } - -void -octave_link::generate_events () +octave_link::do_generate_events (void) { std::string current_working_directory = octave_env::get_current_directory (); - if (current_working_directory != _last_working_directory) + + if (current_working_directory != last_cwd) { - _last_working_directory = current_working_directory; - if (_octave_event_listener) - _octave_event_listener - ->current_directory_has_changed (_last_working_directory); + last_cwd = current_working_directory; + + if (event_listener) + event_listener->current_directory_has_changed (last_cwd); } - if (_debugging_mode_active != Vdebugging) + if (debugging != Vdebugging) { - _debugging_mode_active = Vdebugging; - if (_octave_event_listener) + debugging = Vdebugging; + + if (event_listener) { - if (_debugging_mode_active) - _octave_event_listener->entered_debug_mode (); + if (debugging) + event_listener->entered_debug_mode (); else - _octave_event_listener->quit_debug_mode (); + event_listener->quit_debug_mode (); } } } void -octave_link::process_events () +octave_link::do_process_events (void) { - _event_queue_mutex->lock (); + event_queue_mutex->lock (); - while (_event_queue.size () > 0) + while (event_queue.size () > 0) { - octave_event * e = _event_queue.front (); - _event_queue.pop (); + octave_event *e = event_queue.front (); + + event_queue.pop (); + if (e->perform ()) e->accept (); else e->reject (); } - _event_queue_mutex->unlock (); + + event_queue_mutex->unlock (); +} + +void +octave_link::do_post_event (octave_event *e) +{ + if (e) + { + event_queue_mutex->lock (); + event_queue.push (e); + event_queue_mutex->unlock (); + } } void -octave_link::post_event (octave_event *e) +octave_link::do_about_to_exit (void) { - if (e) - { - _event_queue_mutex->lock (); - _event_queue.push (e); - _event_queue_mutex->unlock (); - } + event_queue_mutex->lock (); + + while (! event_queue.empty ()) + event_queue.pop (); + + event_queue_mutex->unlock (); + + if (event_listener) + event_listener->about_to_exit (); +} + +std::string +octave_link::do_last_working_directory (void) +{ + return last_cwd; } void octave_link::event_accepted (octave_event *e) -{ delete e; } +{ + delete e; +} void octave_link::event_reject (octave_event *e) -{ delete e; } - -void -octave_link::about_to_exit () { - _event_queue_mutex->lock (); - while (!_event_queue.empty ()) - _event_queue.pop (); - - _event_queue_mutex->unlock (); - - if (_octave_event_listener) - _octave_event_listener->about_to_exit (); + delete e; } -void -octave_link::entered_readline_hook () -{ } - -void -octave_link::finished_readline_hook () +bool +octave_link::instance_ok (void) { -} + bool retval = true; + + if (! instance) + { + instance = new octave_link (); + + if (instance) + singleton_cleanup_list::add (cleanup_instance); + } -std::string -octave_link::get_last_working_directory () -{ - return _last_working_directory; + if (! instance) + { + ::error ("unable to create octave_link object!"); + + retval = false; + } + + return retval; } diff --git a/libgui/src/octave-adapter/octave-link.h b/libgui/src/octave-adapter/octave-link.h --- a/libgui/src/octave-adapter/octave-link.h +++ b/libgui/src/octave-adapter/octave-link.h @@ -34,61 +34,124 @@ #include "octave-event-observer.h" #include "octave-event-listener.h" -/** - * \class OctaveLink - * \brief Provides threadsafe access to octave. - * \author Jacob Dawid - * This class is a wrapper around octave and provides threadsafety by - * buffering access operations to octave and executing them in the readline - * event hook, which lives in the octave thread. - */ +// \class OctaveLink +// \brief 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 octave_link : public octave_event_observer { +protected: + + octave_link (void); + public: - /** Provides a way to access the unique octave_link object. */ - static octave_link * instance () { return &_singleton; } + + ~octave_link (void) { } + + static void launch_octave (void) + { + if (instance_ok ()) + instance->do_launch_octave (); + } + + static void register_event_listener (octave_event_listener *el) + { + if (instance_ok ()) + instance->do_register_event_listener (el); + } + + static void generate_events (void) + { + if (instance_ok ()) + instance->do_generate_events (); + } + + static void process_events (void) + { + if (instance_ok ()) + instance->do_process_events (); + } + + static void post_event (octave_event *e) + { + if (instance_ok ()) + instance->do_post_event (e); + } + + static void about_to_exit (void) + { + if (instance_ok ()) + instance->do_about_to_exit (); + } + + static void entered_readline_hook (void) + { + if (instance_ok ()) + instance->do_entered_readline_hook (); + } - /** Starts octave. */ - void launch_octave (); - void register_event_listener (octave_event_listener *oel); + static void finished_readline_hook (void) + { + if (instance_ok ()) + instance->do_finished_readline_hook (); + } + + static std::string last_working_directory (void) + { + return instance_ok () + ? instance->do_last_working_directory () : std::string (); + } + +private: + + static octave_link *instance; + + static void cleanup_instance (void) { delete instance; instance = 0; } + + // No copying! + + octave_link (const octave_link&); + + octave_link& operator = (const octave_link&); + + static bool instance_ok (void); + + octave_event_listener *event_listener; - void generate_events (); - void process_events (); - void post_event (octave_event *e); + // Thread running octave_main. + octave_main_thread *main_thread; + + // Semaphore to lock access to the event queue. + octave_mutex *event_queue_mutex; + + // Buffer for queueing events until they will be processed. + std::queue event_queue; + + // Stores the last known current working directory of octave. + std::string last_cwd; + + bool debugging; + + void do_launch_octave (void); + void do_register_event_listener (octave_event_listener *oel); + + void do_generate_events (void); + void do_process_events (void); + void do_post_event (octave_event *e); + + void do_about_to_exit (void); + + void do_entered_readline_hook (void) { } + void do_finished_readline_hook (void) { } + + std::string do_last_working_directory (void); + void event_accepted (octave_event *e); void event_reject (octave_event *e); - - void about_to_exit (); - - void entered_readline_hook (); - void finished_readline_hook (); - - std::string get_last_working_directory (); - -private: - /** Singleton. */ - octave_link (); - ~octave_link (); - - octave_event_listener *_octave_event_listener; - - /** Thread running octave_main. */ - octave_main_thread *_octave_main_thread; +}; - /** Semaphore to lock access to the event queue. */ - octave_mutex *_event_queue_mutex; - - /** Buffer for queueing events until they will be processed. */ - std::queue _event_queue; - - /** Stores the last known current working directory of octave. */ - std::string _last_working_directory; - bool _debugging_mode_active; - - /** Semaphore to lock access to the performance information. */ - octave_mutex *_performance_information_mutex; - - /** Unique instance. Singelton! */ - static octave_link _singleton; -}; #endif // OCTAVELINK_H diff --git a/libgui/src/workspace-model.cc b/libgui/src/workspace-model.cc --- a/libgui/src/workspace-model.cc +++ b/libgui/src/workspace-model.cc @@ -63,8 +63,7 @@ void workspace_model::request_update_workspace () { - octave_link::instance () - ->post_event (new octave_update_workspace_event (*this)); + octave_link::post_event (new octave_update_workspace_event (*this)); } void