1
0
Fork 0

Percentage feedback during nav-cache build.

- also used by the GUI launcher for the same.
This commit is contained in:
James Turner 2015-03-19 12:01:38 -05:00
parent 2ebf21221d
commit e0274af493
11 changed files with 191 additions and 35 deletions

View 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;

View 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();
}
}

View file

@ -129,7 +129,7 @@
#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;

View 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++;

View 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,19 +1213,37 @@ 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();
}
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;
// 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()
@ -1217,6 +1264,7 @@ void NavDataCache::doRebuild()
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);
@ -1231,6 +1279,7 @@ void NavDataCache::doRebuild()
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());
@ -1247,6 +1296,7 @@ void NavDataCache::doRebuild()
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());

View file

@ -76,11 +76,23 @@ 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);

View file

@ -46,6 +46,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)
{
sg_gzifstream in( path.str() );
@ -58,6 +60,7 @@ 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() ) {
@ -68,6 +71,13 @@ 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);
}
}
}

View file

@ -252,6 +252,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)
{
@ -263,14 +266,24 @@ bool navDBInit(const SGPath& path)
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;

View 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;

View 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("");
@ -416,6 +416,13 @@ void fgSplashProgress( const char *identifier ) {
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;

View 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();