fix freeze when printing status and there are defunct planned buildings

develop
Myk Taylor 2023-03-10 01:04:23 -08:00
parent a37d2c09bf
commit b884fab7b6
No known key found for this signature in database
3 changed files with 12 additions and 7 deletions

@ -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(" use bars: %s\n", get_config_bool(config, CONFIG_BARS) ? "yes" : "no");
out.print("\n"); out.print("\n");
size_t bld_count = 0;
map<string, int32_t> counts; map<string, int32_t> counts;
int32_t total = 0; int32_t total = 0;
for (auto &entry : planned_buildings) { for (auto &entry : planned_buildings) {
auto &pb = entry.second; 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) if (!bld || bld->jobs.size() != 1)
continue; continue;
auto &job_items = bld->jobs[0]->job_items; auto &job_items = bld->jobs[0]->job_items;
if (job_items.size() != pb.vector_ids.size()) if (job_items.size() != pb.vector_ids.size())
continue; continue;
++bld_count;
int job_item_idx = 0; int job_item_idx = 0;
for (auto &vec_ids : pb.vector_ids) { for (auto &vec_ids : pb.vector_ids) {
auto &jitem = job_items[job_item_idx++]; 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", 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) for (auto &count : counts)
out.print(" %3d %s%s\n", count.second, count.first.c_str(), count.second == 1 ? "" : "s"); out.print(" %3d %s%s\n", count.second, count.first.c_str(), count.second == 1 ? "" : "s");
} else { } else {
@ -949,7 +953,7 @@ static string getDescString(color_ostream &out, df::building *bld, int index) {
PlannedBuilding &pb = planned_buildings.at(bld->id); PlannedBuilding &pb = planned_buildings.at(bld->id);
auto &jitem = bld->jobs[0]->job_items[index]; 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) { static int getQueuePosition(color_ostream &out, df::building *bld, int index) {

@ -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 // 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 // for lots of reasons, such as running the game with the buildingplan plugin
// disabled, manually removing the building, modifying it via the API, etc. // 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); auto bld = df::building::find(id);
bool valid = bld && bld->getBuildStage() == 0; bool valid = bld && bld->getBuildStage() == 0;
if (!valid) { if (!valid) {
remove(out); if (!skip_remove)
remove(out);
return NULL; return NULL;
} }
return bld; return bld;

@ -29,7 +29,7 @@ public:
// Ensure the building still exists and is in a valid state. It can disappear // 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 // for lots of reasons, such as running the game with the buildingplan plugin
// disabled, manually removing the building, modifying it via the API, etc. // 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: private:
DFHack::PersistentDataItem bld_config; DFHack::PersistentDataItem bld_config;