]> git.mxchange.org Git - flightgear.git/commitdiff
Percentage feedback during nav-cache build.
authorJames Turner <zakalawe@mac.com>
Thu, 19 Mar 2015 17:01:38 +0000 (12:01 -0500)
committerJames Turner <zakalawe@mac.com>
Thu, 19 Mar 2015 17:01:38 +0000 (12:01 -0500)
- also used by the GUI launcher for the same.

src/Airports/apt_loader.cxx
src/GUI/QtLauncher.cxx
src/Main/fg_init.cxx
src/Main/main.cxx
src/Navaids/NavDataCache.cxx
src/Navaids/NavDataCache.hxx
src/Navaids/fixlist.cxx
src/Navaids/navdb.cxx
src/Navaids/poidb.cxx
src/Viewer/splash.cxx
src/Viewer/splash.hxx

index f2f3b712076fcbc9e013fbd560671165d5cbf5a0..4d159d7fc0128ee026caf0342d3b0df90c18ebc4 100644 (file)
@@ -67,6 +67,8 @@ static FGPositioned::Type fptypeFromRobinType(int aType)
   }
 }
 
+// generated by 'wc -l' on the uncompressed file
+const unsigned int LINES_IN_APT_DAT = 2465648;
 
 namespace flightgear
 {
@@ -109,6 +111,12 @@ public:
         continue;
       }
 
+        if ((line_num % 100) == 0) {
+            // every 100 lines
+            unsigned int percent = (line_num * 100) / LINES_IN_APT_DAT;
+            cache->setRebuildPhaseProgress(NavDataCache::REBUILD_AIRPORTS, percent);
+        }
+
       if (line.size() >= 3) {
           char *p = (char *)memchr(tmp, ' ', 3);
           if ( p )
@@ -557,6 +565,7 @@ bool metarDataLoad(const SGPath& metar_file)
   }
   
   NavDataCache* cache = NavDataCache::instance();
