newgrf_storage.h

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #ifndef NEWGRF_STORAGE_H
00013 #define NEWGRF_STORAGE_H
00014 
00015 #include "core/alloc_func.hpp"
00016 #include "core/pool_type.hpp"
00017 
00022 struct BaseStorageArray
00023 {
00024   virtual ~BaseStorageArray();
00025 
00033   virtual void ClearChanges(bool keep_changes) = 0;
00034 
00040   virtual void StoreValue(uint pos, int32 value) = 0;
00041 };
00042 
00049 template <typename TYPE, uint SIZE>
00050 struct PersistentStorageArray : BaseStorageArray {
00051   TYPE storage[SIZE]; 
00052   TYPE *prev_storage; 
00053 
00055   PersistentStorageArray() : prev_storage(NULL)
00056   {
00057     memset(this->storage, 0, sizeof(this->storage));
00058   }
00059 
00061   ~PersistentStorageArray()
00062   {
00063     free(this->prev_storage);
00064   }
00065 
00067   void ResetToZero()
00068   {
00069     memset(this->storage, 0, sizeof(this->storage));
00070   }
00071 
00079   void StoreValue(uint pos, int32 value)
00080   {
00081     /* Out of the scope of the array */
00082     if (pos >= SIZE) return;
00083 
00084     /* The value hasn't changed, so we pretend nothing happened.
00085      * Saves a few cycles and such and it's pretty easy to check. */
00086     if (this->storage[pos] == value) return;
00087 
00088     /* We do not have made a backup; lets do so */
00089     if (this->prev_storage != NULL) {
00090       this->prev_storage = MallocT<TYPE>(SIZE);
00091       memcpy(this->prev_storage, this->storage, sizeof(this->storage));
00092 
00093       /* We only need to register ourselves when we made the backup
00094        * as that is the only time something will have changed */
00095       AddChangedStorage(this);
00096     }
00097 
00098     this->storage[pos] = value;
00099   }
00100 
00106   TYPE GetValue(uint pos) const
00107   {
00108     /* Out of the scope of the array */
00109     if (pos >= SIZE) return 0;
00110 
00111     return this->storage[pos];
00112   }
00113 
00118   void ClearChanges(bool keep_changes)
00119   {
00120     assert(this->prev_storage != NULL);
00121 
00122     if (!keep_changes) {
00123       memcpy(this->storage, this->prev_storage, sizeof(this->storage));
00124     }
00125     free(this->prev_storage);
00126   }
00127 };
00128 
00129 
00136 template <typename TYPE, uint SIZE>
00137 struct TemporaryStorageArray : BaseStorageArray {
00138   TYPE storage[SIZE]; 
00139 
00141   TemporaryStorageArray()
00142   {
00143     memset(this->storage, 0, sizeof(this->storage));
00144   }
00145 
00151   void StoreValue(uint pos, int32 value)
00152   {
00153     /* Out of the scope of the array */
00154     if (pos >= SIZE) return;
00155 
00156     this->storage[pos] = value;
00157     AddChangedStorage(this);
00158   }
00159 
00165   TYPE GetValue(uint pos) const
00166   {
00167     /* Out of the scope of the array */
00168     if (pos >= SIZE) return 0;
00169 
00170     return this->storage[pos];
00171   }
00172 
00173   void ClearChanges(bool keep_changes)
00174   {
00175     memset(this->storage, 0, sizeof(this->storage));
00176   }
00177 };
00178 
00179 void AddChangedStorage(BaseStorageArray *storage);
00180 void ClearStorageChanges(bool keep_changes);
00181 
00182 
00183 typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
00184 
00185 typedef uint32 PersistentStorageID;
00186 
00187 struct PersistentStorage;
00188 typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
00189 
00190 extern PersistentStoragePool _persistent_storage_pool;
00191 
00196 struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
00197   uint32 grfid; 
00198 
00200   PersistentStorage(const uint32 new_grfid) : grfid(new_grfid)
00201   {
00202     this->prev_storage = NULL;
00203     memset(this->storage, 0, sizeof(this->storage));
00204   }
00205 
00207   ~PersistentStorage()
00208   {
00209     free(this->prev_storage);
00210   }
00211 };
00212 
00213 assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
00214 
00215 #define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
00216 #define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
00217 
00218 #endif /* NEWGRF_STORAGE_H */