changeset 15372:eec0d1fcba4f

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.
author John W. Eaton <jwe@octave.org>
date Thu, 13 Sep 2012 01:03:55 -0400
parents 8355fddce815
children bff950876af5
files libgui/src/history-dockwidget.cc libgui/src/m-editor/file-editor-tab.cc libgui/src/main-window.cc libgui/src/octave-adapter/octave-link.cc libgui/src/octave-adapter/octave-link.h libgui/src/workspace-model.cc
diffstat 6 files changed, 248 insertions(+), 178 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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
--- 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)),
--- 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;
 }
--- 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 <octave_event *> 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 <octave_event *> _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
--- 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