From b884fab7b6f533c21fab125cb7f044ddeadad995 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Fri, 10 Mar 2023 01:04:23 -0800 Subject: [PATCH] fix freeze when printing status and there are defunct planned buildings --- plugins/buildingplan/buildingplan.cpp | 12 ++++++++---- plugins/buildingplan/plannedbuilding.cpp | 5 +++-- plugins/buildingplan/plannedbuilding.h | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/plugins/buildingplan/buildingplan.cpp b/plugins/buildingplan/buildingplan.cpp index 310d03a5e..2b67c2353 100644 --- a/plugins/buildingplan/buildingplan.cpp +++ b/plugins/buildingplan/buildingplan.cpp @@ -516,16 +516,20 @@ static void printStatus(color_ostream &out) { out.print(" use bars: %s\n", get_config_bool(config, CONFIG_BARS) ? "yes" : "no"); out.print("\n"); + size_t bld_count = 0; map counts; int32_t total = 0; for (auto &entry : planned_buildings) { auto &pb = entry.second; - auto bld = pb.getBuildingIfValidOrRemoveIfNot(out); + // don't actually remove bad buildings from the list while we're + // actively iterating through that list + auto bld = pb.getBuildingIfValidOrRemoveIfNot(out, true); if (!bld || bld->jobs.size() != 1) continue; auto &job_items = bld->jobs[0]->job_items; if (job_items.size() != pb.vector_ids.size()) continue; + ++bld_count; int job_item_idx = 0; for (auto &vec_ids : pb.vector_ids) { auto &jitem = job_items[job_item_idx++]; @@ -537,9 +541,9 @@ static void printStatus(color_ostream &out) { } } - if (planned_buildings.size()) { + if (bld_count) { out.print("Waiting for %d item(s) to be produced for %zd building(s):\n", - total, planned_buildings.size()); + total, bld_count); for (auto &count : counts) out.print(" %3d %s%s\n", count.second, count.first.c_str(), count.second == 1 ? "" : "s"); } else { @@ -949,7 +953,7 @@ static string getDescString(color_ostream &out, df::building *bld, int index) { PlannedBuilding &pb = planned_buildings.at(bld->id); auto &jitem = bld->jobs[0]->job_items[index]; - return get_desc_string(out, jitem, pb.vector_ids[index]); + return int_to_string(jitem->quantity) + " " + get_desc_string(out, jitem, pb.vector_ids[index]); } static int getQueuePosition(color_ostream &out, df::building *bld, int index) { diff --git a/plugins/buildingplan/plannedbuilding.cpp b/plugins/buildingplan/plannedbuilding.cpp index a693f6fcf..e678c850f 100644 --- a/plugins/buildingplan/plannedbuilding.cpp +++ b/plugins/buildingplan/plannedbuilding.cpp @@ -99,11 +99,12 @@ PlannedBuilding::PlannedBuilding(color_ostream &out, PersistentDataItem &bld_con // Ensure the building still exists and is in a valid state. It can disappear // for lots of reasons, such as running the game with the buildingplan plugin // disabled, manually removing the building, modifying it via the API, etc. -df::building * PlannedBuilding::getBuildingIfValidOrRemoveIfNot(color_ostream &out) { +df::building * PlannedBuilding::getBuildingIfValidOrRemoveIfNot(color_ostream &out, bool skip_remove) { auto bld = df::building::find(id); bool valid = bld && bld->getBuildStage() == 0; if (!valid) { - remove(out); + if (!skip_remove) + remove(out); return NULL; } return bld; diff --git a/plugins/buildingplan/plannedbuilding.h b/plugins/buildingplan/plannedbuilding.h index 5bd09ba5a..59dc24a79 100644 --- a/plugins/buildingplan/plannedbuilding.h +++ b/plugins/buildingplan/plannedbuilding.h @@ -29,7 +29,7 @@ public: // Ensure the building still exists and is in a valid state. It can disappear // for lots of reasons, such as running the game with the buildingplan plugin // disabled, manually removing the building, modifying it via the API, etc. - df::building * getBuildingIfValidOrRemoveIfNot(DFHack::color_ostream &out); + df::building * getBuildingIfValidOrRemoveIfNot(DFHack::color_ostream &out, bool skip_remove = false); private: DFHack::PersistentDataItem bld_config;