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);
Treat passing nil as clearing the speed / altitude restriction for
the leg. Also default the second arg to ‘at’, so calling these
methods with a single numerical arg is permitted.
Allows creating a new, inactive by empty Flightplan from Nasal. Can
also be used to load a flightplan:
var fp1 = createFlightplan();
var fp2 = createFlightplan("p3.xml");
The problem is that the two aren't functionally equivalent; the Nasal version would fail silently - whereas the new C++ version gave a runtime error.
The immediate fix is therefore to simply remove the runtime error.
Call fgInitAllowedPaths() right after Options::processOptions() (which,
among other things, determines $FG_ROOT and processes
--allow-nasal-read). This way, fgInitAllowedPaths() can be used in much
more code, such as when initializing subsystems.
Improve performance of Nasal properties access
by implementing the setValues/setChildren props.nas
functions in C++. Naive implementation effectively
copying the Nasal versions verbatim.
However, on a test suite writing 1000 Canvas paths,
results in a 50% reduction in runtime, and significant
reductions in memory occupancy.
On a much larger task (5500 paths) results in a 30%
reduction, probably due to Nasal GC.
Change fgcommand to take an optional property tree root element.
This fixes the animation bindings to use the defined property tree root - to support multiplayer (or other) model that can bind to the correct part of the property tree.
Requires a corresponding fix in sg to allow the command methods to take an optional root parameter.
What this means is that when inside someone else's multiplayer model (e.g. backseat, or co-pilot), the multipalyer (AI) model will correctly modify properties inside the correct part of the property tree inside (/ai), rather than modifying the properties inside the same part of the tree as the non-ai model.
This means that a properly setup model will operate within it's own space in the property tree; and permit more generic multiplayer code to be written.
This is probably responsible for some of the pollution of the root property tree with MP aircraft properties.
New Nasal method get_cart_ground_intersection
Returns where the given position in the specified direction will intersect with the ground. Returns whether or not a certain position and direction pair intersect with the ground, and if so the intersection point.
Useful for radars, terrain avoidance (GPWS), etc.
Input parameters:
1. vec3d(x,y,z) position
2. vec3d(x,y,z) direction
Returns nil or geod hash (lat:rad,lon:rad,elevation:Meters) intersection
Example Usage:
var end = geo.Coord.new(start);
end.apply_course_distance(heading, speed_horz_fps*FT2M);
end.set_alt(end.alt() - speed_down_fps*FT2M);
var dir_x = end.x() - start.x();
var dir_y = end.y() - start.y();
var dir_z = end.z() - start.z();
var xyz = { "x":start.x(), "y" : start.y(), "z" : start.z() };
var dir = { "x":dir_x, "y" : dir_y, "z" : dir_z };
var geod = get_cart_ground_intersection(xyz, dir);
if (geod != nil) {
end.set_latlon(geod.lat, geod.lon, geod.elevation);
var dist = start.direct_distance_to(end)*M2FT;
var time = dist / speed_fps;
setprop("/sim/model/radar/time-until-impact", time);
}
-----------
Nasal method aircraftToCart : This allows easily computing offsets in aircraft-relative coordinates, and converting to global cartesian (ECEF) reference frame.
Compile a useful subset of FG as a shared library, and add two basic
uses of this to exercise some Flightplan / RoutePath / navaid
functions.
The test framework can/will be expanded incrementally from here, this
is just a starting point.
This change is the logical counterpart of SimGear's change from commit
79f869a7f32910197be72b21f6489fbbba02c836 that moved the following files
from simgear/misc to simgear/io/iostreams:
gzcontainerfile.cxx
gzcontainerfile.hxx
gzfstream.cxx (formerly zfstream.cxx)
gzfstream.hxx (formerly zfstream.hxx)
sgstream.cxx
sgstream.hxx
sgstream_test.cxx
Previously timer objects defaulted to using wall-clock (real) dt which
does not reflect pause/speed-up. Keep this as the default for
compatibility but make it possible to request simulated time.
Remove uses of .str(), .c_str() and some other methods of SGPath.
Pass SGPath directly where possible, or explicitly convert to the
appropriate 8-bit encoding.
Being able to list arbitrary directories is a privacy violation;
existing in-fgdata uses of this are all permitted paths
(i.e. not Terrasync; FileSelector doesn't use it)
Drop fgNormalizePath, use realpath() only
As this makes it accept relative paths, always use the returned
(absolute) version for the actual file operation to avoid check-to-use
races, or where this is not possible (NasalSGPath) explicitly reject
relative paths
Fix: do_save is a write, not a read