From 9db3cde73af598852da13b748eef31a8207cfcf2 Mon Sep 17 00:00:00 2001 From: frosch Date: Mon, 31 May 2010 20:22:57 +0000 Subject: [PATCH] (svn r19914) -Codechange: Wrap a helper class around temporary assignments of _current_company to ensure proper restoration. --- projects/openttd_vs80.vcproj | 4 ++ projects/openttd_vs90.vcproj | 4 ++ source.list | 1 + src/ai/ai_core.cpp | 32 ++++----- src/ai/ai_gui.cpp | 21 +++--- src/aircraft_cmd.cpp | 18 +++-- src/core/backup_type.hpp | 134 +++++++++++++++++++++++++++++++++++ src/disaster_cmd.cpp | 11 ++- src/economy.cpp | 33 ++++----- src/industry_cmd.cpp | 43 +++++------ src/industry_gui.cpp | 5 +- src/misc_cmd.cpp | 6 +- src/openttd.cpp | 6 +- src/rail_cmd.cpp | 8 ++- src/roadveh_cmd.cpp | 6 +- src/saveload/afterload.cpp | 4 +- src/town_cmd.cpp | 19 +++-- src/vehicle.cpp | 9 ++- src/water_cmd.cpp | 9 +-- 19 files changed, 256 insertions(+), 117 deletions(-) create mode 100644 src/core/backup_type.hpp diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index 0b99a237db..524141cf3f 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1675,6 +1675,10 @@ RelativePath=".\..\src\core\alloc_type.hpp" > + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index 159f080627..2fb14141ad 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1672,6 +1672,10 @@ RelativePath=".\..\src\core\alloc_type.hpp" > + + diff --git a/source.list b/source.list index 3150a8175d..05efb1f1f1 100644 --- a/source.list +++ b/source.list @@ -344,6 +344,7 @@ video/cocoa/cocoa_v.h core/alloc_func.cpp core/alloc_func.hpp core/alloc_type.hpp +core/backup_type.hpp core/bitmath_func.cpp core/bitmath_func.hpp core/endian_func.hpp diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index 02868e9bd0..f61bc058c8 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -10,6 +10,7 @@ /** @file ai_core.cpp Implementation of AI. */ #include "../stdafx.h" +#include "../core/backup_type.hpp" #include "../core/bitmath_func.hpp" #include "../company_base.h" #include "../company_func.h" @@ -68,13 +69,15 @@ assert(_settings_game.difficulty.competitor_speed <= 4); if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return; + Backup cur_company(_current_company); const Company *c; FOR_ALL_COMPANIES(c) { if (c->is_ai) { - _current_company = c->index; + cur_company.Change(c->index); c->ai_instance->GameLoop(); } } + cur_company.Restore(); /* Occasionally collect garbage; every 255 ticks do one company. * Effectively collecting garbage once every two months per AI. */ @@ -82,8 +85,6 @@ CompanyID cid = (CompanyID)GB(AI::frame_counter, 8, 4); if (Company::IsValidAiID(cid)) Company::Get(cid)->ai_instance->CollectGarbage(); } - - _current_company = OWNER_NONE; } /* static */ uint AI::GetTick() @@ -95,14 +96,13 @@ { if (_networking && !_network_server) return; - CompanyID old_company = _current_company; - _current_company = company; + Backup cur_company(_current_company, company); Company *c = Company::Get(company); delete c->ai_instance; c->ai_instance = NULL; - _current_company = old_company; + cur_company.Restore(); InvalidateWindowData(WC_AI_DEBUG, 0, -1); DeleteWindowById(WC_AI_SETTINGS, company); @@ -112,11 +112,10 @@ { if (_networking && !_network_server) return; - CompanyID old_company = _current_company; - _current_company = company; + Backup cur_company(_current_company, company); Company::Get(company)->ai_instance->Suspend(); - _current_company = old_company; + cur_company.Restore(); } /* static */ void AI::KillAll() @@ -202,10 +201,9 @@ } /* Queue the event */ - CompanyID old_company = _current_company; - _current_company = company; + Backup cur_company(_current_company, company); AIEventController::InsertEvent(event); - _current_company = old_company; + cur_company.Restore(); event->Release(); } @@ -249,10 +247,9 @@ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) Company *c = Company::GetIfValid(company); assert(c != NULL && c->ai_instance != NULL); - CompanyID old_company = _current_company; - _current_company = company; + Backup cur_company(_current_company, company); c->ai_instance->Save(); - _current_company = old_company; + cur_company.Restore(); } else { AIInstance::SaveEmpty(); } @@ -264,10 +261,9 @@ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) Company *c = Company::GetIfValid(company); assert(c != NULL && c->ai_instance != NULL); - CompanyID old_company = _current_company; - _current_company = company; + Backup cur_company(_current_company, company); c->ai_instance->Load(version); - _current_company = old_company; + cur_company.Restore(); } else { /* Read, but ignore, the load data */ AIInstance::LoadEmpty(); diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 57e8d0c241..afad432f6c 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -26,6 +26,7 @@ #include "../textbuf_gui.h" #include "../settings_func.h" #include "../network/network_content.h" +#include "../core/backup_type.hpp" #include "ai.hpp" #include "api/ai_log.hpp" @@ -819,10 +820,9 @@ struct AIDebugWindow : public QueryStringBaseWindow { DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget(AID_WIDGET_COMPANY_BUTTON_START + i)->pos_y + 2 + offset); } - CompanyID old_company = _current_company; - _current_company = ai_debug_company; + Backup cur_company(_current_company, ai_debug_company); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); - _current_company = old_company; + cur_company.Restore(); int scroll_count = (log == NULL) ? 0 : log->used; if (this->vscroll.GetCount() != scroll_count) { @@ -875,10 +875,9 @@ struct AIDebugWindow : public QueryStringBaseWindow { switch (widget) { case AID_WIDGET_LOG_PANEL: { - CompanyID old_company = _current_company; - _current_company = ai_debug_company; + Backup cur_company(_current_company, ai_debug_company); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); - _current_company = old_company; + cur_company.Restore(); if (log == NULL) return; int y = this->top_offset; @@ -915,10 +914,9 @@ struct AIDebugWindow : public QueryStringBaseWindow { this->RaiseWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START); ai_debug_company = show_ai; - CompanyID old_company = _current_company; - _current_company = ai_debug_company; + Backup cur_company(_current_company, ai_debug_company); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); - _current_company = old_company; + cur_company.Restore(); this->vscroll.SetCount((log == NULL) ? 0 : log->used); this->LowerWidget(ai_debug_company + AID_WIDGET_COMPANY_BUTTON_START); @@ -1011,8 +1009,7 @@ struct AIDebugWindow : public QueryStringBaseWindow { /* If the log message is related to the active company tab, check the break string */ if (data == ai_debug_company && this->break_check_enabled && !StrEmpty(this->edit_str_buf)) { /* Get the log instance of the active company */ - CompanyID old_company = _current_company; - _current_company = ai_debug_company; + Backup cur_company(_current_company, ai_debug_company); AILog::LogData *log = (AILog::LogData *)AIObject::GetLogPointer(); if (log != NULL && case_sensitive_break_check? @@ -1032,7 +1029,7 @@ struct AIDebugWindow : public QueryStringBaseWindow { this->highlight_row = log->pos; } - _current_company = old_company; + cur_company.Restore(); } } diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 4e3a1168ff..450eb8b9b4 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -36,6 +36,7 @@ #include "engine_base.h" #include "engine_func.h" #include "core/random_func.hpp" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/sprites.h" @@ -1203,12 +1204,9 @@ void HandleMissingAircraftOrders(Aircraft *v) */ const Station *st = GetTargetAirportIfValid(v); if (st == NULL) { - CommandCost ret; - CompanyID old_company = _current_company; - - _current_company = v->owner; - ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); - _current_company = old_company; + Backup cur_company(_current_company, v->owner); + CommandCost ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); + cur_company.Restore(); if (ret.Failed()) CrashAirplane(v); } else if (!v->current_order.IsType(OT_GOTO_DEPOT)) { @@ -1512,9 +1510,9 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass /* Send the helicopter to a hangar if needed for replacement */ if (v->NeedsAutomaticServicing()) { - _current_company = v->owner; + Backup cur_company(_current_company, v->owner); DoCommand(v->tile, v->index, DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); - _current_company = OWNER_NONE; + cur_company.Restore(); } } @@ -1564,9 +1562,9 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->NeedsAutomaticServicing()) { - _current_company = v->owner; + Backup cur_company(_current_company, v->owner); DoCommand(v->tile, v->index, DEPOT_SERVICE, DC_EXEC, CMD_SEND_AIRCRAFT_TO_HANGAR); - _current_company = OWNER_NONE; + cur_company.Restore(); } } diff --git a/src/core/backup_type.hpp b/src/core/backup_type.hpp new file mode 100644 index 0000000000..90b48c2a8a --- /dev/null +++ b/src/core/backup_type.hpp @@ -0,0 +1,134 @@ +/* $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 backup_type.hpp Class for backupping variables and making sure they are restored later. */ + +#ifndef BACKUP_TYPE_HPP +#define BACKUP_TYPE_HPP + +/** + * Class to backup a specific variable and restore it later. + * The variable is not restored automatically, but assertions make sure it is restored. + * You have to call either Trash() or Restore() exactly once. + */ +template +struct Backup { + /** + * Backup variable. + * @param original Variable to backup. + */ + Backup(T &original) : original(original), valid(true), original_value(original) {} + + /** + * Backup variable and switch to new value. + * @param original Variable to backup. + * @param new_value New value for variable. + */ + template + Backup(T &original, const U &new_value) : original(original), valid(true), original_value(original) + { + /* Note: We use a separate typename U, so type conversions are handled by assignment operator. */ + original = new_value; + } + + /** + * Check whether the variable was restored on object destruction. + */ + ~Backup() + { + /* Check whether restoration was done */ + assert(!this->valid); + } + + /** + * Checks whether the variable was already restored. + * @return true if variable has already been restored. + */ + bool IsValid() const + { + return this->valid; + } + + /** + * Returns the backupped value. + * @return value from the backup. + */ + const T &GetOriginalValue() const + { + assert(this->valid); + return original_value; + } + + /** + * Change the value of the variable. + * While this does not touch the backup at all, it ensures that the variable is only modified while backupped. + * @param new_value New value for variable. + */ + template + void Change(const U &new_value) + { + /* Note: We use a separate typename U, so type conversions are handled by assignment operator. */ + assert(this->valid); + original = new_value; + } + + /** + * Revert the variable to its original value, but do not mark it as restored. + */ + void Revert() + { + assert(this->valid); + this->original = this->original_value; + } + + /** + * Trash the backup. The variable shall not be restored anymore. + */ + void Trash() + { + assert(this->valid); + this->valid = false; + } + + /** + * Restore the variable. + */ + void Restore() + { + this->Revert(); + this->Trash(); + } + + /** + * Update the backup. + * That is trash the old value and make the current value of the variable the value to be restored later. + */ + void Update() + { + assert(this->valid); + this->original_value = this->original; + } + + /** + * Check whether the variable is currently equals the backup. + * @return true if equal + */ + bool Verify() const + { + assert(this->valid); + return this->original_value == this->original; + } + +private: + T &original; + bool valid; + T original_value; +}; + +#endif /* BACKUP_TYPE_HPP */ diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp index 314cf14de4..44f27fa8a2 100644 --- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -43,6 +43,7 @@ #include "ai/ai.hpp" #include "company_base.h" #include "core/random_func.hpp" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/sprites.h" @@ -72,10 +73,9 @@ static void DisasterClearSquare(TileIndex tile) switch (GetTileType(tile)) { case MP_RAILWAY: if (Company::IsHumanID(GetTileOwner(tile))) { - CompanyID old_company = _current_company; - _current_company = OWNER_WATER; + Backup cur_company(_current_company, OWNER_WATER); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); - _current_company = old_company; + cur_company.Restore(); /* update signals in buffer */ UpdateSignalsInBuffer(); @@ -83,10 +83,9 @@ static void DisasterClearSquare(TileIndex tile) break; case MP_HOUSE: { - CompanyID old_company = _current_company; - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); - _current_company = old_company; + cur_company.Restore(); break; } diff --git a/src/economy.cpp b/src/economy.cpp index 4107852e31..21e9516c3f 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -47,6 +47,7 @@ #include "core/pool_func.hpp" #include "newgrf.h" #include "engine_base.h" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/sprites.h" @@ -304,7 +305,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) #endif /* ENABLE_NETWORK */ Town *t; - CompanyID old = _current_company; + Backup cur_company(_current_company, old_owner); assert(old_owner != new_owner); @@ -313,7 +314,6 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) uint i; /* See if the old_owner had shares in other companies */ - _current_company = old_owner; FOR_ALL_COMPANIES(c) { for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { @@ -327,9 +327,10 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } /* Sell all the shares that people have on this company */ + Backup cur_company2(_current_company); c = Company::Get(old_owner); for (i = 0; i < 4; i++) { - _current_company = c->share_owners[i]; + cur_company2.Change(c->share_owners[i]); if (_current_company != INVALID_OWNER) { /* Sell the shares */ CommandCost res = DoCommand(0, old_owner, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY); @@ -338,10 +339,9 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) SubtractMoneyFromCompany(res); } } + cur_company2.Restore(); } - _current_company = old_owner; - /* Temporarily increase the company's money, to be sure that * removing his/her property doesn't fail because of lack of money. * Not too drastically though, because it could overflow */ @@ -472,7 +472,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) /* Change colour of existing windows */ if (new_owner != INVALID_OWNER) ChangeWindowOwner(old_owner, new_owner); - _current_company = old; + cur_company.Restore(); MarkWholeScreenDirty(); } @@ -553,11 +553,13 @@ static void CompaniesGenStatistics() Station *st; Company *c; + Backup cur_company(_current_company); FOR_ALL_STATIONS(st) { - _current_company = st->owner; + cur_company.Change(st->owner); CommandCost cost(EXPENSES_PROPERTY, _price[PR_STATION_VALUE] >> 1); SubtractMoneyFromCompany(cost); } + cur_company.Restore(); if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, _cur_month)) return; @@ -686,8 +688,9 @@ static void CompaniesPayInterest() { const Company *c; + Backup cur_company(_current_company); FOR_ALL_COMPANIES(c) { - _current_company = c->index; + cur_company.Change(c->index); /* Over a year the paid interest should be "loan * interest percentage", * but... as that number is likely not dividable by 12 (pay each month), @@ -705,6 +708,7 @@ static void CompaniesPayInterest() SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, _price[PR_STATION_VALUE] >> 2)); } + cur_company.Restore(); } static void HandleEconomyFluctuations() @@ -1023,8 +1027,7 @@ CargoPayment::~CargoPayment() if (this->visual_profit == 0) return; - CompanyID old_company = _current_company; - _current_company = this->front->owner; + Backup cur_company(_current_company, this->front->owner); SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit)); this->front->profit_this_year += this->visual_profit << 8; @@ -1039,7 +1042,7 @@ CargoPayment::~CargoPayment() ShowFeederIncomeAnimation(this->front->x_pos, this->front->y_pos, this->front->z_pos, this->visual_profit); } - _current_company = old_company; + cur_company.Restore(); } /** @@ -1426,8 +1429,6 @@ void CompaniesMonthlyLoop() RecomputePrices(); } CompaniesPayInterest(); - /* Reset the _current_company flag */ - _current_company = OWNER_NONE; HandleEconomyFluctuations(); } @@ -1457,14 +1458,14 @@ static void DoAcquireCompany(Company *c) } value = CalculateCompanyValue(c) >> 2; - CompanyID old_company = _current_company; + Backup cur_company(_current_company); for (i = 0; i != 4; i++) { if (c->share_owners[i] != COMPANY_SPECTATOR) { - _current_company = c->share_owners[i]; + cur_company.Change(c->share_owners[i]); SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -value)); } } - _current_company = old_company; + cur_company.Restore(); if (c->is_ai) AI::Stop(c->index); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 304f9bd272..f425daf34e 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -43,6 +43,7 @@ #include "ai/ai.hpp" #include "core/pool_func.hpp" #include "subsidy_func.h" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/industry_land.h" @@ -1040,17 +1041,17 @@ void PlantRandomFarmField(const Industry *i) static bool SearchLumberMillTrees(TileIndex tile, void *user_data) { if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) { ///< 3 and up means all fully grown trees - CompanyID old_company = _current_company; /* found a tree */ - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); + _industry_sound_ctr = 1; _industry_sound_tile = tile; SndPlayTileFx(SND_38_CHAINSAW, tile); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); - _current_company = old_company; + cur_company.Restore(); return true; } return false; @@ -1371,10 +1372,9 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil } /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ - CompanyID old_company = _current_company; - _current_company = OWNER_TOWN; + Backup cur_company(_current_company, OWNER_TOWN); CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); - _current_company = old_company; + cur_company.Restore(); if (ret.Failed()) return ret; } else { @@ -1484,8 +1484,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry. * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */ - CompanyID old_company = _current_company; - _current_company = OWNER_TOWN; + Backup cur_company(_current_company, OWNER_TOWN); TILE_LOOP(tile_walk, size_x, size_y, cur_tile) { curh = TileHeight(tile_walk); @@ -1493,13 +1492,13 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* This tile needs terraforming. Check if we can do that without * damaging the surroundings too much. */ if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) { - _current_company = old_company; + cur_company.Restore(); return false; } /* This is not 100% correct check, but the best we can do without modifying the map. * What is missing, is if the difference in height is more than 1.. */ if (DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND).Failed()) { - _current_company = old_company; + cur_company.Restore(); return false; } } @@ -1519,7 +1518,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, } } - _current_company = old_company; + cur_company.Restore(); return true; } @@ -1789,8 +1788,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry()) { if (flags & DC_EXEC) { /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */ - CompanyID founder = _current_company; - _current_company = OWNER_TOWN; + Backup cur_company(_current_company, OWNER_TOWN); /* Prospecting has a chance to fail, however we cannot guarantee that something can * be built on the map, so the chance gets lower when the map is fuller, but there * is nothing we can really do about that. */ @@ -1800,11 +1798,11 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * because parameter evaluation order is not guaranteed in the c++ standard */ tile = RandomTile(); - CommandCost ret = CreateNewIndustryHelper(tile, it, flags, indspec, RandomRange(indspec->num_table), random_var8f, random_initial_bits, founder, &ind); + CommandCost ret = CreateNewIndustryHelper(tile, it, flags, indspec, RandomRange(indspec->num_table), random_var8f, random_initial_bits, cur_company.GetOriginalValue(), &ind); if (ret.Succeeded()) break; } } - _current_company = founder; + cur_company.Restore(); } } else { int count = indspec->num_table; @@ -1892,8 +1890,7 @@ static const byte _numof_industry_table[]= { */ static void PlaceInitialIndustry(IndustryType type, bool try_hard) { - CompanyID old_company = _current_company; - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); IncreaseGeneratingWorldProgress(GWP_INDUSTRY); @@ -1901,7 +1898,7 @@ static void PlaceInitialIndustry(IndustryType type, bool try_hard) if (CreateNewIndustry(RandomTile(), type) != NULL) break; } - _current_company = old_company; + cur_company.Restore(); } /** @@ -2417,8 +2414,7 @@ void IndustryDailyLoop() return; // Nothing to do? get out } - CompanyID old_company = _current_company; - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); /* perform the required industry changes for the day */ for (uint16 j = 0; j < change_loop; j++) { @@ -2434,7 +2430,7 @@ void IndustryDailyLoop() } } - _current_company = old_company; + cur_company.Restore(); /* production-change */ InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 1); @@ -2443,8 +2439,7 @@ void IndustryDailyLoop() void IndustryMonthlyLoop() { Industry *i; - CompanyID old_company = _current_company; - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); FOR_ALL_INDUSTRIES(i) { UpdateIndustryStatistics(i); @@ -2456,7 +2451,7 @@ void IndustryMonthlyLoop() } } - _current_company = old_company; + cur_company.Restore(); /* production-change */ InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 1); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 0f6d8ba622..a0177fea38 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -33,6 +33,7 @@ #include "company_base.h" #include "core/geometry_func.hpp" #include "core/random_func.hpp" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/sprites.h" @@ -522,12 +523,14 @@ public: return; } - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); _generating_world = true; _ignore_restrictions = true; + DoCommandP(tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry); + cur_company.Restore(); _ignore_restrictions = false; _generating_world = false; } else { diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index fe9bc9fde2..181b8c1901 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -21,6 +21,7 @@ #include "company_func.h" #include "company_gui.h" #include "company_base.h" +#include "core/backup_type.hpp" #include "table/strings.h" @@ -228,10 +229,9 @@ CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { /* Add money to company */ - CompanyID old_company = _current_company; - _current_company = (CompanyID)p2; + Backup cur_company(_current_company, (CompanyID)p2); SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost())); - _current_company = old_company; + cur_company.Restore(); } /* Subtract money from local-company */ diff --git a/src/openttd.cpp b/src/openttd.cpp index 644781162a..500ab077b0 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -65,6 +65,7 @@ #include "engine_func.h" #include "core/random_func.hpp" #include "rail_gui.h" +#include "core/backup_type.hpp" #include "newgrf_commons.h" @@ -1215,8 +1216,7 @@ void StateGameLoop() /* All these actions has to be done from OWNER_NONE * for multiplayer compatibility */ - CompanyID old_company = _current_company; - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); AnimateAnimatedTiles(); IncreaseDate(); @@ -1229,7 +1229,7 @@ void StateGameLoop() CallWindowTickEvent(); NewsLoop(); - _current_company = old_company; + cur_company.Restore(); } } diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 0bf4aa8929..59bc30e715 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -36,6 +36,7 @@ #include "town.h" #include "pbs.h" #include "company_base.h" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/sprites.h" @@ -641,9 +642,10 @@ bool FloodHalftile(TileIndex t) TrackBits to_remove = lower_track & rail_bits; if (to_remove != 0) { - _current_company = OWNER_WATER; - if (DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Failed()) return flooded; // not yet floodable - flooded = true; + Backup cur_company(_current_company, OWNER_WATER); + flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded(); + cur_company.Restore(); + if (!flooded) return flooded; // not yet floodable rail_bits = rail_bits & ~to_remove; if (rail_bits == 0) { MakeShore(t); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index f207efaf72..67fa291efd 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -41,6 +41,7 @@ #include "engine_base.h" #include "company_base.h" #include "engine_func.h" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/sprites.h" @@ -1159,12 +1160,11 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r) { /* The 'current' company is not necessarily the owner of the vehicle. */ - CompanyID original_company = _current_company; - _current_company = c; + Backup cur_company(_current_company, c); CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, DC_NONE, CMD_BUILD_ROAD); - _current_company = original_company; + cur_company.Restore(); return ret.Succeeded(); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 9a128e4042..59c7430120 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -52,6 +52,7 @@ #include "../engine_base.h" #include "../engine_func.h" #include "../rail_gui.h" +#include "../core/backup_type.hpp" #include "table/strings.h" @@ -1570,8 +1571,9 @@ bool AfterLoadGame() if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) { Owner o = GetTileOwner(t); if (o < MAX_COMPANIES && !Company::IsValidID(o)) { - _current_company = o; + Backup cur_company(_current_company, o); ChangeTileOwner(t, o, INVALID_OWNER); + cur_company.Restore(); } if (IsBuoyTile(t)) { /* reset buoy owner to OWNER_NONE in the station struct diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index f6a2f0d4f5..8cc3c59d9b 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -45,6 +45,7 @@ #include "townname_func.h" #include "townname_type.h" #include "core/random_func.hpp" +#include "core/backup_type.hpp" #include "table/strings.h" #include "table/town_land.h" @@ -515,7 +516,7 @@ static void TileLoop_Town(TileIndex tile) } } - _current_company = OWNER_TOWN; + Backup cur_company(_current_company, OWNER_TOWN); if ((hs->building_flags & BUILDING_HAS_1_TILE) && HasBit(t->flags, TOWN_IS_FUNDED) && @@ -530,7 +531,7 @@ static void TileLoop_Town(TileIndex tile) if (GB(r, 24, 8) >= 12) BuildTownHouse(t, tile); } - _current_company = OWNER_NONE; + cur_company.Restore(); } static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlag flags) @@ -1296,8 +1297,7 @@ static bool GrowTown(Town *t) }; /* Current "company" is a town */ - CompanyID old_company = _current_company; - _current_company = OWNER_TOWN; + Backup cur_company(_current_company, OWNER_TOWN); TileIndex tile = t->xy; // The tile we are working with ATM @@ -1306,7 +1306,7 @@ static bool GrowTown(Town *t) for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { if (GetTownRoadBits(tile) != ROAD_NONE) { int r = GrowTownAtRoad(t, tile); - _current_company = old_company; + cur_company.Restore(); return r != 0; } tile = TILE_ADD(tile, ToTileIndexDiff(*ptr)); @@ -1321,7 +1321,7 @@ static bool GrowTown(Town *t) if (!IsTileType(tile, MP_HOUSE) && GetTileSlope(tile, NULL) == SLOPE_FLAT) { if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) { DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); - _current_company = old_company; + cur_company.Restore(); return true; } } @@ -1329,7 +1329,7 @@ static bool GrowTown(Town *t) } } - _current_company = old_company; + cur_company.Restore(); return false; } @@ -2383,10 +2383,9 @@ static bool DoBuildStatueOfCompany(TileIndex tile, TownID town_id) return false; } - CompanyID old = _current_company; - _current_company = OWNER_NONE; + Backup cur_company(_current_company, OWNER_NONE); CommandCost r = DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); - _current_company = old; + cur_company.Restore(); if (r.Failed()) return false; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e14d4979c8..30bd2f74b4 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -50,6 +50,7 @@ #include "core/random_func.hpp" #include "engine_base.h" #include "newgrf.h" +#include "core/backup_type.hpp" #include "table/sprites.h" #include "table/strings.h" @@ -772,10 +773,11 @@ void CallVehicleTicks() } } + Backup cur_company(_current_company); for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) { v = it->first; /* Autoreplace needs the current company set as the vehicle owner */ - _current_company = v->owner; + cur_company.Change(v->owner); /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick() * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that @@ -816,7 +818,7 @@ void CallVehicleTicks() AddVehicleNewsItem(message, NS_ADVICE, v->index); } - _current_company = OWNER_NONE; + cur_company.Restore(); } static void DoDrawVehicle(const Vehicle *v) @@ -1110,8 +1112,9 @@ void VehicleEnterDepot(Vehicle *v) } if (t.IsRefit()) { - _current_company = v->owner; + Backup cur_company(_current_company, v->owner); CommandCost cost = DoCommand(v->tile, v->index, t.GetRefitCargo() | t.GetRefitSubtype() << 8, DC_EXEC, GetCmdRefitVeh(v)); + cur_company.Restore(); if (cost.Failed()) { _vehicles_to_autoreplace[v] = false; diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 4f05633aa7..6912d07eca 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -34,6 +34,7 @@ #include "station_base.h" #include "ai/ai.hpp" #include "core/random_func.hpp" +#include "core/backup_type.hpp" #include "table/sprites.h" #include "table/strings.h" @@ -881,7 +882,7 @@ void DoFloodTile(TileIndex target) bool flooded = false; // Will be set to true if something is changed. - _current_company = OWNER_WATER; + Backup cur_company(_current_company, OWNER_WATER); Slope tileh = GetTileSlope(target, NULL); if (tileh != SLOPE_FLAT) { @@ -933,7 +934,7 @@ void DoFloodTile(TileIndex target) UpdateSignalsInBuffer(); } - _current_company = OWNER_NONE; + cur_company.Restore(); } /** @@ -941,7 +942,7 @@ void DoFloodTile(TileIndex target) */ static void DoDryUp(TileIndex tile) { - _current_company = OWNER_WATER; + Backup cur_company(_current_company, OWNER_WATER); switch (GetTileType(tile)) { case MP_RAILWAY: @@ -977,7 +978,7 @@ static void DoDryUp(TileIndex tile) default: NOT_REACHED(); } - _current_company = OWNER_NONE; + cur_company.Restore(); } /**