From 2637c06f88ed6f9dea55449883f42a62c30f19d8 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Thu, 4 Nov 2021 00:10:13 +0100 Subject: [PATCH] Codechange: Un-bitstuff timetable commands. --- src/date_gui.cpp | 11 ++++--- src/date_gui.h | 4 +-- src/order_type.h | 2 +- src/timetable_cmd.cpp | 68 ++++++++++++++----------------------------- src/timetable_cmd.h | 8 ++--- src/timetable_gui.cpp | 33 +++++++++------------ 6 files changed, 50 insertions(+), 76 deletions(-) diff --git a/src/date_gui.cpp b/src/date_gui.cpp index 9327287201..66c9a378a3 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -24,6 +24,7 @@ /** Window to select a date graphically by using dropdowns */ struct SetDateWindow : Window { SetDateCallback *callback; ///< Callback to call when a date has been selected + void *callback_data; ///< Callback data pointer. YearMonthDay date; ///< The currently selected date Year min_year; ///< The minimum year in the year dropdown Year max_year; ///< The maximum year (inclusive) in the year dropdown @@ -38,9 +39,10 @@ struct SetDateWindow : Window { * @param max_year the maximum year (inclusive) to show in the year dropdown * @param callback the callback to call once a date has been selected */ - SetDateWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback) : + SetDateWindow(WindowDesc *desc, WindowNumber window_number, Window *parent, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback, void *callback_data) : Window(desc), callback(callback), + callback_data(callback_data), min_year(std::max(MIN_YEAR, min_year)), max_year(std::min(MAX_YEAR, max_year)) { @@ -146,7 +148,7 @@ struct SetDateWindow : Window { break; case WID_SD_SET_DATE: - if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day)); + if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day), this->callback_data); this->Close(); break; } @@ -209,9 +211,10 @@ static WindowDesc _set_date_desc( * @param min_year the minimum year to show in the year dropdown * @param max_year the maximum year (inclusive) to show in the year dropdown * @param callback the callback to call once a date has been selected + * @param callback_data extra callback data */ -void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback) +void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback, void *callback_data) { CloseWindowByClass(WC_SET_DATE); - new SetDateWindow(&_set_date_desc, window_number, parent, initial_date, min_year, max_year, callback); + new SetDateWindow(&_set_date_desc, window_number, parent, initial_date, min_year, max_year, callback, callback_data); } diff --git a/src/date_gui.h b/src/date_gui.h index 8d41ee3e71..da866d01f5 100644 --- a/src/date_gui.h +++ b/src/date_gui.h @@ -18,8 +18,8 @@ * @param w the window that sends the callback * @param date the date that has been chosen */ -typedef void SetDateCallback(const Window *w, Date date); +typedef void SetDateCallback(const Window *w, Date date, void *data); -void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback); +void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback, void *callback_data); #endif /* DATE_GUI_H */ diff --git a/src/order_type.h b/src/order_type.h index 6743529078..1a0687794a 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -167,7 +167,7 @@ enum OrderDepotAction { /** * Enumeration for the data to set in #CmdChangeTimetable. */ -enum ModifyTimetableFlags { +enum ModifyTimetableFlags : byte { MTF_WAIT_TIME, ///< Set wait time. MTF_TRAVEL_TIME, ///< Set travel time. MTF_TRAVEL_SPEED, ///< Set max travel speed. diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index c889e5374f..3e5695b51a 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -87,32 +87,24 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, /** * Change timetable data of an order. * @param flags Operation to perform. - * @param tile Not used. - * @param p1 Various bitstuffed elements - * - p1 = (bit 0-19) - Vehicle with the orders to change. - * - p1 = (bit 20-27) - Order index to modify. - * - p1 = (bit 28-29) - Timetable data to change (@see ModifyTimetableFlags) - * @param p2 The amount of time to wait. - * - p2 = (bit 0-15) - The data to modify as specified by p1 bits 28-29. - * 0 to clear times, UINT16_MAX to clear speed limit. - * @param text unused + * @param veh Vehicle with the orders to change. + * @param order_number Order index to modify. + * @param mtf Timetable data to change (@see ModifyTimetableFlags) + * @param data The data to modify as specified by \c mtf. + * 0 to clear times, UINT16_MAX to clear speed limit. * @return the cost of this operation or an error */ -CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16 data) { - VehicleID veh = GB(p1, 0, 20); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; - VehicleOrderID order_number = GB(p1, 20, 8); Order *order = v->GetOrder(order_number); if (order == nullptr || order->IsType(OT_IMPLICIT)) return CMD_ERROR; - ModifyTimetableFlags mtf = Extract(p1); if (mtf >= MTF_END) return CMD_ERROR; int wait_time = order->GetWaitTime(); @@ -120,15 +112,15 @@ CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, u int max_speed = order->GetMaxSpeed(); switch (mtf) { case MTF_WAIT_TIME: - wait_time = GB(p2, 0, 16); + wait_time = data; break; case MTF_TRAVEL_TIME: - travel_time = GB(p2, 0, 16); + travel_time = data; break; case MTF_TRAVEL_SPEED: - max_speed = GB(p2, 0, 16); + max_speed = data; if (max_speed == 0) max_speed = UINT16_MAX; // Disable speed limit. break; @@ -185,17 +177,11 @@ CommandCost CmdChangeTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, u /** * Clear the lateness counter to make the vehicle on time. * @param flags Operation to perform. - * @param tile Not used. - * @param p1 Various bitstuffed elements - * - p1 = (bit 0-19) - Vehicle with the orders to change. - * @param p2 unused - * @param text unused + * @param veh Vehicle with the orders to change. * @return the cost of this operation or an error */ -CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh) { - VehicleID veh = GB(p1, 0, 20); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; @@ -251,25 +237,20 @@ static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b) /** * Set the start date of the timetable. * @param flags Operation to perform. - * @param tile Not used. - * @param p2 Various bitstuffed elements - * - p2 = (bit 0-19) - Vehicle ID. - * - p2 = (bit 20) - Set to 1 to set timetable start for all vehicles sharing this order - * @param p2 The timetable start date. - * @param text Not used. + * @param veh_id Vehicle ID. + * @param timetable_all Set to set timetable start for all vehicles sharing this order + * @param start_date The timetable start date. * @return The error or cost of the operation. */ -CommandCost CmdSetTimetableStart(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, Date start_date) { - bool timetable_all = HasBit(p1, 20); - Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); + Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; /* Don't let a timetable start more than 15 years into the future or 1 year in the past. */ - Date start_date = (Date)p2; if (start_date < 0 || start_date > MAX_DAY) return CMD_ERROR; if (start_date - _date > 15 * DAYS_IN_LEAP_YEAR) return CMD_ERROR; if (_date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR; @@ -316,18 +297,13 @@ CommandCost CmdSetTimetableStart(DoCommandFlag flags, TileIndex tile, uint32 p1, * actually takes to complete it. When starting to autofill the current times * are cleared and the timetable will start again from scratch. * @param flags Operation to perform. - * @param tile Not used. - * @param p1 Vehicle index. - * @param p2 Various bitstuffed elements - * - p2 = (bit 0) - Set to 1 to enable, 0 to disable autofill. - * - p2 = (bit 1) - Set to 1 to preserve waiting times in non-destructive mode - * @param text unused + * @param veh Vehicle index. + * @param autofill Enable or disable autofill + * @param preserve_wait_time Set to preserve waiting times in non-destructive mode * @return the cost of this operation or an error */ -CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, uint32 p2, const std::string &text) +CommandCost CmdAutofillTimetable(DoCommandFlag flags, VehicleID veh, bool autofill, bool preserve_wait_time) { - VehicleID veh = GB(p1, 0, 20); - Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; @@ -335,7 +311,7 @@ CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, if (ret.Failed()) return ret; if (flags & DC_EXEC) { - if (HasBit(p2, 0)) { + if (autofill) { /* Start autofilling the timetable, which clears the * "timetable has started" bit. Times are not cleared anymore, but are * overwritten when the order is reached now. */ @@ -343,7 +319,7 @@ CommandCost CmdAutofillTimetable(DoCommandFlag flags, TileIndex tile, uint32 p1, ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED); /* Overwrite waiting times only if they got longer */ - if (HasBit(p2, 1)) SetBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); + if (preserve_wait_time) SetBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); v->timetable_start = 0; v->lateness_counter = 0; diff --git a/src/timetable_cmd.h b/src/timetable_cmd.h index ba5e2b37e2..ddf1277372 100644 --- a/src/timetable_cmd.h +++ b/src/timetable_cmd.h @@ -12,10 +12,10 @@ #include "command_type.h" -CommandProc CmdChangeTimetable; -CommandProc CmdSetVehicleOnTime; -CommandProc CmdAutofillTimetable; -CommandProc CmdSetTimetableStart; +CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16 data); +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh); +CommandCost CmdAutofillTimetable(DoCommandFlag flags, VehicleID veh, bool autofill, bool preserve_wait_time); +CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, Date start_date); DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT) diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 12c3914875..9a09bce365 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -23,6 +23,7 @@ #include "vehicle_gui.h" #include "settings_type.h" #include "timetable_cmd.h" +#include #include "widgets/timetable_widget.h" @@ -141,9 +142,9 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID * @param w the window related to the setting of the date * @param date the actually chosen date */ -static void ChangeTimetableStartCallback(const Window *w, Date date) +static void ChangeTimetableStartCallback(const Window *w, Date date, void *data) { - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, w->window_number, date, {}); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, (VehicleID)w->window_number, reinterpret_cast(data) != 0, date); } @@ -502,14 +503,14 @@ struct TimetableWindow : Window { } } - static inline uint32 PackTimetableArgs(const Vehicle *v, uint selected, bool speed) + static inline std::tuple PackTimetableArgs(const Vehicle *v, uint selected, bool speed) { uint order_number = (selected + 1) / 2; ModifyTimetableFlags mtf = (selected % 2 == 1) ? (speed ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME; if (order_number >= v->GetNumOrders()) order_number = 0; - return v->index | (order_number << 20) | (mtf << 28); + return { order_number, mtf }; } void OnClick(Point pt, int widget, int click_count) override @@ -530,7 +531,7 @@ struct TimetableWindow : Window { } case WID_VT_START_DATE: // Change the date that the timetable starts. - ShowSetDateWindow(this, v->index | (v->orders.list->IsCompleteTimetable() && _ctrl_pressed ? 1U << 20 : 0), _date, _cur_year, _cur_year + 15, ChangeTimetableStartCallback); + ShowSetDateWindow(this, v->index, _date, _cur_year, _cur_year + 15, ChangeTimetableStartCallback, reinterpret_cast(static_cast(v->orders.list->IsCompleteTimetable() && _ctrl_pressed))); break; case WID_VT_CHANGE_TIME: { // "Wait For" button. @@ -578,26 +579,23 @@ struct TimetableWindow : Window { } case WID_VT_CLEAR_TIME: { // Clear waiting time. - uint32 p1 = PackTimetableArgs(v, this->sel_index, false); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, 0, {}); + auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, false); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, 0); break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. - uint32 p1 = PackTimetableArgs(v, this->sel_index, true); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, UINT16_MAX, {}); + auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, true); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, UINT16_MAX); break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, 0, {}); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index); break; case WID_VT_AUTOFILL: { // Autofill the timetable. - uint32 p2 = 0; - if (!HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(p2, 0); - if (_ctrl_pressed) SetBit(p2, 1); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, v->index, p2, {}); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, !HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE), _ctrl_pressed); break; } @@ -619,8 +617,6 @@ struct TimetableWindow : Window { const Vehicle *v = this->vehicle; - uint32 p1 = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); - uint64 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10); if (this->query_is_speed_query) { val = ConvertDisplaySpeedToKmhishSpeed(val); @@ -628,9 +624,8 @@ struct TimetableWindow : Window { if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS; } - uint32 p2 = std::min(val, UINT16_MAX); - - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, 0, p1, p2, {}); + auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, std::min(val, UINT16_MAX)); } void OnResize() override