changeset 14671:f346343654a4 gui

Settings readline event hook and fixed race condition. * WorkspaceModel: Decoupled writing and reading the symbol table. * OctaveLink: Added timer to periodically query for symbol table changes.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Tue, 22 May 2012 17:29:34 +0200
parents 7fbea449737d
children 7b607001d571
files gui/src/WorkspaceModel.cpp gui/src/WorkspaceModel.h gui/src/backend/OctaveLink.cpp gui/src/backend/OctaveLink.h
diffstat 4 files changed, 50 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/gui/src/WorkspaceModel.cpp	Tue May 22 13:04:24 2012 +0200
+++ b/gui/src/WorkspaceModel.cpp	Tue May 22 17:29:34 2012 +0200
@@ -25,6 +25,7 @@
   QList<QVariant> rootData;
   rootData << tr ("Name") << tr ("Type") << tr ("Value");
   _rootItem = new TreeItem(rootData);
+  _cachedSymbolTableSemaphore = new QSemaphore (1);
 }
 
 WorkspaceModel::~WorkspaceModel()
@@ -135,26 +136,34 @@
   return item->data(index.column());
 }
 
+
 void
-WorkspaceModel::updateTreeEntry (TreeItem * treeItem, symbol_table::symbol_record *symbolRecord)
+WorkspaceModel::cacheSymbolTable ()
 {
-  treeItem->setData (0, QString (symbolRecord->name ().c_str ()));
-  treeItem->setData (1, QString (symbolRecord->varval ().type_name ().c_str ()));
-  treeItem->setData (2, octaveValueAsQString (symbolRecord->varval ()));
+  std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables ();
+
+  _cachedSymbolTableSemaphore->acquire (1);
+  _cachedSymbolTable.clear();
+  for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin ();
+       iterator != symbolTable.end (); iterator++)
+    {
+      _cachedSymbolTable.push_back((*iterator).dup(symbol_table::global_scope()));
+    }
+  _cachedSymbolTableSemaphore->release (1);
 }
 
 void
 WorkspaceModel::updateFromSymbolTable ()
 {
-  std::list < symbol_table::symbol_record > allVariables = symbol_table::all_variables ();
   // Split the symbol table into its different categories.
   QList < symbol_table::symbol_record* > localSymbolTable;
   QList < symbol_table::symbol_record* > globalSymbolTable;
   QList < symbol_table::symbol_record* > persistentSymbolTable;
   QList < symbol_table::symbol_record* > hiddenSymbolTable;
 
-  for (std::list < symbol_table::symbol_record > ::iterator iterator = allVariables.begin ();
-       iterator != allVariables.end (); iterator++)
+  _cachedSymbolTableSemaphore->acquire (1);
+  for (std::list < symbol_table::symbol_record > ::iterator iterator = _cachedSymbolTable.begin ();
+       iterator != _cachedSymbolTable.end (); iterator++)
     {
       // It's true that being global or hidden includes it's can mean it's also locally visible,
       // but we want to distinguish that here.
@@ -183,8 +192,8 @@
   updateCategory (1, globalSymbolTable);
   updateCategory (2, persistentSymbolTable);
   updateCategory (3, hiddenSymbolTable);
+ _cachedSymbolTableSemaphore->release (1);
   reset();
-
   emit expandRequest();
 }
 
@@ -192,6 +201,8 @@
 WorkspaceModel::updateCategory (int topLevelItemIndex, const QList < symbol_table::symbol_record* > &symbolTable)
 {
   TreeItem *treeItem = topLevelItem (topLevelItemIndex);
+
+  QModelIndex mi = index(treeItem->row(), 0);
   treeItem->deleteChildItems();
 
   int symbolTableSize = symbolTable.size ();
@@ -203,6 +214,14 @@
     }
 }
 
