- 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.
Similar to the existing FGGlobals::get/set_terrasync_dir(), add
FGGlobals::get_download_dir() and FGGlobals::set_download_dir() methods,
and of course the corresponding FGGlobals::download_dir public member
variable. FGGlobals::set_download_dir() stores the realpath() of the
given directory, including into the /sim/paths/download-dir property,
which is marked as read-only just as /sim/terrasync/scenery-dir already
is.
Handle the setup of the TerraSync and download dirs all in the same
place (Options::processOptions()), since most of the work is already
done there. This allows one to get rid of fgOptTerrasyncDir() and
fgOptDownloadDir(), and to make it easier to see that
globals->set_terrasync_dir() (resp. globals->set_download_dir()) is
called on the correct SGPath, regardless of whether --terrasync-dir
(resp. --download-dir) was passed.
Always create the TerraSync and download dirs when they don't already
exist, regardless of whether --terrasync-dir or --download-dir has been
given on the command line.
Add comments explaining how to avoid security pitfalls with download and
TerraSync dirs (cf. discussion around
<https://sourceforge.net/p/flightgear/mailman/message/35461636/>).
Adjust indentation where it was too broken, hampering readbility.
1) Paths and the FG_SCENERY paths list are now printed like:
FG_ROOT=/home/flo/flightgear/src/fgdata
instead of:
FG_ROOT=Path "/home/flo/flightgear/src/fgdata"
Moreover, FG_SCENERY is now correctly printed (without 'Path ""'
wrapping, without Terrain, Objects and markers instead of the actual
scenery paths) regardless of the position of --version relatively to
--fg-scenery, --terrasync-dir, etc. Of course, the values given to
these options do influence the output of --version.
Simplify printing of FG_SCENERY via SGPath::join() and use the
correct, OS-dependent separator between paths, SGPath::pathListSep.
Write the --version output to stdout, as already done for --help;
then it can be easily piped to $PAGER and doesn't get mixed with the
output of SG_LOG (which is on stderr). This is of course backward
incompatible for programs reading the stderr output of
'fgfs --version', but has been agreed upon on FlightGear-devel (cf.
<https://sourceforge.net/p/flightgear/mailman/message/35461619/>).
2) Don't write explicit values in the OptionResult enum: they don't
matter, but giving them is error-prone in case one does a copy-paste
to add a new member to the enum and forgets to change the value.
For some reason, g++ may see a 'skipws' I/O manipulator from the
standard library (depending on the order of includes...) when compiling
src/Navaids/poidb.cxx. This I/O manipulator is then in competition with
one with the same name defined in simgear/misc/sgstream.cxx. Use std::ws
to remove all ambiguity (std:skipws does something quite different!).
The new FGLight::updateObjects() function is now being passed into the global
events manager as a task rather than FGLight::updateSunPos(). The
updateSunPos() function has been renamed to updateBodyPos() and generalised for
any solar system body and is called twice by updateObjects(), once for the sun
and once for the moon. The local position of the moon is then exposed at
"/ephemeris/moon/local/".
This includes the moon's absolute position, age and phase. For this, the new
simgear MoonPos::get*() functions are tied to the property tree at
"/ephemeris/moon/" using a new tieMoonPos() function.
In addition the moon illumination factor is exposed by tying the simgear
MoonPos::getIlluminanceFactor() function to the /environment/moonlight property.
This is a number ranging between 0 and 1 based on the log of the illuminance of
the moon outside the atmosphere. It is calculated as
factor = (log(I) - max_loglux) / (max_loglux - min_loglux) + 1.0,
The illuminance of the moon outside the atmosphere, I, is from equation 20 from:
Krisciunas K. and Schaefer B.E. (1991). A model of the brightness of
moonlight, Publ. Astron. Soc. Pacif. 103(667), 1033-1039 (DOI:
http://dx.doi.org/10.1086/132921).
For more background, see
http://forum.flightgear.org/viewtopic.php?f=47&t=28201&start=60#p270516 .
The functions fgSunPositionGST() and fgTimeSecondsUntilSunAngle() have been
renamed to fgBodyPositionGST() and fgBodyPositionGST() respectively, and both
require a new char argument specifying the body of interest. This allows the
position of all solar system bodies to be calculated from the aircraft frame of
reference.
Add option --print-solidness
without this option, behaviour of fgelev is unchanged
with this option the word "solid" gets printed behind the elevation if the
material at the given location is solid. A hyphen (-) gets printed otherwise
Move the existing aircraft history to a more obvious place, and follow
the same pattern for the complete location history. This makes restoring
a previously used configuration much simpler.
Of fast systems with 60fps sending many properties to web clients
may overrun the rendering capabilities of the browser. At some point
the web socket client halts the simulation by throtteling the network
connection.
Update rate is settable at startup setting to a double value
/sim/http/property-websocket/update-interval-secs
(default: 0.05 aka 20Hz)
Without this change, it would be possible that the NavCache is rebuilt
using $FG_ROOT/Airports/apt.dat (if $FG_ROOT/Airports/apt.dat.gz is
manually deleted) despite APTLoader::readAptDatFile() using
sg_gzifstream() with $FG_ROOT/Airports/apt.dat.gz, but the NavCache
would still contain a reference to $FG_ROOT/Airports/apt.dat.gz and log
messages would pretend we are reading this (non-existent) file.
Unrelated: the change
- "Loaded data for " << nbAirports << " airports" );
+ "Loaded data for " << nbLoadedAirports << " airports" );
has no incidence given the current code, but it is more logical and
future-proof (in case someone adds a continue statement inside the for
loop starting at line 224...).
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.
Add checks to avoid read-past-vector-bounds errors.
Make the current line number in each apt.dat file available to methods
such as parseRunwayLine810(), parseRunwayLine850(), etc. for useful
error messages.
In APTLoader::parseCommLine():
- use 'rowCode' instead of 'lineId' for consistency with the apt.dat
spec and the rest of the code;
- use 'unsigned int' for the type since row codes are always
non-negative;
- add a missing 'return' statement and improve an error message.
Small optimization in APTLoader::parseAirportLine().
This will be clearer since it is a PositionedID and we are also dealing
with airport identifiers in the sense of the apt.dat spec in the same
class.
Rename 'line_id' to 'rowCode' in src/Airports/apt_loader.cxx
"Row code" is the expression consistently used for this number in the
apt.dat format spec. Since we already deal with airport *identifiers*,
this should make this piece of code easier to read.
For the same reason, rename the 'num' parameter of
APTLoader::parsePavementNodeLine850() to 'rowCode'.
- APTLoader::parseViewpointLine(): new method.
- APTLoader::parseViewpointLine(): check vector size to prevent
past-bounds reading.
More accurate signature for fptypeFromRobinType()
Row codes in the apt.dat spec are always non-negative -> take an
unsigned int instead of just an int.
Use an initialization list for remaining members of APTLoader::APTLoader()
This is slightly more efficient in general. Swap the order of
declarations for the 'cache' and 'currentAirportID' members of
APTLoader to have the initialization list in the same order as the
member declarations (cf. g++'s -Wreorder option and
<http://stackoverflow.com/questions/1828037/whats-the-point-of-g-wreorder>).
Fix detection of blank lines by APTLoader::isBlankOrCommentLine()
In
<https://sourceforge.net/p/flightgear/flightgear/merge-requests/39/#cea6>,
it was decided to let the main apt.dat line reading loop give out
"lines" that may end with '\r', because most of the downstream code will
automatically get rid of this character thanks to its use of
simgear::strutils::split(). However, APTLoader::isBlankOrCommentLine()
didn't detect blank lines properly due to that trailing '\r', which
could cause bad behavior because the subsequent atoi() call could return
anything from a string containing only whitespace (the "anything" in
question being then interpreted as an apt.dat row code...).
Add method APTLoader::cleanLine()
This method returns a copy of the input line with trailing '\r' char(s)
removed.
APTLoader::loadAirports(): clean message when finding an unknown row code
The start of the log message could previously be overwritten by later
text because of the '\r' at the end of input lines (now obtained from
APTLoader::readAptDatFile()). Quite confusing! Use the new
APTLoader::cleanLine() to prevent this from happening.
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.