Mercurial > hg > openttd
changeset 15857:9a9ec79c5d25 draft
(svn r20539) -Codechange: make order backups more self-contained.
author | rubidium <rubidium@openttd.org> |
---|---|
date | Wed, 18 Aug 2010 15:15:59 +0000 |
parents | 33f7ff76add8 |
children | f6f00bb2a6fc |
files | projects/openttd_vs100.vcxproj projects/openttd_vs100.vcxproj.filters projects/openttd_vs80.vcproj projects/openttd_vs90.vcproj source.list src/depot_gui.cpp src/group_cmd.cpp src/misc.cpp src/order_backup.cpp src/order_backup.h src/order_cmd.cpp src/order_func.h src/vehicle_base.h src/vehicle_gui.cpp |
diffstat | 14 files changed, 270 insertions(+), 143 deletions(-) [+] |
line wrap: on
line diff
--- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -345,6 +345,7 @@ <ClCompile Include="..\src\network\network_server.cpp" /> <ClCompile Include="..\src\network\network_udp.cpp" /> <ClCompile Include="..\src\openttd.cpp" /> + <ClCompile Include="..\src\order_backup.cpp" /> <ClCompile Include="..\src\os_timer.cpp" /> <ClCompile Include="..\src\pbs.cpp" /> <ClCompile Include="..\src\rail.cpp" /> @@ -508,6 +509,7 @@ <ClInclude Include="..\src\object_base.h" /> <ClInclude Include="..\src\object_type.h" /> <ClInclude Include="..\src\openttd.h" /> + <ClInclude Include="..\src\order_backup.h" /> <ClInclude Include="..\src\order_base.h" /> <ClInclude Include="..\src\order_func.h" /> <ClInclude Include="..\src\order_type.h" />
--- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -238,6 +238,9 @@ <ClCompile Include="..\src\openttd.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\src\order_backup.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\src\os_timer.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -727,6 +730,9 @@ <ClInclude Include="..\src\openttd.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\src\order_backup.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="..\src\order_base.h"> <Filter>Header Files</Filter> </ClInclude>
--- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -644,6 +644,10 @@ > </File> <File + RelativePath=".\..\src\order_backup.cpp" + > + </File> + <File RelativePath=".\..\src\os_timer.cpp" > </File> @@ -1300,6 +1304,10 @@ > </File> <File + RelativePath=".\..\src\order_backup.h" + > + </File> + <File RelativePath=".\..\src\order_base.h" > </File>
--- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -641,6 +641,10 @@ > </File> <File + RelativePath=".\..\src\order_backup.cpp" + > + </File> + <File RelativePath=".\..\src\os_timer.cpp" > </File> @@ -1297,6 +1301,10 @@ > </File> <File + RelativePath=".\..\src\order_backup.h" + > + </File> + <File RelativePath=".\..\src\order_base.h" > </File>
--- a/source.list +++ b/source.list @@ -46,6 +46,7 @@ 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_base.h object_type.h openttd.h +order_backup.h order_base.h order_func.h order_type.h
--- 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 @@ this->FinishInitNested(desc, tile); this->owner = GetTileOwner(tile); - _backup_orders_tile = 0; - + OrderBackup::Reset(); } ~DepotWindow() @@ -979,11 +979,11 @@ 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; }
--- 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 @@ } /* 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) {
--- a/src/misc.cpp +++ b/src/misc.cpp @@ -36,6 +36,7 @@ void InitializeDepots(); void InitializeEngineRenews(); void InitializeOrders(); +void InitializeOrderBackups(); void InitializeClearLand(); void InitializeRailGui(); void InitializeRoadGui(); @@ -83,6 +84,7 @@ InitializeVehicles(); InitializeDepots(); InitializeOrders(); + InitializeOrderBackups(); InitializeGroup(); InitNewsItemStructs();
new file mode 100644 --- /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 <http://www.gnu.org/licenses/>. + */ + +/** @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<Order>(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(); +}
new file mode 100644 --- /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 <http://www.gnu.org/licenses/>. + */ + +/** @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<OrderBackup, OrderBackupID, 1, 256> 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 */
--- 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"); @@ -1332,113 +1329,6 @@ } /** - * - * 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<Order>(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 * @param flags operation to perform @@ -1904,8 +1794,5 @@ void InitializeOrders() { _order_pool.CleanPool(); - _orderlist_pool.CleanPool(); - - _backup_orders_tile = 0; }
--- 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);
--- 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,
--- 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 @@ 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); }