Use a new SGPropertyNode flag, LISTENER_SAFE, to white-list properties
where we do correctly fire listeners, and test this flag when listening
from Nasal, to avoid the warning.
Ensure changes from Nasal are picked up by delegates (such as GPS) when
they are made. Add a route-manager test which sets and exits a hold
using Nasal.
As part of this, update the test API to make it easy to run Nasal from
a test.
GPS now lets the delegate handle the sequencing behaviour, by
setting a new config property. The default GPS delegate (in Nasal)
now sets this property.
This requires a corresponding FGData update.
This is a clean up commit prior to the subsystem API standardisation to simplify
the diffs. It includes all SGSubsystem and SGSubsystemGroup derived classes.
Problem seen with Nasal setChildren/setValues where names were not
being passed down the stack. Identified as over-zealous IF_DEF
to remove unused variable compiler which meant snprintf was not being called
for non debug builds (see c177aeb623)
Fix is to change assert() calls to an naRuntime error, which ensures
that the len variable is always used and is
more appropriate as buffer overrun could occur in any release build if
someone tried to set a name of >1024 characters.
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.
(everything described here lives in the namespace flightgear::addons)
New classes: Author, Maintainer, and Contact. Author and Maintainer
derive from Contact. For each contact, the following can be defined in
addon-metadata.xml: name, email, and url. See [1] for details about the
syntax and usage policy. Nasal bindings have been updated accordingly,
there are three new ghosts: addons.Contact, addons.Author and
addons.Maintainer.
The enum class UrlType has two new members: author and maintainer. The
Addon::getUrls() method has a new signature:
std::multimap<UrlType, QualifiedUrl> getUrls() const;
because non-empty 'url' fields for authors and maintainers contribute to
the result, and there can be an arbitrary number of authors and an
arbitrary number of maintainers defined for a given add-on---therefore,
std::map can't be used anymore.
Finally, QualifiedUrl has a new field (detail) which stores the author
name (resp. maintainer name) when the QualifiedUrl type is
UrlType::author (resp. UrlType::maintainer). Currently, this 'detail'
field is not used for other URL types, but this could be changed if
desired.
[1] https://sourceforge.net/p/flightgear/fgdata/ci/next/tree/Docs/README.add-ons
These methods were removed by mistake in commit 0dbb0dff9, which broke
code that relies on them (e.g., FMSDelegate.currentWaypointChanged() in
$FG_ROOT/Nasal/route_manager.nas).
Also remove 'waypointPrototype' from NasalPositioned.cxx, since it is
not used anymore.
Note: the methods can't be easily re-enabled by means of
'waypointPrototype', because for FPLeg ghosts, 'waypointPrototype'
was emulated as a parent class before this commit, and thus when
querying an FPLeg ghost for its 'airport', 'runway' or 'navaid'
member, the corresponding data member returned by
waypointCommonGetMember() would be found by legGhostGetMember()
*before* parent classes are searched. This commit prevents this
from happening by returning 'airport', 'runway' and 'navaid' as
member functions *directly* in legGhostGetMember(), before
waypointCommonGetMember() is queried as a fallback.
Thanks to Eric van den Berg for the bug report.
This commit adds C++ classes for add-on management, most notably
AddonManager, Addon and AddonVersion. The AddonManager is used to
register add-ons. It relies on an std::map<std::string, AddonRef> to
hold the metadata of each registered add-on (keys of the std::map are
add-on identifiers, and AddonRef is currently SGSharedPtr<Addon>).
Accessor methods are available for:
- retrieving the list of registered or loaded add-ons (terminology
explained in $FG_ROOT/Docs/README.add-ons);
- checking if a particular add-on has already been registered or
loaded;
- for each add-on, obtaining an Addon instance which can be queried
for its name, id, version, base path, the minimum and maximum
FlightGear versions it requires, its base node in the Property Tree,
its order in the load sequence, short and long description strings,
home page, etc.
The most important metadata is made accessible in the Property Tree
under /addons/by-id/<addon-id> and the property
/addons/by-id/<addon-id>/loaded can be checked or listened to, in
order to determine when a particular add-on is loaded. There is also a
Nasal interface to access add-on metadata in a convenient way.
In order to provide this metadata, each add-on must from now on have in
its base directory a file called 'addon-metadata.xml'.
All this is documented in much more detail in
$FG_ROOT/Docs/README.add-ons.
Mailing-list discussion:
https://sourceforge.net/p/flightgear/mailman/message/36146017/
Waypoint objects used in Nasal code can now return their airport,
runway or navaid object (Nasal ghost). More precisely:
- if waypoint 'wpt' was made from an airport object[1], then
'wpt.airport' is this airport object;
- if waypoint 'wpt' was made from a runway object[2], then
'wpt.runway' is this runway object, and 'wpt.airport' is the
airport containing that runway;
- if waypoint 'wpt' was made from a navaid object[3], then
'wpt.navaid' is this navaid object.
When one of the three properties 'airport', 'runway', and 'navaid' is
not applicable to a given waypoint due to the type of the underlying
FGPositioned, its value is nil.
The code for these properties was already mostly there, but
unreachable from Nasal.
[1] For instance, with createWPFrom(airportinfo("LOWI"))
[2] For instance, with createWPFrom(airportinfo("LOWI").runway("26"))
[3] For instance, with:
var apt = airportinfo("LOWI");
var navaid = findNavaidByFrequencyMHz(apt, 109.7);
var navaidWpt = createWPFrom(navaid);