As an opt-in API, allow clients to request partial results, with a time-bounded cutoff. Use this to keep the MapWidget responsive even when many airports are being added to the cache (e.g., zooming out or panning rapidly when zoomed out)
void MapWidget::drawAirports()
{
MapAirportFilter af(_root);
- FGPositioned::List apts = FGPositioned::findWithinRange(_projectionCenter, _drawRangeNm, &af);
+ bool partial = false;
+ FGPositioned::List apts = FGPositioned::findWithinRangePartial(_projectionCenter, _drawRangeNm, &af, partial);
for (unsigned int i=0; i<apts.size(); ++i) {
drawAirport((FGAirport*) apts[i].get());
}
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
+#include <simgear/timing/timestamp.hxx>
namespace flightgear
{
}
}
-void findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults)
+bool findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults, int aCutoffMsec)
{
aResults.clear();
FindNearestPQueue pq;
pq.push(Ordered<Node*>(global_spatialOctree, 0));
double rng = aRangeM;
- while (!pq.empty()) {
+ SGTimeStamp tm;
+ tm.stamp();
+
+ while (!pq.empty() && (tm.elapsedMSec() < aCutoffMsec)) {
Node* nd = pq.top().get();
pq.pop();
for (unsigned int r=0; r<numResults; ++r) {
aResults[r] = results[r].get();
}
+
+ return !pq.empty();
}
} // of namespace Octree
};
void findNearestN(const SGVec3d& aPos, unsigned int aN, double aCutoffM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults);
- void findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults);
+ bool findAllWithinRange(const SGVec3d& aPos, double aRangeM, FGPositioned::Filter* aFilter, FGPositioned::List& aResults, int aCutoffMsec);
} // of namespace Octree
List result;
Octree::findAllWithinRange(SGVec3d::fromGeod(aPos),
- aRangeNm * SG_NM_TO_METER, aFilter, result);
+ aRangeNm * SG_NM_TO_METER, aFilter, result, 0xffffff);
+ return result;
+}
+
+FGPositioned::List
+FGPositioned::findWithinRangePartial(const SGGeod& aPos, double aRangeNm, Filter* aFilter, bool& aPartial)
+{
+ validateSGGeod(aPos);
+
+ int limitMsec = 32;
+ List result;
+ aPartial = Octree::findAllWithinRange(SGVec3d::fromGeod(aPos),
+ aRangeNm * SG_NM_TO_METER, aFilter, result,
+ limitMsec);
return result;
}
std::vector<Type> types;
Type mMinType, mMaxType;
};
-
+
static List findWithinRange(const SGGeod& aPos, double aRangeNm, Filter* aFilter = NULL);
+
+ static List findWithinRangePartial(const SGGeod& aPos, double aRangeNm, Filter* aFilter, bool& aPartial);
static FGPositionedRef findClosestWithIdent(const std::string& aIdent, const SGGeod& aPos, Filter* aFilter = NULL);