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
00021 struct BaseStorageArray {
00022 virtual ~BaseStorageArray();
00023
00031 virtual void ClearChanges(bool keep_changes) = 0;
00032
00038 virtual void StoreValue(uint pos, int32 value) = 0;
00039 };
00040
00047 template <typename TYPE, uint SIZE>
00048 struct PersistentStorageArray : BaseStorageArray {
00049 TYPE storage[SIZE];
00050 TYPE *prev_storage;
00051
00053 PersistentStorageArray() : prev_storage(NULL)
00054 {
00055 memset(this->storage, 0, sizeof(this->storage));
00056 }
00057
00059 ~PersistentStorageArray()
00060 {
00061 free(this->prev_storage);
00062 }
00063
00065 void ResetToZero()
00066 {
00067 memset(this->storage, 0, sizeof(this->storage));
00068 }
00069
00077 void StoreValue(uint pos, int32 value)
00078 {
00079
00080 if (pos >= SIZE) return;
00081
00082
00083
00084 if (this->storage[pos] == value) return;
00085
00086
00087 if (this->prev_storage != NULL) {
00088 this->prev_storage = MallocT<TYPE>(SIZE);
00089 memcpy(this->prev_storage, this->storage, sizeof(this->storage));
00090
00091
00092
00093 AddChangedStorage(this);
00094 }
00095
00096 this->storage[pos] = value;
00097 }
00098
00104 TYPE GetValue(uint pos) const
00105 {
00106
00107 if (pos >= SIZE) return 0;
00108
00109 return this->storage[pos];
00110 }
00111
00116 void ClearChanges(bool keep_changes)
00117 {
00118 assert(this->prev_storage != NULL);
00119
00120 if (!keep_changes) {
00121 memcpy(this->storage, this->prev_storage, sizeof(this->storage));
00122 }
00123 free(this->prev_storage);
00124 }
00125 };
00126
00127
00134 template <typename TYPE, uint SIZE>
00135 struct TemporaryStorageArray : BaseStorageArray {
00136 TYPE storage[SIZE];
00137
00139 TemporaryStorageArray()
00140 {
00141 memset(this->storage, 0, sizeof(this->storage));
00142 }
00143
00149 void StoreValue(uint pos, int32 value)
00150 {
00151
00152 if (pos >= SIZE) return;
00153
00154 this->storage[pos] = value;
00155 AddChangedStorage(this);
00156 }
00157
00163 TYPE GetValue(uint pos) const
00164 {
00165
00166 if (pos >= SIZE) return 0;
00167
00168 return this->storage[pos];
00169 }
00170
00171 void ClearChanges(bool keep_changes)
00172 {
00173 memset(this->storage, 0, sizeof(this->storage));
00174 }
00175 };
00176
00177 void AddChangedStorage(BaseStorageArray *storage);
00178 void ClearStorageChanges(bool keep_changes);
00179
00180
00181 typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
00182
00183 typedef uint32 PersistentStorageID;
00184
00185 struct PersistentStorage;
00186 typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
00187
00188 extern PersistentStoragePool _persistent_storage_pool;
00189
00194 struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
00195 uint32 grfid;
00196
00198 PersistentStorage(const uint32 new_grfid) : grfid(new_grfid)
00199 {
00200 this->prev_storage = NULL;
00201 memset(this->storage, 0, sizeof(this->storage));
00202 }
00203
00205 ~PersistentStorage()
00206 {
00207 free(this->prev_storage);
00208 }
00209 };
00210
00211 assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
00212
00213 #define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
00214 #define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
00215
00216 #endif