+
   string ident;
   while ( metar_in ) {
     metar_in >> ident;
index 86eb19e3a63e2c7dbb285ef0a52e357f83d256f9..d36ca2fc5dc55eef889b616cd0d3e68fc76268f0 100644 (file)
@@ -72,18 +72,52 @@ namespace { // anonymous namespace
 
 void initNavCache()
 {
+    QString baseLabel = QT_TR_NOOP("Initialising navigation data, this may take several minutes");
     NavDataCache* cache = NavDataCache::createInstance();
     if (cache->isRebuildRequired()) {
-        QProgressDialog rebuildProgress("Initialising navigation data, this may take several minutes",
+        QProgressDialog rebuildProgress(baseLabel,
                                        QString() /* cancel text */,
-                                       0, 0);
+                                       0, 100);
         rebuildProgress.setWindowModality(Qt::WindowModal);
         rebuildProgress.show();
 
-        while (!cache->rebuild()) {
+        NavDataCache::RebuildPhase phase = cache->rebuild();
+
+        while (phase != NavDataCache::REBUILD_DONE) {
             // sleep to give the rebuild thread more time
             SGTimeStamp::sleepForMSec(50);
-            rebuildProgress.setValue(0);
+            phase = cache->rebuild();
+            
+            switch (phase) {
+            case NavDataCache::REBUILD_AIRPORTS:
+                rebuildProgress.setLabelText(QT_TR_NOOP("Loading airport data"));
+                break;
+
+            case NavDataCache::REBUILD_FIXES:
+                rebuildProgress.setLabelText(QT_TR_NOOP("Loading waypoint data"));
+                break;
+
+            case NavDataCache::REBUILD_NAVAIDS:
+                rebuildProgress.setLabelText(QT_TR_NOOP("Loading navigation data"));
+                break;
+
+
+            case NavDataCache::REBUILD_POIS:
+                rebuildProgress.setLabelText(QT_TR_NOOP("Loading point-of-interest data"));
+                break;
+
+            default:
+                rebuildProgress.setLabelText(baseLabel);
+            }
+
+            if (phase == NavDataCache::REBUILD_UNKNOWN) {
+                rebuildProgress.setValue(0);
+                rebuildProgress.setMaximum(0);
+            } else {
+                rebuildProgress.setValue(cache->rebuildPhaseCompletionPercentage());
+                rebuildProgress.setMaximum(100);
+            }
+
             QCoreApplication::processEvents();
         }
     }
index 9604f2a591b54560a363fc27b8f082da0ab7b0a7..e7b391862f3ea52c785d8f7dbe9a5a7d00461e91 100644 (file)
 #include <Network/fgcom.hxx>
 #include <Network/http/httpd.hxx>
 #include <Include/version.h>
-
+#include <Viewer/splash.hxx>
 #include <Viewer/CameraGroup.hxx>
 
 #include "fg_init.hxx"
@@ -592,9 +592,23 @@ fgInitNav ()
         doingRebuild = cache->isRebuildRequired();
     }
 
+    static const char* splashIdentsByRebuildPhase[] = {
+        "loading-nav-dat",
+        "navdata-airports",
+        "navdata-navaids",
+        "navdata-fixes",
+        "navdata-pois"
+    };
+
     if (doingRebuild) {
-        bool finished = cache->rebuild();
-        if (!finished) {
+        flightgear::NavDataCache::RebuildPhase phase;
+        phase = cache->rebuild();
+        if (phase != flightgear::NavDataCache::REBUILD_DONE) {
+            // update the splash text based on percentage, phase
+
+            fgSplashProgress(splashIdentsByRebuildPhase[phase],
+                             cache->rebuildPhaseCompletionPercentage());
+
             // sleep to give the rebuild thread more time
             SGTimeStamp::sleepForMSec(50);
             return false;
index d6ab4c5635d2e93f0f976c4285c64042a5a28a0b..30edd654eac4676ba39621eefa915c33a1b1d91b 100644 (file)
@@ -221,10 +221,7 @@ static void fgIdleFunction ( void ) {
         if (done) {
           ++idle_state;
           fgSplashProgress("init-scenery");
-        } else {
-          fgSplashProgress("loading-nav-dat");
         }
-      
     } else if ( idle_state == 4 ) {
         idle_state++;
 
index 1a5b696ab36635515b2357625f413ac249653006..1746ece4e3a091b27149e8e537b2ef23d0dc6813 100644 (file)
@@ -162,6 +162,8 @@ class RebuildThread : public SGThread
 public:
   RebuildThread(NavDataCache* cache) :
   _cache(cache),
+    _phase(NavDataCache::REBUILD_UNKNOWN),
+    _completionPercent(0),
   _isFinished(false)
   {
     
@@ -182,9 +184,36 @@ public:
     
     SGGuard<SGMutex> g(_lock);
     _isFinished = true;
+    _phase = NavDataCache::REBUILD_DONE;
   }
+
+    NavDataCache::RebuildPhase currentPhase() const
+    {
+        NavDataCache::RebuildPhase ph;
+        SGGuard<SGMutex> g(_lock);
+        ph = _phase;
+        return ph;
+    }
+
+    unsigned int completionPercent() const
+    {
+        unsigned int perc = 0;
+        SGGuard<SGMutex> g(_lock);
+        perc = _completionPercent;
+        return perc;
+    }
+
+    void setProgress(NavDataCache::RebuildPhase ph, unsigned int percent)
+    {
+        SGGuard<SGMutex> g(_lock);
+        _phase = ph;
+        _completionPercent = percent;
+    }
+
 private:
   NavDataCache* _cache;
+    NavDataCache::RebuildPhase _phase;
+    unsigned int _completionPercent;
   mutable SGMutex _lock;
   bool _isFinished;
 };
@@ -1184,21 +1213,39 @@ bool NavDataCache::dropGroundnetsIfRequired()
     return false;
 }
   
-bool NavDataCache::rebuild()
+NavDataCache::RebuildPhase NavDataCache::rebuild()
 {
-  if (!d->rebuilder.get()) {
-    d->rebuilder.reset(new RebuildThread(this));
-    d->rebuilder->start();
-  }
-  
-// poll the rebuild thread
-  bool fin = d->rebuilder->isFinished();
-  if (fin) {
-    d->rebuilder.reset(); // all done!
-  }
-  return fin;
+    if (!d->rebuilder.get()) {
+        d->rebuilder.reset(new RebuildThread(this));
+        d->rebuilder->start();
+    }
+
+    // poll the rebuild thread
+    RebuildPhase phase = d->rebuilder->currentPhase();
+    if (phase == REBUILD_DONE) {
+        d->rebuilder.reset(); // all done!
+    }
+    return phase;
 }
-  
+
+unsigned int NavDataCache::rebuildPhaseCompletionPercentage() const
+{
+    if (!d->rebuilder.get()) {
+        return 0;
+    }
+
+    return d->rebuilder->completionPercent();
+}
+
+void NavDataCache::setRebuildPhaseProgress(RebuildPhase ph, unsigned int percent)
+{
+    if (!d->rebuilder.get()) {
+        return;
+    }
+
+    d->rebuilder->setProgress(ph, percent);
+}
+
 void NavDataCache::doRebuild()
 {
   try {
@@ -1216,7 +1263,8 @@ void NavDataCache::doRebuild()
         st.stamp();
         airportDBLoad(d->aptDatPath);
         SG_LOG(SG_NAVCACHE, SG_INFO, "apt.dat load took:" << st.elapsedMSec());
-        
+
+        setRebuildPhaseProgress(REBUILD_UNKNOWN);
         metarDataLoad(d->metarDatPath);
         stampCacheFile(d->aptDatPath);
         stampCacheFile(d->metarDatPath);
@@ -1230,7 +1278,8 @@ void NavDataCache::doRebuild()
         navDBInit(d->navDatPath);
         stampCacheFile(d->navDatPath);
         SG_LOG(SG_NAVCACHE, SG_INFO, "nav.dat load took:" << st.elapsedMSec());
-        
+
+        setRebuildPhaseProgress(REBUILD_UNKNOWN);
         st.stamp();
         txn.commit();
         SG_LOG(SG_NAVCACHE, SG_INFO, "stage 1 commit took:" << st.elapsedMSec());
@@ -1246,7 +1295,8 @@ void NavDataCache::doRebuild()
           poiDBInit(d->poiDatPath);
           stampCacheFile(d->poiDatPath);
           SG_LOG(SG_NAVCACHE, SG_INFO, "poi.dat load took:" << st.elapsedMSec());
-          
+
+          setRebuildPhaseProgress(REBUILD_UNKNOWN);
           st.stamp();
           txn.commit();
           SG_LOG(SG_NAVCACHE, SG_INFO, "POI commit took:" << st.elapsedMSec());
index 47220d073bcb5280f5ce30e8e357d7b603cc9e24..5c8bbbc8abb2805fdc1b2200df60151569e0df60 100644 (file)
@@ -76,12 +76,24 @@ public:
      */
   bool dropGroundnetsIfRequired();
 
+    enum RebuildPhase
+    {
+        REBUILD_UNKNOWN = 0,
+        REBUILD_AIRPORTS,
+        REBUILD_NAVAIDS,
+        REBUILD_FIXES,
+        REBUILD_POIS,
+        REBUILD_DONE
+    };
+
   /**
-   * run the cache rebuild - returns true if rebuild is complete,
-   * otherwise keep going.
+   * run the cache rebuild - returns the current phase or 'done'
    */
-  bool rebuild();
-  
+  RebuildPhase rebuild();
+
+    unsigned int rebuildPhaseCompletionPercentage() const;
+    void setRebuildPhaseProgress(RebuildPhase ph, unsigned int percent = 0);
+
   bool isCachedFileModified(const SGPath& path) const;
   void stampCacheFile(const SGPath& path);
   
index 27ece574481156ef4b39014916b264e179554b16..c665b1de13c3707eaee22a692a48be1b256c1e98 100644 (file)
@@ -45,6 +45,8 @@ FGFix::FGFix(PositionedID aGuid, const std::string& aIdent, const SGGeod& aPos)
 
 namespace flightgear
 {
+
+const unsigned int LINES_IN_FIX_DAT = 119724;
   
 void loadFixes(const SGPath& path)
 {
@@ -58,7 +60,8 @@ void loadFixes(const SGPath& path)
   in >> skipeol;
   
   NavDataCache* cache = NavDataCache::instance();
-  
+  unsigned int lineNumber = 2;
+
   // read in each remaining line of the file
   while ( ! in.eof() ) {
     double lat, lon;
@@ -68,8 +71,15 @@ void loadFixes(const SGPath& path)
     
     cache->insertFix(ident, SGGeod::fromDeg(lon, lat));
     in >> skipcomment;
+
+      ++lineNumber;
+      if ((lineNumber % 100) == 0) {
+          // every 100 lines
+          unsigned int percent = (lineNumber * 100) / LINES_IN_FIX_DAT;
+          cache->setRebuildPhaseProgress(NavDataCache::REBUILD_FIXES, percent);
+      }
   }
 
 }
-  
+
 } // of namespace flightgear;
index 4b01c3ad6ff29688d9616d6c0aeceabbce191556..964d2b3cc96e480ea279aa5cc11de9e549c81bdb 100644 (file)
@@ -251,6 +251,9 @@ static PositionedID readNavFromStream(std::istream& aStream,
   
   return r;
 }
+
+// generated by wc -l on uncomrpessed nav.dat
+const unsigned int LINES_IN_NAV_DAT = 26775;
   
 // load and initialize the navigational databases
 bool navDBInit(const SGPath& path)
@@ -260,17 +263,27 @@ bool navDBInit(const SGPath& path)
         SG_LOG( SG_NAVAID, SG_ALERT, "Cannot open file: " << path.str() );
       return false;
     }
-  
+
   autoAlignLocalizers = fgGetBool("/sim/navdb/localizers/auto-align", true);
   autoAlignThreshold = fgGetDouble( "/sim/navdb/localizers/auto-align-threshold-deg", 5.0 );
+    NavDataCache* cache = NavDataCache::instance();
 
     // skip first two lines
     in >> skipeol;
     in >> skipeol;
+    unsigned int lineNumber = 2;
 
     while (!in.eof()) {
       readNavFromStream(in);
       in >> skipcomment;
+
+        ++lineNumber;
+        if ((lineNumber % 100) == 0) {
+            // every 100 lines
+            unsigned int percent = (lineNumber * 100) / LINES_IN_NAV_DAT;
+            cache->setRebuildPhaseProgress(NavDataCache::REBUILD_NAVAIDS, percent);
+        }
+
     } // of stream data loop
   
   return true;
index 15da16813305dbfc13a4acbe8a56e320d73a3639..8782f85d0127eb800426cacd3406600f4fd21f52 100644 (file)
@@ -52,6 +52,8 @@ mapPOITypeToFGPType(int aTy)
 namespace flightgear
 {
 
+    const int LINES_IN_POI_DAT = 769019;
+
 static PositionedID readPOIFromStream(std::istream& aStream, NavDataCache* cache,
                                         FGPositioned::Type type = FGPositioned::INVALID)
 {
@@ -96,9 +98,17 @@ bool poiDBInit(const SGPath& path)
       return false;
     }
 
+    unsigned int lineNumber = 0;
     NavDataCache* cache = NavDataCache::instance();
     while (!in.eof()) {
       readPOIFromStream(in, cache);
+
+        ++lineNumber;
+        if ((lineNumber % 100) == 0) {
+            // every 100 lines
+            unsigned int percent = (lineNumber * 100) / LINES_IN_POI_DAT;
+            cache->setRebuildPhaseProgress(NavDataCache::REBUILD_POIS, percent);
+        }
     } // of stream data loop
 
     return true;
index 03995c44f9a2086a2ea1a42bb4b1ebb1771e6041..99539c7356ae2fbbbc3e5c2f9218489c24294338 100644 (file)
@@ -385,7 +385,7 @@ void fgSplashInit () {
   globals->get_renderer()->splashinit();
 }
 
-void fgSplashProgress( const char *identifier ) {
+void fgSplashProgress( const char *identifier, unsigned int percent ) {
   const char* spinChars = "-\\|/";
   static int spin_count = 0;
   std::string spin_status = std::string("");
@@ -415,6 +415,13 @@ void fgSplashProgress( const char *identifier ) {
         fgSetString("/sim/startup/splash-progress-text", oss.str());
         return;
     }
+
+    // over-write the spinner
+    if (!strncmp(identifier, "navdata-", 8)) {
+        std::ostringstream oss;
+        oss << percent << "% complete";
+        fgSetString("/sim/startup/splash-progress-spinner", oss.str());
+    }
     
     if( fgGetString("/sim/startup/splash-progress-text") == text )
       return;
index d6c054dfb56c8dd01376a81b823d18f7ec088df8..cb1c219c5e143e1e0ccf90be36ed0332e6e1f0fa 100644 (file)
@@ -36,7 +36,7 @@ void fgSplashInit ();
 
 /** Set progress information.
  * "identifier" references an element of the language resource. */
-void fgSplashProgress ( const char *identifier );
+void fgSplashProgress ( const char *identifier, unsigned int percent = 0 );
 
 /** Retrieve the splash screen node */
 osg::Node* fgCreateSplashNode();