+void
+WorkspaceModel::updateTreeEntry (TreeItem * treeItem, symbol_table::symbol_record *symbolRecord)
+{
+  treeItem->setData (0, QString (symbolRecord->name ().c_str ()));
+  treeItem->setData (1, QString (symbolRecord->varval ().type_name ().c_str ()));
+  treeItem->setData (2, octaveValueAsQString (symbolRecord->varval ()));
+}
+
 QString
 WorkspaceModel::octaveValueAsQString (const octave_value& octaveValue)
 {
--- a/gui/src/WorkspaceModel.h	Tue May 22 13:04:24 2012 +0200
+++ b/gui/src/WorkspaceModel.h	Tue May 22 17:29:34 2012 +0200
@@ -57,6 +57,7 @@
 // Qt includes
 #include <QAbstractItemModel>
 #include <QVector>
+#include <QSemaphore>
 
 class TreeItem
 {
@@ -158,15 +159,21 @@
   void insertTopLevelItem (int at, TreeItem *treeItem);
   TreeItem *topLevelItem (int at);
 
-  void updateFromSymbolTable ();
+
+  void cacheSymbolTable ();
   void updateTreeEntry (TreeItem * treeItem, symbol_table::symbol_record *symbolRecord);
   void updateCategory (int topLevelItemIndex, const QList < symbol_table::symbol_record *> &symbolTable);
   QString octaveValueAsQString (const octave_value &octaveValue);
 
+public slots:
+  void updateFromSymbolTable ();
+
 signals:
   void expandRequest();
 
 private:
+  QSemaphore *_cachedSymbolTableSemaphore;
+  std::list < symbol_table::symbol_record > _cachedSymbolTable;
   TreeItem *_rootItem;
 };
 
--- a/gui/src/backend/OctaveLink.cpp	Tue May 22 13:04:24 2012 +0200
+++ b/gui/src/backend/OctaveLink.cpp	Tue May 22 17:29:34 2012 +0200
@@ -17,13 +17,13 @@
 
 #include "OctaveLink.h"
 
-void octave_loop_hook_impl()
+int update_hook_impl()
 {
   OctaveLink::instance()->triggerUpdateHistoryModel();
-  OctaveLink::instance()->triggerUpdateSymbolTable();
+  OctaveLink::instance()->triggerCacheSymbolTable();
+  return 0;
 }
 
-
 OctaveLink OctaveLink::m_singleton;
 
 OctaveLink::OctaveLink ():QObject ()
@@ -35,6 +35,11 @@
   m_workspaceModel->insertTopLevelItem(1, new TreeItem ("Global"));
   m_workspaceModel->insertTopLevelItem(2, new TreeItem ("Persistent"));
   m_workspaceModel->insertTopLevelItem(3, new TreeItem ("Hidden"));
+
+  _updateWorkspaceModelTimer.setInterval (1000);
+  _updateWorkspaceModelTimer.setSingleShot (false);
+  connect(&_updateWorkspaceModelTimer, SIGNAL (timeout ()),
+    m_workspaceModel, SLOT (updateFromSymbolTable ()));
 }
 
 OctaveLink::~OctaveLink ()
@@ -46,9 +51,10 @@
 {
   // Create both threads.
   m_octaveMainThread = new OctaveMainThread (this);
-  octave_loop_hook = octave_loop_hook_impl;
+  command_editor::add_event_hook(update_hook_impl);
   // Start the first one.
   m_octaveMainThread->start ();
+  _updateWorkspaceModelTimer.start ();
 }
 
 void
@@ -78,9 +84,9 @@
 }
 
 void
-OctaveLink::triggerUpdateSymbolTable ()
+OctaveLink::triggerCacheSymbolTable ()
 {
-  m_workspaceModel->updateFromSymbolTable();
+  m_workspaceModel->cacheSymbolTable();
 }
 
 QStringListModel *
--- a/gui/src/backend/OctaveLink.h	Tue May 22 13:04:24 2012 +0200
+++ b/gui/src/backend/OctaveLink.h	Tue May 22 17:29:34 2012 +0200
@@ -71,6 +71,7 @@
 #include <QSemaphore>
 #include <QObject>
 #include <QStringListModel>
+#include <QTimer>
 
 #include "WorkspaceModel.h"
 #include "OctaveMainThread.h"
@@ -95,7 +96,7 @@
   WorkspaceModel *workspaceModel ();
 
   void triggerUpdateHistoryModel ();
-  void triggerUpdateSymbolTable ();
+  void triggerCacheSymbolTable ();
 
 private:
   OctaveLink ();
@@ -106,6 +107,7 @@
 
   // Threads for running octave and managing the data interaction.
   OctaveMainThread *m_octaveMainThread;
+  QTimer _updateWorkspaceModelTimer;
 
   static OctaveLink m_singleton;
 };