#include <boost/foreach.hpp>
#include <boost/algorithm/string/case_conv.hpp>
+#include <simgear/misc/ListDiff.hxx>
#include <simgear/nasal/cppbind/from_nasal.hxx>
#include <simgear/nasal/cppbind/to_nasal.hxx>
#include <simgear/nasal/cppbind/NasalHash.hxx>
}
//------------------------------------------------------------------------------
-static naRef f_navaid_course(naContext, FGNavRecord& nav)
+static naRef f_navaid_course(FGNavRecord& nav, naContext)
{
if( !( nav.type() == FGPositioned::ILS
|| nav.type() == FGPositioned::LOC
}
//------------------------------------------------------------------------------
-FGRunway* runwayFromNasalArg( const FGAirport& apt,
+FGRunwayRef runwayFromNasalArg( const FGAirport& apt,
const nasal::CallContext& ctx,
size_t index = 0 )
{
if( index >= ctx.argc )
- return NULL;
+ return FGRunwayRef();
try
{
{
if( !apt.hasRunwayWithIdent(ident) )
// TODO warning/exception?
- return NULL;
+ return FGRunwayRef();
return apt.getRunwayByIdent(ident);
}
{}
// TODO warn/error if no runway?
- return NasalRunway::fromNasal(ctx.c, ctx.args[index]);
+ return ctx.from_nasal<FGRunwayRef>(ctx.args[index]);
}
//------------------------------------------------------------------------------
{
std::string type = ctx.getArg<std::string>(0);
bool only_available = ctx.getArg<bool>(1);
-
- FGAirportDynamics* dynamics = apt.getDynamics();
- PositionedIDVec parkings =
- flightgear::NavDataCache::instance()
- ->airportItemsOfType(apt.guid(), FGPositioned::PARKING);
-
- FGParkingList ret;
- BOOST_FOREACH(PositionedID parking, parkings)
- {
- // filter out based on availability and type
- if( only_available && !dynamics->isParkingAvailable(parking) )
- continue;
-
- FGParking* park = dynamics->getParking(parking);
- if( !type.empty() && (park->getType() != type) )
- continue;
-
- ret.push_back(park);
- }
-
- return ret;
+ FGAirportDynamicsRef dynamics = apt.getDynamics();
+ return dynamics->getParkings(only_available, type);
}
/**
if( ctx.isGhost(0) )
{
- FGPositioned* pos =
- NasalPositioned::fromNasal(ctx.c, ctx.requireArg<naRef>(0));
+ FGPositionedRef pos =
+ ctx.from_nasal<FGPositionedRef>(ctx.requireArg<naRef>(0));
if( pos )
{
std::string typeSpec = ctx.getArg<std::string>(1);
FGPositioned::TypeFilter filter(FGPositioned::TypeFilter::fromString(typeSpec));
-
+
FGPositionedList items = FGPositioned::findWithinRange(pos, range_nm, &filter);
FGPositioned::sortByRange(items, pos);
return ctx.to_nasal(items);
return ctx.to_nasal(items);
}
+//------------------------------------------------------------------------------
+// Get difference between two lists of positioned objects.
+//
+// For every element in old_list not in new_list the callback cb_remove is
+// called with the removed element as single argument. For every element in
+// new_list not in old_list cb_add is called.
+//
+// diff(old_list, new_list, cb_add[, cb_remove])
+//
+// example:
+// # Print all fixes within a distance of 320 to 640 miles
+// diff( findWithinRange(320, "fix"),
+// findWithinRange(640, "fix"),
+// func(p) print('found fix: ', p.id) );
+static naRef f_diff(nasal::CallContext ctx)
+{
+ typedef simgear::ListDiff<FGPositionedRef> Diff;
+ Diff::List old_list = ctx.requireArg<FGPositionedList>(0),
+ new_list = ctx.requireArg<FGPositionedList>(1);
+ Diff::Callback cb_add = ctx.requireArg<Diff::Callback>(2),
+ cb_rm = ctx.getArg<Diff::Callback>(3);
+
+ // Note that FGPositionedRef instances are only compared for pointer equality.
+ // As the NavCache caches every queried positioned instance it is guaranteed
+ // that only one instance of every positioned object can exist. Therefore we
+ // can make the comparison faster by just comparing pointers and not also the
+ // guid.
+ // (On my machine the difference is 0.27s vs 0.17s)
+ Diff::inplace(old_list, new_list, cb_add, cb_rm);
+
+ return naNil();
+}
+
//------------------------------------------------------------------------------
naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c)
{
positioned.set("courseAndDistance", &f_courseAndDistance);
positioned.set("sortByRange", &f_sortByRange);
+ positioned.set("diff", &f_diff);
+
return naNil();
}