2010-05-31 22:22:57 +02:00
|
|
|
/* $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 backup_type.hpp Class for backupping variables and making sure they are restored later. */
|
|
|
|
|
|
|
|
#ifndef BACKUP_TYPE_HPP
|
|
|
|
#define BACKUP_TYPE_HPP
|
|
|
|
|
2010-06-05 14:16:12 +02:00
|
|
|
#include "../debug.h"
|
|
|
|
|
2010-05-31 22:22:57 +02:00
|
|
|
/**
|
|
|
|
* 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 <typename T>
|
|
|
|
struct Backup {
|
|
|
|
/**
|
|
|
|
* Backup variable.
|
|
|
|
* @param original Variable to backup.
|
2010-06-05 14:16:12 +02:00
|
|
|
* @param file Filename for debug output. Use FILE_LINE macro.
|
|
|
|
* @param line Linenumber for debug output. Use FILE_LINE macro.
|
2010-05-31 22:22:57 +02:00
|
|
|
*/
|
2010-06-05 14:16:12 +02:00
|
|
|
Backup(T &original, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line) {}
|
2010-05-31 22:22:57 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Backup variable and switch to new value.
|
|
|
|
* @param original Variable to backup.
|
|
|
|
* @param new_value New value for variable.
|
2010-06-05 14:16:12 +02:00
|
|
|
* @param file Filename for debug output. Use FILE_LINE macro.
|
|
|
|
* @param line Linenumber for debug output. Use FILE_LINE macro.
|
2010-05-31 22:22:57 +02:00
|
|
|
*/
|
|
|
|
template <typename U>
|
2010-06-05 14:16:12 +02:00
|
|
|
Backup(T &original, const U &new_value, const char * const file, const int line) : original(original), valid(true), original_value(original), file(file), line(line)
|
2010-05-31 22:22:57 +02:00
|
|
|
{
|
|
|
|
/* 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 */
|
2010-06-05 14:16:12 +02:00
|
|
|
if (this->valid)
|
|
|
|
{
|
|
|
|
/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
|
|
|
|
* Exceptions are especially used to abort world generation. */
|
2018-04-30 12:54:00 +02:00
|
|
|
DEBUG(misc, 0, "%s:%d: Backed-up value was not restored!", this->file, this->line);
|
2010-06-05 14:16:12 +02:00
|
|
|
this->Restore();
|
|
|
|
}
|
2010-05-31 22:22:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 <typename U>
|
|
|
|
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;
|
2010-06-05 14:16:12 +02:00
|
|
|
|
|
|
|
const char * const file;
|
|
|
|
const int line;
|
2010-05-31 22:22:57 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* BACKUP_TYPE_HPP */
|