TBTR: Fix crash which could occur with multiple virtual vehicle deletes in flight

This commit is contained in:
Jonathan G Rennison
2020-10-09 19:07:04 +01:00
parent 8cec0181b2
commit 348178e9eb

View File

@@ -133,6 +133,7 @@ private:
VehicleID vehicle_over; VehicleID vehicle_over;
bool sell_hovered; ///< A vehicle is being dragged/hovered over the sell button. bool sell_hovered; ///< A vehicle is being dragged/hovered over the sell button.
uint32 template_index; uint32 template_index;
btree::btree_set<VehicleID> pending_deletions; ///< Vehicle IDs where deletion is in progress
public: public:
TemplateCreateWindow(WindowDesc* _wdesc, TemplateVehicle *to_edit, bool *window_open) : Window(_wdesc) TemplateCreateWindow(WindowDesc* _wdesc, TemplateVehicle *to_edit, bool *window_open) : Window(_wdesc)
@@ -390,8 +391,14 @@ public:
Train* train_to_delete = Train::Get(this->sel); Train* train_to_delete = Train::Get(this->sel);
this->pending_deletions.insert(this->sel);
if (virtual_train == train_to_delete) { if (virtual_train == train_to_delete) {
virtual_train = (_ctrl_pressed) ? nullptr : virtual_train->GetNextUnit(); if (_ctrl_pressed) {
virtual_train = nullptr;
} else {
this->RearrangeVirtualTrain();
}
} }
DoCommandP(0, this->sel | (sell_cmd << 20) | (1 << 21), 0, GetCmdSellVeh(VEH_TRAIN), CcDeleteVirtualTrain); DoCommandP(0, this->sel | (sell_cmd << 20) | (1 << 21), 0, GetCmdSellVeh(VEH_TRAIN), CcDeleteVirtualTrain);
@@ -566,11 +573,20 @@ public:
} }
} }
void VirtualVehicleDeleted(VehicleID id)
{
this->pending_deletions.erase(id);
this->RearrangeVirtualTrain();
}
void RearrangeVirtualTrain() void RearrangeVirtualTrain()
{ {
if (!virtual_train) return; if (!this->virtual_train) return;
virtual_train = virtual_train->First(); this->virtual_train = this->virtual_train->First();
assert(HasBit(virtual_train->subtype, GVSF_VIRTUAL)); assert(HasBit(this->virtual_train->subtype, GVSF_VIRTUAL));
for (; this->virtual_train != nullptr; this->virtual_train = this->virtual_train->GetNextUnit()) {
if (this->pending_deletions.count(this->virtual_train->index) == 0) break;
}
} }
@@ -615,7 +631,7 @@ void CcDeleteVirtualTrain(const CommandCost &result, TileIndex tile, uint32 p1,
Window* window = FindWindowById(WC_CREATE_TEMPLATE, 0); Window* window = FindWindowById(WC_CREATE_TEMPLATE, 0);
if (window) { if (window) {
((TemplateCreateWindow*)window)->RearrangeVirtualTrain(); ((TemplateCreateWindow*)window)->VirtualVehicleDeleted(GB(p1, 0, 20));
window->InvalidateData(); window->InvalidateData();
} }
} }