diff --git a/src/order_base.h b/src/order_base.h index 5bc5aa4bd4..0b13c3e240 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -639,7 +639,7 @@ public: void RemoveScheduledDispatch(uint32 offset); void ClearScheduledDispatch() { this->scheduled_dispatch.clear(); } bool UpdateScheduledDispatchToDate(DateTicksScaled now); - void UpdateScheduledDispatch(); + void UpdateScheduledDispatch(const Vehicle *v); /** * Set the scheduled dispatch duration, in scaled tick diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 2f69db1d92..ea864421d9 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -338,6 +338,7 @@ Order::Order(uint64 packed) void InvalidateVehicleOrder(const Vehicle *v, int data) { SetWindowDirty(WC_VEHICLE_VIEW, v->index); + SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); if (data != 0) { /* Calls SetDirty() too */ diff --git a/src/schdispatch.h b/src/schdispatch.h index a8315675b5..dd35e2c2d7 100644 --- a/src/schdispatch.h +++ b/src/schdispatch.h @@ -15,6 +15,7 @@ #include "settings_type.h" void ShowSchdispatchWindow(const Vehicle *v); +void SchdispatchInvalidateWindows(const Vehicle *v); /** * Convert date and full date fraction to DateTicksScaled diff --git a/src/schdispatch_cmd.cpp b/src/schdispatch_cmd.cpp index e58143c5d6..1d3c9c41ac 100644 --- a/src/schdispatch_cmd.cpp +++ b/src/schdispatch_cmd.cpp @@ -59,9 +59,8 @@ CommandCost CmdScheduledDispatch(TileIndex tile, DoCommandFlag flags, uint32 p1, } else { ClrBit(v2->vehicle_flags, VF_SCHEDULED_DISPATCH); } - SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v2->index); } + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -106,7 +105,7 @@ CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32 p2 += offset; ds.AddScheduledDispatch(p2); } - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -138,7 +137,7 @@ CommandCost CmdScheduledDispatchRemove(TileIndex tile, DoCommandFlag flags, uint if (flags & DC_EXEC) { v->orders.list->GetDispatchScheduleByIndex(schedule_index).RemoveScheduledDispatch(p2); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -172,8 +171,8 @@ CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags, if (flags & DC_EXEC) { DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(schedule_index); ds.SetScheduledDispatchDuration(p2); - ds.UpdateScheduledDispatch(); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + ds.UpdateScheduledDispatch(nullptr); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -217,8 +216,8 @@ CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags if (flags & DC_EXEC) { DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(schedule_index); ds.SetScheduledDispatchStartDate(date, full_date_fract); - ds.UpdateScheduledDispatch(); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + ds.UpdateScheduledDispatch(nullptr); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -251,7 +250,7 @@ CommandCost CmdScheduledDispatchSetDelay(TileIndex tile, DoCommandFlag flags, ui if (flags & DC_EXEC) { v->orders.list->GetDispatchScheduleByIndex(schedule_index).SetScheduledDispatchDelay(p2); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -289,7 +288,7 @@ CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag if (flags & DC_EXEC) { v->orders.list->GetDispatchScheduleByIndex(schedule_index).SetScheduledDispatchLastDispatch(0); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -322,7 +321,7 @@ CommandCost CmdScheduledDispatchClear(TileIndex tile, DoCommandFlag flags, uint3 if (flags & DC_EXEC) { v->orders.list->GetDispatchScheduleByIndex(schedule_index).ClearScheduledDispatch(); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -362,9 +361,8 @@ CommandCost CmdScheduledDispatchAddNewSchedule(TileIndex tile, DoCommandFlag fla DispatchSchedule &ds = v->orders.list->GetScheduledDispatchScheduleSet().back(); ds.SetScheduledDispatchDuration(p2); ds.SetScheduledDispatchStartDate(date, full_date_fract); - ds.UpdateScheduledDispatch(); - SetWindowClassesDirty(WC_VEHICLE_TIMETABLE); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index); + ds.UpdateScheduledDispatch(nullptr); + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -406,8 +404,7 @@ CommandCost CmdScheduledDispatchRemoveSchedule(TileIndex tile, DoCommandFlag fla o->SetDispatchScheduleIndex(idx - 1); } } - SetWindowClassesDirty(WC_VEHICLE_TIMETABLE); - InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS); + SchdispatchInvalidateWindows(v); } return CommandCost(); @@ -421,7 +418,7 @@ void DispatchSchedule::SetScheduledDispatch(std::vector dispatch_list) { this->scheduled_dispatch = std::move(dispatch_list); assert(std::is_sorted(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end())); - if (this->IsScheduledDispatchValid()) this->UpdateScheduledDispatch(); + if (this->IsScheduledDispatchValid()) this->UpdateScheduledDispatch(nullptr); } /** @@ -436,7 +433,7 @@ void DispatchSchedule::AddScheduledDispatch(uint32 offset) return; } this->scheduled_dispatch.insert(insert_position, offset); - this->UpdateScheduledDispatch(); + this->UpdateScheduledDispatch(nullptr); } /** @@ -496,9 +493,9 @@ bool DispatchSchedule::UpdateScheduledDispatchToDate(DateTicksScaled now) /** * Update the scheduled dispatch start time to be the most recent possible. */ -void DispatchSchedule::UpdateScheduledDispatch() +void DispatchSchedule::UpdateScheduledDispatch(const Vehicle *v) { - if (this->UpdateScheduledDispatchToDate(_scaled_date_ticks)) { - InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS); + if (this->UpdateScheduledDispatchToDate(_scaled_date_ticks) && v != nullptr) { + SetTimetableWindowsDirty(v, true); } } diff --git a/src/schdispatch_gui.cpp b/src/schdispatch_gui.cpp index b43cd2af10..17436a1b7a 100644 --- a/src/schdispatch_gui.cpp +++ b/src/schdispatch_gui.cpp @@ -184,8 +184,7 @@ static void AddNewScheduledDispatchSchedule(VehicleID vindex) DoCommandPEx(0, vindex, duration, p3, CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), CcAddNewSchDispatchSchedule, nullptr, 0); } -struct SchdispatchWindow : Window { - const Vehicle *vehicle; ///< Vehicle monitored by the window. +struct SchdispatchWindow : GeneralVehicleWindow { int schedule_index; int clicked_widget; ///< The widget that was clicked (used to determine what to do in OnQueryTextFinished) Scrollbar *vscroll; ///< Verticle scrollbar @@ -197,8 +196,7 @@ struct SchdispatchWindow : Window { bool no_order_warning_pad = false; SchdispatchWindow(WindowDesc *desc, WindowNumber window_number) : - Window(desc), - vehicle(Vehicle::Get(window_number)) + GeneralVehicleWindow(desc, Vehicle::Get(window_number)) { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_SCHDISPATCH_V_SCROLL); @@ -1151,3 +1149,16 @@ void ShowScheduledDispatchAddSlotsWindow(SchdispatchWindow *parent, int window_n new ScheduledDispatchAddSlotsWindow(&_scheduled_dispatch_add_desc, window_number, parent); } + +void SchdispatchInvalidateWindows(const Vehicle *v) +{ + v = v->FirstShared(); + for (Window *w : Window::IterateFromBack()) { + if (w->window_class == WC_VEHICLE_TIMETABLE) { + if (static_cast(w)->vehicle->FirstShared() == v) w->SetDirty(); + } + if (w->window_class == WC_SCHDISPATCH_SLOTS) { + if (static_cast(w)->vehicle->FirstShared() == v) w->InvalidateData(VIWD_MODIFY_ORDERS, false); + } + } +} diff --git a/src/timetable.h b/src/timetable.h index 891b2573fd..8ed9f7132b 100644 --- a/src/timetable.h +++ b/src/timetable.h @@ -18,6 +18,7 @@ void ShowTimetableWindow(const Vehicle *v); void UpdateVehicleTimetable(Vehicle *v, bool travelling); void SetTimetableParams(int first_param, Ticks ticks, bool long_mode = false); +void SetTimetableWindowsDirty(const Vehicle *v, bool include_scheduled_dispatch = false); struct TimetableProgress { VehicleID id; diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 3cde0dec16..6eb39b2f5a 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -102,6 +102,8 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val, v->orders.list->UpdateTotalDuration(total_delta); v->orders.list->UpdateTimetableDuration(timetable_delta); + SetTimetableWindowsDirty(v, mtf == MTF_ASSIGN_SCHEDULE); + for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) { if (v->cur_real_order_index == order_number && v->current_order.Equals(*order)) { switch (mtf) { @@ -139,7 +141,6 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val, NOT_REACHED(); } } - SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); } } @@ -469,8 +470,10 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, for (Vehicle *w = v->orders.list->GetFirstSharedVehicle(); w != nullptr; w = w->NextShared()) { vehs.push_back(w); } + SetTimetableWindowsDirty(v); } else { vehs.push_back(v); + SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); } int total_duration = v->orders.list->GetTimetableTotalDuration(); @@ -483,7 +486,6 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, int idx = vehs.begin() - std::find(vehs.begin(), vehs.end(), v); for (Vehicle *w : vehs) { - w->lateness_counter = 0; ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED); /* Do multiplication, then division to reduce rounding errors. */ @@ -493,7 +495,6 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, } w->timetable_start = tt_start / _settings_game.economy.day_length_factor; w->timetable_start_subticks = tt_start % _settings_game.economy.day_length_factor; - SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index); ++idx; } @@ -551,8 +552,8 @@ CommandCost CmdAutofillTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, ClrBit(v2->vehicle_flags, VF_AUTOFILL_TIMETABLE); ClrBit(v2->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); } - SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); } + SetTimetableWindowsDirty(v); } return CommandCost(); @@ -608,8 +609,8 @@ CommandCost CmdAutomateTimetable(TileIndex index, DoCommandFlag flags, uint32 p1 v2->current_loading_time = 0; } } - SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); } + SetTimetableWindowsDirty(v); if (!HasBit(p2, 0) && !HasBit(p2, 1)) { OrderList *orders = v->orders.list; if (orders != nullptr) { @@ -652,9 +653,8 @@ CommandCost CmdTimetableSeparation(TileIndex tile, DoCommandFlag flags, uint32 p ClrBit(v2->vehicle_flags, VF_TIMETABLE_SEPARATION); } v2->ClearSeparation(); - SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); - SetWindowDirty(WC_SCHDISPATCH_SLOTS, v2->index); } + SetTimetableWindowsDirty(v, true); } return CommandCost(); @@ -847,7 +847,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(real_implicit_order->GetDispatchScheduleIndex()); /* Update scheduled information */ - ds.UpdateScheduledDispatch(); + ds.UpdateScheduledDispatch(v); const int wait_offset = real_current_order->GetTimetabledWait(); DateTicksScaled slot = GetScheduledDispatchTime(ds, _scaled_date_ticks + wait_offset); @@ -867,9 +867,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) /* If the lateness is set by scheduled dispatch above, do not reset */ if (!HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) v->lateness_counter = 0; if (HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION)) UpdateSeparationOrder(v); - for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) { - SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); - } + SetTimetableWindowsDirty(v); return; } @@ -969,8 +967,8 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) /* Clear VF_TIMETABLE_STARTED but do not call ClearSeparation */ ClrBit(v2->vehicle_flags, VF_TIMETABLE_STARTED); v2->lateness_counter = 0; - SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index); } + SetTimetableWindowsDirty(v); return; } else if (new_time >= (int32)timetabled / 2) { /* Compute running average, with sign conversion to avoid negative overflow. @@ -1037,9 +1035,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) } } - for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) { - SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); - } + SetTimetableWindowsDirty(v); } void SetOrderFixedWaitTime(Vehicle *v, VehicleOrderID order_number, uint32 wait_time, bool wait_timetabled) { diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index b05c4fe253..b417b70049 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -289,9 +289,8 @@ void ProcessTimetableWarnings(const Vehicle *v, std::functionCreateNestedTree(); @@ -1197,3 +1195,13 @@ void ShowTimetableWindow(const Vehicle *v) DeleteWindowById(WC_VEHICLE_ORDERS, v->index, false); AllocateWindowDescFront(&_timetable_desc, v->index); } + +void SetTimetableWindowsDirty(const Vehicle *v, bool include_scheduled_dispatch) +{ + v = v->FirstShared(); + for (Window *w : Window::IterateFromBack()) { + if (w->window_class == WC_VEHICLE_TIMETABLE || (include_scheduled_dispatch && w->window_class == WC_SCHDISPATCH_SLOTS)) { + if (static_cast(w)->vehicle->FirstShared() == v) w->SetDirty(); + } + } +} diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 0cf1b41b9f..55317bf2b7 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2139,6 +2139,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u DeleteWindowById(WC_VEHICLE_REFIT, src->index); DeleteWindowById(WC_VEHICLE_DETAILS, src->index); DeleteWindowById(WC_VEHICLE_TIMETABLE, src->index); + DeleteWindowById(WC_SCHDISPATCH_SLOTS, src->index); DeleteNewGRFInspectWindow(GSF_TRAINS, src->index); SetWindowDirty(WC_COMPANY, _current_company); diff --git a/src/window_gui.h b/src/window_gui.h index 8b55f06e60..990938d42f 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -1102,4 +1102,10 @@ inline bool MayBeShown(const Window *w) } } +struct GeneralVehicleWindow : public Window { + const Vehicle *vehicle; + + GeneralVehicleWindow(WindowDesc *desc, const Vehicle *v) : Window(desc), vehicle(v) {} +}; + #endif /* WINDOW_GUI_H */