summaryrefslogtreecommitdiff
path: root/src/newgrf_storage.h
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2014-02-23 22:03:08 +0000
committerfrosch <frosch@openttd.org>2014-02-23 22:03:08 +0000
commita32d18cbb939b240bc16d909fce71ba72c24f040 (patch)
tree1cb4fa063b33b684a3a94fe60ade548dd7703624 /src/newgrf_storage.h
parentc6ce57e8a7529b970ef45eb7baa00560d6f4b16b (diff)
downloadopenttd-a32d18cbb939b240bc16d909fce71ba72c24f040.tar.xz
(svn r26371) -Fix [FS#5831]: Calling DoCommandP during the gameloop cleared pending persistent storage changes.
Diffstat (limited to 'src/newgrf_storage.h')
-rw-r--r--src/newgrf_storage.h54
1 files changed, 35 insertions, 19 deletions
diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h
index 7dccb053c..ae9782d88 100644
--- a/src/newgrf_storage.h
+++ b/src/newgrf_storage.h
@@ -16,6 +16,18 @@
#include "tile_type.h"
/**
+ * Mode switches to the behaviour of persistent storage array.
+ */
+enum PersistentStorageMode {
+ PSM_ENTER_GAMELOOP, ///< Enter the gameloop, changes will be permanent.
+ PSM_LEAVE_GAMELOOP, ///< Leave the gameloop, changes will be temporary.
+ PSM_ENTER_COMMAND, ///< Enter command scope, changes will be permanent.
+ PSM_LEAVE_COMMAND, ///< Leave command scope, revert to previous mode.
+ PSM_ENTER_TESTMODE, ///< Enter command test mode, changes will be tempoary.
+ PSM_LEAVE_TESTMODE, ///< Leave command test mode, revert to previous mode.
+};
+
+/**
* Base class for all persistent NewGRF storage arrays. Nothing fancy, only here
* so we have a generalised access to the virtual methods.
*/
@@ -26,14 +38,24 @@ struct BasePersistentStorageArray {
virtual ~BasePersistentStorageArray();
+ static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode = false);
+
+protected:
+ /**
+ * Discard temporary changes.
+ */
+ virtual void ClearChanges() = 0;
+
/**
- * Clear the changes made since the last #ClearChanges.
- * This can be done in two ways:
- * - saving the changes permanently
- * - reverting to the previous version
- * @param keep_changes do we save or revert the changes since the last #ClearChanges?
+ * Check whether currently changes to the storage shall be persistent or
+ * temporary till the next call to ClearChanges().
*/
- virtual void ClearChanges(bool keep_changes) = 0;
+ static bool AreChangesPersistent() { return (gameloop || command) && !testmode; }
+
+private:
+ static bool gameloop;
+ static bool command;
+ static bool testmode;
};
/**
@@ -82,7 +104,9 @@ struct PersistentStorageArray : BasePersistentStorageArray {
if (this->storage[pos] == value) return;
/* We do not have made a backup; lets do so */
- if (this->prev_storage == NULL) {
+ if (AreChangesPersistent()) {
+ assert(this->prev_storage == NULL);
+ } else if (this->prev_storage == NULL) {
this->prev_storage = MallocT<TYPE>(SIZE);
memcpy(this->prev_storage, this->storage, sizeof(this->storage));
@@ -107,19 +131,13 @@ struct PersistentStorageArray : BasePersistentStorageArray {
return this->storage[pos];
}
- /**
- * Clear the changes, or assign them permanently to the storage.
- * @param keep_changes Whether to assign or ditch the changes.
- */
- void ClearChanges(bool keep_changes)
+ void ClearChanges()
{
- assert(this->prev_storage != NULL);
-
- if (!keep_changes) {
+ if (this->prev_storage != NULL) {
memcpy(this->storage, this->prev_storage, sizeof(this->storage));
+ free(this->prev_storage);
+ this->prev_storage = NULL;
}
- free(this->prev_storage);
- this->prev_storage = NULL;
}
};
@@ -189,8 +207,6 @@ struct TemporaryStorageArray {
};
void AddChangedPersistentStorage(BasePersistentStorageArray *storage);
-void ClearPersistentStorageChanges(bool keep_changes);
-
typedef PersistentStorageArray<int32, 16> OldPersistentStorage;