From 476161cf2caa27abb9e4da0e082f765dc39c059c Mon Sep 17 00:00:00 2001 From: Andrettin <6322423+Andrettin@users.noreply.github.com> Date: Sun, 8 Nov 2020 17:13:09 +0100 Subject: [PATCH] Improved the performance of the BestDepotFinder --- src/unit/unit_find.cpp | 65 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/unit/unit_find.cpp b/src/unit/unit_find.cpp index ac77feb58..ef1596416 100644 --- a/src/unit/unit_find.cpp +++ b/src/unit/unit_find.cpp @@ -178,7 +178,7 @@ bool FindTerrainType(int movemask, int resmask, int range, template <const bool NEARLOCATION> class BestDepotFinder { - inline void operator()(CUnit *const dest) + void operator()(CUnit *const dest) { /* Only resource depots */ if (dest->Type->CanStore[resource] @@ -186,64 +186,65 @@ class BestDepotFinder && dest->CurrentAction() != UnitActionBuilt) { // Unit in range? - if (NEARLOCATION) { - int d = dest->MapDistanceTo(u_near.loc); + if constexpr (NEARLOCATION) { + const int d = dest->MapDistanceTo(u_near.loc); // // Take this depot? // - if (d <= range && d < best_dist) { - best_depot = dest; - best_dist = d; + if (d <= this->range && d < this->best_dist) { + this->best_depot = dest; + this->best_dist = d; } } else { - int d; - const CUnit *worker = u_near.worker; - if (!worker->Container) { - d = worker->MapDistanceTo(*dest); - } else { - d = worker->Container->MapDistanceTo(*dest); - } + const CUnit *worker = this->u_near.worker; + const CUnit *first_container = GetFirstContainer(*worker); + + //simple distance + const int distance = first_container->MapDistanceTo(*dest); // Use Circle, not square :) - if (d > range) { + if (distance > this->range) { return; } - if (best_dist == INT_MAX) { - best_depot = dest; + if (this->best_dist == INT_MAX) { + this->best_depot = dest; + } + + if (distance >= this->best_dist) { + //if the depot's simple distance is greater or equal to the real travel distance of the currently-chosen depot, then it can never be closer than it, and we have no reason to actually calculate its real travel distance + return; } // calck real travel distance - if (worker->Container) { - UnmarkUnitFieldFlags(*worker->Container); + if (worker->Container != nullptr) { + UnmarkUnitFieldFlags(*first_container); } - d = UnitReachable(*worker, *dest, 1); - if (worker->Container) { - MarkUnitFieldFlags(*worker->Container); + const int travel_distance = UnitReachable(*worker, *dest, 1); + if (worker->Container != nullptr) { + MarkUnitFieldFlags(*first_container); } // // Take this depot? // - if (d && d < best_dist) { - best_depot = dest; - best_dist = d; + if (travel_distance && travel_distance < this->best_dist) { + this->best_depot = dest; + this->best_dist = travel_distance; } } } } public: - BestDepotFinder(const CUnit &w, int res, int ran) : - resource(res), range(ran), - best_dist(INT_MAX), best_depot(0) + explicit BestDepotFinder(const CUnit &w, const int res, const int ran) + : resource(res), range(ran) { u_near.worker = &w; } - BestDepotFinder(const Vec2i &pos, int res, int ran) : - resource(res), range(ran), - best_dist(INT_MAX), best_depot(0) + explicit BestDepotFinder(const Vec2i &pos, const int res, const int ran) : + resource(res), range(ran) { u_near.loc = pos; } @@ -269,9 +270,9 @@ private: } u_near; const int resource; const int range; - int best_dist; + int best_dist = INT_MAX; public: - CUnit *best_depot; + CUnit *best_depot = nullptr; }; CUnit *FindDepositNearLoc(CPlayer &p, const Vec2i &pos, int range, int resource)