This very first query was left un-finalized, which apparently blocks
another process from obtaining the exclusive lock needed to
COMMIT. Found using the trace funtions, phew.
Sentry-Id: FLIGHTGEAR-8C
Sentry-Id: FLIGHTGEAR-8F
If impatient users start multiple copies of FlightGear when a cache
rebuild is required, we can get into a mess. Use an additional
named mutex on Windows to avoid this situation, and block the secondary
copies until the primary instance has completed its cache rebuild.
Sentry-Id: FLIGHTGEAR-8D
Sentry-Id: FLIGHTGEAR-FY
- Use a range-based for loop instead of an iterator.
- Don't bother checking if the previously-visited directory was the
same: the potential saving that the previous code was hoping should be
null because FGGlobals::append_fg_scenery() doesn't add a path to
FGGlobals::fg_scenery if it's already there---this assumes that all
paths added to FGGlobals::fg_scenery go through
FGGlobals::append_fg_scenery(), of course.
This should have no effect on FG's behavior.
Adjust the special NavCache function used for airport search, to
allow filtering by type (which is exposed in an upcoming patch to the
dialog code).
Patch by Daniel Wickstrom
Add better airway support, fix various issues with VIA, and add
parsing / generation of ICAO route strings. Also fix the
serialisation of flight-plans with airway enroute segments, so these
can be restored correctly.
Before SimGear commit a962c90b30f36575d01162b64471fa77473237a0,
SGPath::pathListSep was a char in static memory that was not necessarily
followed by '\0'. As a consequence, using &SGPath::pathListSep as a
C-style string could result in a string containing the correct separator
*plus* whatever followed in memory until the first null byte...
SimGear commit a962c90b30 changes this situation by making
SGPath::pathListSep an array of two const chars: the path list separator
followed by a '\0'.
This commit simply adapts FlightGear to this change, which fixes a
couple of bugs where the separator was used, mainly unneeded NavCache
rebuilds due to the "apt.dat", "fix.dat" and "nav.dat" properties in the
SQLite database containing the correct paths separated by a possibly
incorrect separator string (there was no alteration of the cache
contents as far as I can tell, since the db property is only used to
check if the lists of apt.dat, fix.dat and nav.dat files have changed).
- Rename fatalMessageBox() to fatalMessageBoxWithoutExit(). This should
prevent the kind of bug that prompted this set of changes: someone
calling fatalMessageBox(), assuming the program would stop at that
point, whereas in reality it did not.
- Add new function fatalMessageBoxThenExit(). This is not vital of
course, but allows one to spare one line here and there and to apply
the DRY principle for such fatal exits.
- Replace every existing call to fatalMessageBox() with one or the other
of the two new functions. Improve formatting along the way. This
fixes a few bugs of the kind explained above.
- The 'DatFilesGroupInfo' struct and 'DatFileType' enum are now public
members of 'NavDataCache'.
- New public method NavDataCache::getDatFilesInfo() returning the
'DatFilesGroupInfo' struct for a given type of dat files. For
instance, this allows one to retrieve the ordered list of apt.dat
files the NavCache would use if it were rebuilt at that time, as well
as their total size.
It is not needed anymore to hardcode the number of lines of
$FG_ROOT/Airports/apt.dat.gz. The new method, which relies on
SGPath::sizeInBytes() and sg_gzifstream::approxOffset(), works as well
for the other dat files.
Add a new NavCache rebuild phase, REBUILD_READING_APT_DAT_FILES, since
the process is now made of two parts.
Rename NavDataCachePrivate::getDatFilesPaths() to
NavDataCachePrivate::findDatFiles(), because it now returns a
DatFilesGroupInfo (new struct) instead of a PathList. For the same
reason, rename NavDataCachePrivate::aptDatPaths to
NavDataCachePrivate::aptDatFilesInfo. Adapt signatures, etc.
This requires up-to-date SimGear and FGData.
It is now allowed to have the same airport appear in several apt.dat
files ($scenery_path/NavData/apt/*.dat[.gz] for each scenery path, plus
the default $FG_ROOT/Airports/apt.dat.gz, coming last). Airports found
in earlier files(*) take precedence over those found later, in case
several apt.dat files define the same airports. Airports that are
skipped due to this mechanism are logged with
SG_LOG(SG_GENERAL, SG_INFO, ...).
(*) using 1) FG_SCENERY order (followed by $FG_ROOT/Airports/apt.dat.gz)
and 2) lexicographic order inside each $scenery_path/NavData/apt
folder
With this commit, APTLoader::parseAPT() is replaced by two methods:
readAptDatFile() and loadAirports():
- APTLoader::readAptDatFile() reads airport definitions from an
apt.dat file into APTLoader's 'airportInfoMap' member variable,
discarding duplicate definitions due to overlapping apt.dat files
('airportInfoMap' is an std::unordered_map instance in C++11 and
later, an std::map otherwise);
- APTLoader::loadAirports() reads each airport definition from
'airportInfoMap' and loads it into the NavCache, the same way as
APTLoader::parseAPT() used to do.
The airportDBLoad() function is not useful anymore, and is thus removed
(in NavDataCache::doRebuild(), APTLoader::readAptDatFile() is now called
once per apt.dat file, but APTLoader::loadAirports() is only called
once at the end, after duplicate airports have been discarded; the class
interface is much better suited to this scheme, because it can cleanly
retain the state between these calls).
By the way, this commit fixes an old bug: APTLoader's member variable
'last_apt_id' was used in several places but never assigned to, except
in APTLoader::APTLoader() as the empty string.
Thanks to Alan Teeder for his feedback and testing.
Load every file matching the pattern NavData/apt/*.dat[.gz] inside each
scenery path. These files are loaded in the same order as the components
of globals->get_unmangled_fg_scenery() they reside in. Inside a given
component, the order is determined by pathSortPredicate() in
simgear/misc/sg_dir.cxx (lexicographic order at the time of this
writing). For compatibility with existing scenery,
$FG_ROOT/Airports/apt.dat.gz is also loaded last.
The idea is that such files will have the same precedence order as the
globals->get_unmangled_fg_scenery() scenery components they come from.
This commit doesn't handle this fully yet, though: it blindly loads all
these files. A future commit will ensure that no airport is loaded twice
due to overlapping apt.dat files. This commit however handles all the
logic of navdata cache rebuilding when the list, the order of apt.dat
files, or any of their timestamps changes.
Although only apt.dat files receive a new treatment in this commit, the
changes to NavDataCache.[ch]xx are already generic so that extension of
this method to fix.dat, nav.dat, etc. will require almost no change to
NavDataCache.[ch]xx (however, changes will probably be needed in the
various loaders: in fixlist.[ch]xx, navdb.[ch]xx, etc.).
src/Navaids/CacheSchema.h:
- increment the SCHEMA_VERSION by 1. This ensures among others that if
someone uses a FlightGear version posterior to this change with
new-style scenery (having NavData/apt/*.dat[.gz] files inside
scenery paths), then goes back to a FlightGear version anterior to
this change, his NavCache is rebuilt ignoring the in-scenery-paths
NavData/apt/*.dat[.gz] files, as expected with the old FlightGear
version.
src/Navaids/NavDataCache.cxx:
- NavDataCachePrivate: replace aptDatPath (SGPath) with aptDatPaths
(PathList).
- NavDataCachePrivate::getDatFilesPaths(): new method that returns the
list of $scenery_path/NavData/<type>/*.dat[.gz] files found inside
scenery paths (where <type> is one of 'apt', 'fix', etc.), plus the
historical file (e.g., $FG_ROOT/Airports/apt.dat.gz for the 'apt'
type).
- NavDataCachePrivate::areDatFilesModified(): new method that tells
whether any of these files (for a given type) has changed since the
last NavCache rebuild, or if their ordered list has changed.
- NavDataCachePrivate::isCachedFileModified(): minor changes.
- NavDataCache::updateListsOfDatFiles(): new method that updates the
lists of dat files used for NavCache freshness checking and
rebuilding, i.e. currently sets/updates d->aptDatPaths using the new
method d->getDatFilesPaths(), and d->metarDatPath, d->navDatPath,
d->fixDatPath, d->poiDatPath, etc. as usual. This method will be
useful for instance in the built-in launcher after updating scenery
paths and before calling NavDataCache::isRebuildRequired().
- NavDataCache::NavDataCache(): use
NavDataCache::updateListsOfDatFiles() to initialize d->aptDatPaths,
d->metarDatPath, d->navDatPath, d->fixDatPath, d->poiDatPath, etc.
- NavDataCache::isRebuildRequired(): use
NavDataCachePrivate::areDatFilesModified() instead of just checking
$FG_ROOT/Airports/apt.dat.gz.
- NavDataCache::doRebuild(): load all apt.dat files listed in
d->aptDatPaths, instead of only $FG_ROOT/Airports/apt.dat.gz. Write
their ordered list and timestamps in the NavCache.
src/Navaids/NavDataCache.hxx:
- declare the new method NavDataCache::updateListsOfDatFiles().
- NavDataCache::DatFileType: new enum with values DATFILETYPE_APT,
DATFILETYPE_METAR, DATFILETYPE_AWY, DATFILETYPE_NAV,
DATFILETYPE_FIX, DATFILETYPE_POI, DATFILETYPE_CARRIER and
DATFILETYPE_TACAN_FREQ. Maybe some of the corresponding files won't
have to be moved to scenery paths, but simply listing them in the
enum doesn't change how they are dealt with. Those for which
per-scenery-path locations doesn't make sense can just be removed
from the enum.
- NavDataCache::datTypeStr: new static string_list giving an
std::string such as 'apt' for each value of the
NavDataCache::DatFileType enum.
- NavDataCache::defaultDatFile: new static string_list giving a path
(relative to $FG_ROOT) to the historical/default file for each value
of the NavDataCache::DatFileType enum.
src/Airports/apt_loader.cxx and src/Airports/apt_loader.hxx:
- always include a path to the apt.dat file being processed in log
messages, since they can now apply to many files;
- be clearer about code 99: it should normally be at the end of
apt.dat files, but technically, it is not an EOF;
- use the expression "row code" consistently with the apt.dat format
spec (for now: only in places where there is another change to do).
src/GUI/QtLauncher.cxx and src/GUI/QtLauncher_private.hxx:
- turn QtLauncher::setSceneryPaths() into a static method and call it
in runLauncherDialog() before instantiating NavDataCache, so that
NavDataCache::updateListsOfDatFiles() (called from NavDataCache's
constructor) can see all configured scenery paths.
This will avoid problems in case stampCacheFile() or
isCachedFileModified() is passed a relative path, or a path containing
.. components, etc. Among others, it ensures the stat_cache table only
contains absolute paths.
NavDataCache: read and write methods preserving order for string list props
New methods: NavDataCache::readOrderedStringListProperty() and
NavDataCache::writeOrderedStringListProperty().
- loadFixes() becomes FixesLoader::loadFixes();
- the previous 'cache' variable (NavDataCache *) is now a private member
of FixesLoader, named '_cache'.