Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef NEWGRF_STORAGE_H
00013 #define NEWGRF_STORAGE_H
00014
00015 #include "core/pool_type.hpp"
00016 #include "tile_type.h"
00017
00021 enum PersistentStorageMode {
00022 PSM_ENTER_GAMELOOP,
00023 PSM_LEAVE_GAMELOOP,
00024 PSM_ENTER_COMMAND,
00025 PSM_LEAVE_COMMAND,
00026 PSM_ENTER_TESTMODE,
00027 PSM_LEAVE_TESTMODE,
00028 };
00029
00034 struct BasePersistentStorageArray {
00035 uint32 grfid;
00036 byte feature;
00037 TileIndex tile;
00038
00039 virtual ~BasePersistentStorageArray();
00040
00041 static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode = false);
00042
00043 protected:
00047 virtual void ClearChanges() = 0;
00048
00053 static bool AreChangesPersistent() { return (gameloop || command) && !testmode; }
00054
00055 private:
00056 static bool gameloop;
00057 static bool command;
00058 static bool testmode;
00059 };
00060
00067 template <typename TYPE, uint SIZE>
00068 struct PersistentStorageArray : BasePersistentStorageArray {
00069 TYPE storage[SIZE];
00070 TYPE *prev_storage;
00071
00073 PersistentStorageArray() : prev_storage(NULL)
00074 {
00075 memset(this->storage, 0, sizeof(this->storage));
00076 }
00077
00079 ~PersistentStorageArray()
00080 {
00081 free(this->prev_storage);
00082 }
00083
00085 void ResetToZero()
00086 {
00087 memset(this->storage, 0, sizeof(this->storage));
00088 }
00089
00097 void StoreValue(uint pos, int32 value)
00098 {
00099
00100 if (pos >= SIZE) return;
00101
00102
00103
00104 if (this->storage[pos] == value) return;
00105
00106
00107 if (AreChangesPersistent()) {
00108 assert(this->prev_storage == NULL);
00109 } else if (this->prev_storage == NULL) {
00110 this->prev_storage = MallocT<TYPE>(SIZE);
00111 memcpy(this->prev_storage, this->storage, sizeof(this->storage));
00112
00113
00114
00115 AddChangedPersistentStorage(this);
00116 }
00117
00118 this->storage[pos] = value;
00119 }
00120
00126 TYPE GetValue(uint pos) const
00127 {
00128
00129 if (pos >= SIZE) return 0;
00130
00131 return this->storage[pos];
00132 }
00133
00134 void ClearChanges()
00135 {
00136 if (this->prev_storage != NULL) {
00137 memcpy(this->storage, this->prev_storage, sizeof(this->storage));
00138 free(this->prev_storage);
00139 this->prev_storage = NULL;
00140 }
00141 }
00142 };
00143
00144
00151 template <typename TYPE, uint SIZE>
00152 struct TemporaryStorageArray {
00153 TYPE storage[SIZE];
00154 uint16 init[SIZE];
00155 uint16 init_key;
00156
00158 TemporaryStorageArray()
00159 {
00160 memset(this->storage, 0, sizeof(this->storage));
00161 memset(this->init, 0, sizeof(this->init));
00162 this->init_key = 1;
00163 }
00164
00170 void StoreValue(uint pos, int32 value)
00171 {
00172
00173 if (pos >= SIZE) return;
00174
00175 this->storage[pos] = value;
00176 this->init[pos] = this->init_key;
00177 }
00178
00184 TYPE GetValue(uint pos) const
00185 {
00186
00187 if (pos >= SIZE) return 0;
00188
00189 if (this->init[pos] != this->init_key) {
00190
00191 return 0;
00192 }
00193
00194 return this->storage[pos];
00195 }
00196
00197 void ClearChanges()
00198 {
00199
00200 this->init_key++;
00201 if (this->init_key == 0) {
00202
00203 memset(this->init, 0, sizeof(this->init));
00204 this->init_key = 1;
00205 }
00206 }
00207 };
00208
00209 void AddChangedPersistentStorage(BasePersistentStorageArray *storage);
00210
00211 typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
00212
00213 typedef uint32 PersistentStorageID;
00214
00215 struct PersistentStorage;
00216 typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
00217
00218 extern PersistentStoragePool _persistent_storage_pool;
00219
00223 struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
00225 PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile)
00226 {
00227 this->grfid = new_grfid;
00228 this->feature = feature;
00229 this->tile = tile;
00230 }
00231 };
00232
00233 assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
00234
00235 #define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
00236 #define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
00237
00238 #endif