From 38ca44594fa71eda7c53e5c2e320020fb5cba6c8 Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 18 Aug 2010 15:15:59 +0000 Subject: [PATCH] (svn r20539) -Codechange: make order backups more self-contained. --- projects/openttd_vs100.vcxproj | 2 + projects/openttd_vs100.vcxproj.filters | 6 + projects/openttd_vs80.vcproj | 8 ++ projects/openttd_vs90.vcproj | 8 ++ source.list | 2 + src/depot_gui.cpp | 10 +- src/group_cmd.cpp | 3 +- src/misc.cpp | 2 + src/order_backup.cpp | 146 +++++++++++++++++++++++++ src/order_backup.h | 85 ++++++++++++++ src/order_cmd.cpp | 113 ------------------- src/order_func.h | 20 ---- src/vehicle_base.h | 1 + src/vehicle_gui.cpp | 7 +- 14 files changed, 270 insertions(+), 143 deletions(-) create mode 100644 src/order_backup.cpp create mode 100644 src/order_backup.h diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index b99f553bec..a48a9b692e 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -345,6 +345,7 @@ + @@ -508,6 +509,7 @@ + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 951b331fb8..724f27bcde 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -238,6 +238,9 @@ Source Files + + Source Files + Source Files @@ -727,6 +730,9 @@ Header Files + + Header Files + Header Files diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index dc4716163e..90c4d0f362 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -643,6 +643,10 @@ RelativePath=".\..\src\openttd.cpp" > + + @@ -1299,6 +1303,10 @@ RelativePath=".\..\src\openttd.h" > + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index 64d9f85c9d..622bde1ebc 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -640,6 +640,10 @@ RelativePath=".\..\src\openttd.cpp" > + + @@ -1296,6 +1300,10 @@ RelativePath=".\..\src\openttd.h" > + + diff --git a/source.list b/source.list index 986805f5e3..36086498dc 100644 --- a/source.list +++ b/source.list @@ -46,6 +46,7 @@ network/network_gamelist.cpp network/network_server.cpp network/network_udp.cpp openttd.cpp +order_backup.cpp os_timer.cpp pbs.cpp rail.cpp @@ -234,6 +235,7 @@ object.h object_base.h object_type.h openttd.h +order_backup.h order_base.h order_func.h order_type.h diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 159e6adc30..ff976fe773 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -30,6 +30,7 @@ #include "tilehighlight_func.h" #include "window_gui.h" #include "vehiclelist.h" +#include "order_backup.h" #include "table/strings.h" #include "table/sprites.h" @@ -254,8 +255,7 @@ struct DepotWindow : Window { this->FinishInitNested(desc, tile); this->owner = GetTileOwner(tile); - _backup_orders_tile = 0; - + OrderBackup::Reset(); } ~DepotWindow() @@ -979,11 +979,11 @@ struct DepotWindow : Window { bool is_engine = (v->type != VEH_TRAIN || Train::From(v)->IsFrontEngine()); if (is_engine) { - _backup_orders_tile = v->tile; - BackupVehicleOrders(v); + OrderBackup::Reset(); + new OrderBackup(v); } - if (!DoCommandP(v->tile, v->index | sell_cmd << 16, 0, GetCmdSellVeh(v->type)) && is_engine) _backup_orders_tile = 0; + if (!DoCommandP(v->tile, v->index | sell_cmd << 16, 0, GetCmdSellVeh(v->type)) && is_engine) OrderBackup::Reset(); break; } diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 6585d5084a..725acab3e6 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -23,6 +23,7 @@ #include "string_func.h" #include "company_func.h" #include "core/pool_func.hpp" +#include "order_backup.h" #include "table/strings.h" @@ -126,7 +127,7 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } /* Update backupped orders if needed */ - if (_backup_orders_data.group == g->index) _backup_orders_data.group = DEFAULT_GROUP; + OrderBackup::ClearGroup(g->index); /* If we set an autoreplace for the group we delete, remove it. */ if (_current_company < MAX_COMPANIES) { diff --git a/src/misc.cpp b/src/misc.cpp index b0f2dd35d4..6d6fa7232f 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -36,6 +36,7 @@ void InitializeVehicles(); void InitializeDepots(); void InitializeEngineRenews(); void InitializeOrders(); +void InitializeOrderBackups(); void InitializeClearLand(); void InitializeRailGui(); void InitializeRoadGui(); @@ -83,6 +84,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin InitializeVehicles(); InitializeDepots(); InitializeOrders(); + InitializeOrderBackups(); InitializeGroup(); InitNewsItemStructs(); diff --git a/src/order_backup.cpp b/src/order_backup.cpp new file mode 100644 index 0000000000..3a462e3ce6 --- /dev/null +++ b/src/order_backup.cpp @@ -0,0 +1,146 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file order_backup.cpp Handling of order backups. */ + +#include "stdafx.h" +#include "command_func.h" +#include "core/pool_func.hpp" +#include "order_backup.h" +#include "order_base.h" +#include "vehicle_base.h" +#include "settings_type.h" + +OrderBackupPool _order_backup_pool("BackupOrder"); +INSTANTIATE_POOL_METHODS(OrderBackup) + +OrderBackup::~OrderBackup() +{ + free(this->name); + free(this->orders); +} + +OrderBackup::OrderBackup(const Vehicle *v) +{ + this->tile = v->tile; + this->orderindex = v->cur_order_index; + this->group = v->group_id; + this->service_interval = v->service_interval; + + if (v->name != NULL) this->name = strdup(v->name); + + /* If we have shared orders, store the vehicle we share the order with. */ + if (v->IsOrderListShared()) { + const Vehicle *u = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared(); + + this->clone = u->index; + } else { + /* Else copy the orders */ + + /* We do not have shared orders */ + this->clone = INVALID_VEHICLE; + + /* Count the number of orders */ + uint cnt = 0; + const Order *order; + FOR_VEHICLE_ORDERS(v, order) cnt++; + + /* Allocate memory for the orders plus an end-of-orders marker */ + this->orders = MallocT(cnt + 1); + + Order *dest = this->orders; + + /* Copy the orders */ + FOR_VEHICLE_ORDERS(v, order) { + memcpy(dest, order, sizeof(Order)); + dest++; + } + /* End the list with an empty order */ + dest->Free(); + } +} + +void OrderBackup::RestoreTo(const Vehicle *v) +{ + /* If we have a custom name, process that */ + if (this->name != NULL) DoCommandP(0, v->index, 0, CMD_RENAME_VEHICLE, NULL, this->name); + + /* If we had shared orders, recover that */ + if (this->clone != INVALID_VEHICLE) { + DoCommandP(0, v->index | (this->clone << 16), CO_SHARE, CMD_CLONE_ORDER); + } else { + + /* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the + * order number is one more than the current amount of orders, and because + * in network the commands are queued before send, the second insert always + * fails in test mode. By bypassing the test-mode, that no longer is a problem. */ + for (uint i = 0; !this->orders[i].IsType(OT_NOTHING); i++) { + Order o = this->orders[i]; + /* Conditional orders need to have their destination to be valid on insertion. */ + if (o.IsType(OT_CONDITIONAL)) o.SetConditionSkipToOrder(0); + + if (!DoCommandP(0, v->index + (i << 16), o.Pack(), + CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) { + break; + } + + /* Copy timetable if enabled */ + if (_settings_game.order.timetabling && !DoCommandP(0, v->index | (i << 16) | (1 << 25), + o.wait_time << 16 | o.travel_time, + CMD_CHANGE_TIMETABLE | CMD_NO_TEST_IF_IN_NETWORK)) { + break; + } + } + + /* Fix the conditional orders' destination. */ + for (uint i = 0; !this->orders[i].IsType(OT_NOTHING); i++) { + if (!this->orders[i].IsType(OT_CONDITIONAL)) continue; + + if (!DoCommandP(0, v->index + (i << 16), MOF_LOAD | (this->orders[i].GetConditionSkipToOrder() << 4), + CMD_MODIFY_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) { + break; + } + } + } + + /* Restore vehicle order-index and service interval */ + DoCommandP(0, v->index, this->orderindex | (this->service_interval << 16), CMD_RESTORE_ORDER_INDEX); + + /* Restore vehicle group */ + DoCommandP(0, this->group, v->index, CMD_ADD_VEHICLE_GROUP); + + delete this; +} + +/* static */ OrderBackup *OrderBackup::GetByTile(TileIndex t) +{ + OrderBackup *ob; + FOR_ALL_ORDER_BACKUPS(ob) { + if (ob->tile == t) return ob; + } + return NULL; +} + +/* static */ void OrderBackup::Reset() +{ + _order_backup_pool.CleanPool(); +} + +/* static */ void OrderBackup::ClearGroup(GroupID group) +{ + OrderBackup *ob; + FOR_ALL_ORDER_BACKUPS(ob) { + if (ob->group == group) ob->group = DEFAULT_GROUP; + } +} + +void InitializeOrderBackups() +{ + _order_backup_pool.CleanPool(); +} diff --git a/src/order_backup.h b/src/order_backup.h new file mode 100644 index 0000000000..a64c9b4fb6 --- /dev/null +++ b/src/order_backup.h @@ -0,0 +1,85 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file order_backup.h Functions related to order backups. */ + +#ifndef ORDER_BACKUP_H +#define ORDER_BACKUP_H + +#include "core/pool_type.hpp" +#include "order_type.h" +#include "vehicle_type.h" +#include "tile_type.h" +#include "group_type.h" +#include "company_type.h" + +/** Unique identifier for an order backup. */ +typedef uint8 OrderBackupID; +struct OrderBackup; + +/** The pool type for order backups. */ +typedef Pool OrderBackupPool; +/** The pool with order backups. */ +extern OrderBackupPool _order_backup_pool; + +/** + * Data for backing up an order of a vehicle so it can be + * restored after a vehicle is rebuilt in the same depot. + */ +struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool> { +private: + TileIndex tile; ///< Tile of the depot where the order was changed. + GroupID group; ///< The group the vehicle was part of. + uint16 service_interval; ///< The service interval of the vehicle. + char *name; ///< The custom name of the vehicle. + + VehicleID clone; ///< VehicleID this vehicle was a clone of, or INVALID_VEHICLE. + VehicleOrderID orderindex; ///< The order-index the vehicle had. + Order *orders; ///< The actual orders if the vehicle was not a clone. + +public: + /** + * Create an order backup for the given vehicle. + * @param v The vehicle to make a backup of. + */ + OrderBackup(const Vehicle *v); + + /** Free everything that is allocated. */ + ~OrderBackup(); + + /** + * Restore the data of this order to the given vehicle. + * @param v The vehicle to restore to. + * @note After restoration the backup will automatically be removed. + */ + void RestoreTo(const Vehicle *v); + + /** + * Get the order backup associated with a given tile. + * @param t The tile to get the order backup for. + * @return The order backup, or NULL if it doesn't exist. + */ + static OrderBackup *GetByTile(TileIndex t); + + /** + * Reset the OrderBackups. + */ + static void Reset(); + + /** + * Clear the group of all backups having this group ID. + * @param group The group to clear + */ + static void ClearGroup(GroupID group); +}; + +#define FOR_ALL_ORDER_BACKUPS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderBackup, order_backup_index, var, start) +#define FOR_ALL_ORDER_BACKUPS(var) FOR_ALL_ORDER_BACKUPS_FROM(var, 0) + +#endif /* ORDER_BACKUP_H */ diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 98b4b316ef..2a3e998f8c 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -37,9 +37,6 @@ assert_compile(sizeof(DestinationID) >= sizeof(DepotID)); assert_compile(sizeof(DestinationID) >= sizeof(StationID)); -TileIndex _backup_orders_tile; -BackuppedOrders _backup_orders_data; - OrderPool _order_pool("Order"); INSTANTIATE_POOL_METHODS(Order) OrderListPool _orderlist_pool("OrderList"); @@ -1331,113 +1328,6 @@ CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return CommandCost(); } -/** - * - * Backup a vehicle order-list, so you can replace a vehicle - * without losing the order-list - * - */ -void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *bak) -{ - /* Make sure we always have freed the stuff */ - free(bak->order); - bak->order = NULL; - free(bak->name); - bak->name = NULL; - - /* Save general info */ - bak->orderindex = v->cur_order_index; - bak->group = v->group_id; - bak->service_interval = v->service_interval; - if (v->name != NULL) bak->name = strdup(v->name); - - /* If we have shared orders, store it on a special way */ - if (v->IsOrderListShared()) { - const Vehicle *u = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared(); - - bak->clone = u->index; - } else { - /* Else copy the orders */ - - /* We do not have shared orders */ - bak->clone = INVALID_VEHICLE; - - - /* Count the number of orders */ - uint cnt = 0; - const Order *order; - FOR_VEHICLE_ORDERS(v, order) cnt++; - - /* Allocate memory for the orders plus an end-of-orders marker */ - bak->order = MallocT(cnt + 1); - - Order *dest = bak->order; - - /* Copy the orders */ - FOR_VEHICLE_ORDERS(v, order) { - memcpy(dest, order, sizeof(Order)); - dest++; - } - /* End the list with an empty order */ - dest->Free(); - } -} - -/** - * - * Restore vehicle orders that are backupped via BackupVehicleOrders - * - */ -void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *bak) -{ - /* If we have a custom name, process that */ - if (bak->name != NULL) DoCommandP(0, v->index, 0, CMD_RENAME_VEHICLE, NULL, bak->name); - - /* If we had shared orders, recover that */ - if (bak->clone != INVALID_VEHICLE) { - DoCommandP(0, v->index | (bak->clone << 16), CO_SHARE, CMD_CLONE_ORDER); - } else { - - /* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the - * order number is one more than the current amount of orders, and because - * in network the commands are queued before send, the second insert always - * fails in test mode. By bypassing the test-mode, that no longer is a problem. */ - for (uint i = 0; !bak->order[i].IsType(OT_NOTHING); i++) { - Order o = bak->order[i]; - /* Conditional orders need to have their destination to be valid on insertion. */ - if (o.IsType(OT_CONDITIONAL)) o.SetConditionSkipToOrder(0); - - if (!DoCommandP(0, v->index + (i << 16), o.Pack(), - CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) { - break; - } - - /* Copy timetable if enabled */ - if (_settings_game.order.timetabling && !DoCommandP(0, v->index | (i << 16) | (1 << 25), - o.wait_time << 16 | o.travel_time, - CMD_CHANGE_TIMETABLE | CMD_NO_TEST_IF_IN_NETWORK)) { - break; - } - } - - /* Fix the conditional orders' destination. */ - for (uint i = 0; !bak->order[i].IsType(OT_NOTHING); i++) { - if (!bak->order[i].IsType(OT_CONDITIONAL)) continue; - - if (!DoCommandP(0, v->index + (i << 16), MOF_LOAD | (bak->order[i].GetConditionSkipToOrder() << 4), - CMD_MODIFY_ORDER | CMD_NO_TEST_IF_IN_NETWORK)) { - break; - } - } - } - - /* Restore vehicle order-index and service interval */ - DoCommandP(0, v->index, bak->orderindex | (bak->service_interval << 16), CMD_RESTORE_ORDER_INDEX); - - /* Restore vehicle group */ - DoCommandP(0, bak->group, v->index, CMD_ADD_VEHICLE_GROUP); -} - /** * Restore the current order-index of a vehicle and sets service-interval. * @param tile unused @@ -1904,8 +1794,5 @@ bool Order::ShouldStopAtStation(const Vehicle *v, StationID station) const void InitializeOrders() { _order_pool.CleanPool(); - _orderlist_pool.CleanPool(); - - _backup_orders_tile = 0; } diff --git a/src/order_func.h b/src/order_func.h index e1ff810fe6..5736cb0ca0 100644 --- a/src/order_func.h +++ b/src/order_func.h @@ -14,28 +14,8 @@ #include "order_type.h" #include "vehicle_type.h" -#include "tile_type.h" -#include "group_type.h" #include "company_type.h" -struct BackuppedOrders { - BackuppedOrders() : order(NULL), name(NULL) { } - ~BackuppedOrders() { free(order); free(name); } - - VehicleID clone; - VehicleOrderID orderindex; - GroupID group; - Order *order; - uint16 service_interval; - char *name; -}; - -extern TileIndex _backup_orders_tile; -extern BackuppedOrders _backup_orders_data; - -void BackupVehicleOrders(const Vehicle *v, BackuppedOrders *order = &_backup_orders_data); -void RestoreVehicleOrders(const Vehicle *v, const BackuppedOrders *order = &_backup_orders_data); - /* Functions */ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination); void InvalidateVehicleOrder(const Vehicle *v, int data); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index c2bc0e8db5..ea7d70baef 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -21,6 +21,7 @@ #include "engine_type.h" #include "order_func.h" #include "transport_type.h" +#include "group_type.h" enum VehStatus { VS_HIDDEN = 0x01, diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 33b3e79d3a..7d62184aa6 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -44,6 +44,7 @@ #include "engine_func.h" #include "newgrf.h" #include "station_base.h" +#include "order_backup.h" #include "table/sprites.h" #include "table/strings.h" @@ -2372,9 +2373,7 @@ void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, if (result.Failed()) return; const Vehicle *v = Vehicle::Get(_new_vehicle_id); - if (v->tile == _backup_orders_tile) { - _backup_orders_tile = 0; - RestoreVehicleOrders(v); - } + OrderBackup *ob = OrderBackup::GetByTile(v->tile); + if (ob != NULL) ob->RestoreTo(v); ShowVehicleViewWindow(v); }