- also used by the GUI launcher for the same.
}
}
+// generated by 'wc -l' on the uncompressed file
+const unsigned int LINES_IN_APT_DAT = 2465648;
namespace flightgear
{
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 )
}
NavDataCache* cache = NavDataCache::instance();
+
string ident;
while ( metar_in ) {
metar_in >> ident;
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();
}
}
#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"
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;
if (done) {
++idle_state;
fgSplashProgress("init-scenery");
- } else {
- fgSplashProgress("loading-nav-dat");
}
-
} else if ( idle_state == 4 ) {
idle_state++;
public:
RebuildThread(NavDataCache* cache) :
_cache(cache),
+ _phase(NavDataCache::REBUILD_UNKNOWN),
+ _completionPercent(0),
_isFinished(false)
{
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;
};
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 {
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);
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());
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());
*/
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);
namespace flightgear
{
+
+const unsigned int LINES_IN_FIX_DAT = 119724;
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;
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;
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)
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;
namespace flightgear
{
+ const int LINES_IN_POI_DAT = 769019;
+
static PositionedID readPOIFromStream(std::istream& aStream, NavDataCache* cache,
FGPositioned::Type type = FGPositioned::INVALID)
{
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;
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("");
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;
/** 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();