From cac6407a8e229e02bcc6ae547b7f164308fa3c9c Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sun, 8 Dec 2013 19:22:41 +0100 Subject: [PATCH] Add positioned.diff for fast difference calculations on positioned lists. --- src/Scripting/NasalPositioned_cppbind.cxx | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Scripting/NasalPositioned_cppbind.cxx b/src/Scripting/NasalPositioned_cppbind.cxx index 8d51624a8..79d24a1d2 100644 --- a/src/Scripting/NasalPositioned_cppbind.cxx +++ b/src/Scripting/NasalPositioned_cppbind.cxx @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -398,7 +399,7 @@ static naRef f_findWithinRange(nasal::CallContext ctx) std::string typeSpec = ctx.getArg(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); @@ -456,6 +457,39 @@ static naRef f_sortByRange(nasal::CallContext ctx) 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 Diff; + Diff::List old_list = ctx.requireArg(0), + new_list = ctx.requireArg(1); + Diff::Callback cb_add = ctx.requireArg(2), + cb_rm = ctx.getArg(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) { @@ -517,5 +551,7 @@ naRef initNasalPositioned_cppbind(naRef globalsRef, naContext c) positioned.set("courseAndDistance", &f_courseAndDistance); positioned.set("sortByRange", &f_sortByRange); + positioned.set("diff", &f_diff); + return naNil(); }