[dasher: 16/43] Gtk2: only update lock dialogue/display at 10fps to leave CPU free to train!



commit a5b1bc92265c203d00c3f841283d38cfeceb1f70
Author: Alan Lawrence <acl33 inf phy cam ac uk>
Date:   Wed Apr 20 19:08:59 2011 +0100

    Gtk2: only update lock dialogue/display at 10fps to leave CPU free to train!

 Src/Gtk2/DasherControl.cpp        |    8 +++---
 Src/Gtk2/GtkDasherControl.h       |    4 +-
 Src/Gtk2/dasher_lock_dialogue.cpp |   48 +++++++++++++++++++++++++-----------
 3 files changed, 39 insertions(+), 21 deletions(-)
---
diff --git a/Src/Gtk2/DasherControl.cpp b/Src/Gtk2/DasherControl.cpp
index 58c3895..acc2821 100644
--- a/Src/Gtk2/DasherControl.cpp
+++ b/Src/Gtk2/DasherControl.cpp
@@ -373,13 +373,13 @@ void CDasherControl::ExternalEventHandler(Dasher::CEvent *pEvent) {
 void CDasherControl::SetLockStatus(const string &strText, int iPercent) {
     DasherLockInfo sInfo;
     sInfo.szMessage = strText.c_str();
-    sInfo.bLock = (iPercent!=-1);
     sInfo.iPercent = iPercent;
+    sInfo.time = get_time();
 
-    g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_lock_info", &sInfo);
-    //No frames seem to be rendered, so this is probably unnecessary.
-    // But call through to superclass anyway:
+    //Uniquely, the call to gtk to handle events and update the progress
+    // dialogue, also renders the canvas. So let's have a message there too...
     CDasherInterfaceBase::SetLockStatus(strText,iPercent);
+    g_signal_emit_by_name(GTK_WIDGET(m_pDasherControl), "dasher_lock_info", &sInfo);
 }
 
 unsigned int CDasherControl::ctrlMove(bool bForwards, CControlManager::EditDistance dist) {
diff --git a/Src/Gtk2/GtkDasherControl.h b/Src/Gtk2/GtkDasherControl.h
index af59972..da074f5 100644
--- a/Src/Gtk2/GtkDasherControl.h
+++ b/Src/Gtk2/GtkDasherControl.h
@@ -15,8 +15,8 @@ typedef struct _DasherLockInfo DasherLockInfo;
 
 struct _DasherLockInfo {
   const gchar *szMessage;
-  gboolean bLock;
-  gint iPercent;
+  gint iPercent; //-1 = unlock, anything else = locked
+  unsigned long time;
 };
 
 typedef struct _DasherMessageInfo DasherMessageInfo;
diff --git a/Src/Gtk2/dasher_lock_dialogue.cpp b/Src/Gtk2/dasher_lock_dialogue.cpp
index ae49619..f0ac184 100644
--- a/Src/Gtk2/dasher_lock_dialogue.cpp
+++ b/Src/Gtk2/dasher_lock_dialogue.cpp
@@ -16,12 +16,14 @@
 GtkWindow *m_pLockWindow;
 GtkProgressBar *m_pLockProgress;
 GtkLabel *m_pLockMessage;
+unsigned long lastTime;
 
 void dasher_lock_dialogue_new(GtkBuilder *pXML, GtkWindow *pMainWindow) {
 #ifndef WITH_MAEMO
   m_pLockWindow = GTK_WINDOW(gtk_builder_get_object(pXML, "lock_window"));
   m_pLockProgress = GTK_PROGRESS_BAR(gtk_builder_get_object(pXML, "lock_progress"));
   m_pLockMessage = GTK_LABEL(gtk_builder_get_object(pXML, "lock_message"));
+  lastTime=0;
 
   gtk_widget_hide(GTK_WIDGET(m_pLockWindow));
   
@@ -35,32 +37,48 @@ extern "C" void on_lock_info(GtkDasherControl *pDasherControl, gpointer pLockInf
   // TODO: signals are connected after the Dasher control is created,
   // which is too late to receive notification about intial training
   // etc.
-
   DasherLockInfo *pInfo = (DasherLockInfo *)pLockInfo;
 
+  //Whether to perform a full refresh of GUI components (too expensive to do every time):
+  bool bFullRefresh(pInfo->time-lastTime > 100);
 #ifndef WITH_MAEMO
-  gtk_label_set_text(m_pLockMessage, pInfo->szMessage);
-  gtk_progress_bar_set_fraction(m_pLockProgress, pInfo->iPercent / 100.0);
-
-  if(pInfo->bLock)
-    gtk_widget_show(GTK_WIDGET(m_pLockWindow));
-  else
-    gtk_widget_hide(GTK_WIDGET(m_pLockWindow));
+  GtkWidget *pWinWidget(GTK_WIDGET(m_pLockWindow));
+  if(pInfo->iPercent!=-1) {
+    gtk_label_set_text(m_pLockMessage, pInfo->szMessage);
+    gtk_progress_bar_set_fraction(m_pLockProgress, pInfo->iPercent / 100.0);
+    if (!gtk_widget_get_visible(pWinWidget)) {
+      bFullRefresh = true;
+      gtk_widget_show(pWinWidget);
+    }
+  }
+  else if (gtk_widget_get_visible(pWinWidget)) {
+    bFullRefresh = true;
+    gtk_widget_hide(pWinWidget);
+  }
 #else
-  if(pInfo->bLock) {
-    if(!m_pLockWindow)
+  if(pInfo->iPercent!=-1) {
+    if(!m_pLockWindow) {
+      bFullRefresh = true;
       m_pLockWindow = hildon_banner_show_progress(NULL, NULL, pInfo->szMessage);
-
+    }
     hildon_banner_set_fraction(HILDON_BANNER(m_pLockWindow), pInfo->iPercent / 100.0);
   }
   else {
-    if(m_pLockWindow)
+    if(m_pLockWindow) {
+      bFullRefresh = true;
       gtk_widget_destroy(GTK_WIDGET(m_pLockWindow));
+    }
     m_pLockWindow = 0;
   }
 #endif
 
-  // Keep the GTK interface responsive
-  while(gtk_events_pending())
-    gtk_main_iteration();
+  if (bFullRefresh) {
+    //This takes too long, on some hardware / software versions, to perform every time
+    // (or else training takes much longer than without progress display!), but we do
+    // it every so often to ensure the progress display is visible onscreen.
+    // (I've measured it at 40+ iterations upon show() of progress dialogue! and averages 5-6)
+    while(gtk_events_pending())
+        gtk_main_iteration();
+      lastTime=pInfo->time;
+  }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]