newgrf_storage.h

Go to the documentation of this file.
00001 /* $Id: newgrf_storage.h 11691 2007-12-25 09:48:53Z rubidium $ */
00002 
00005 #ifndef NEWGRF_STORAGE_H
00006 #define NEWGRF_STORAGE_H
00007 
00008 #include "core/alloc_func.hpp"
00009 
00014 struct BaseStorageArray
00015 {
00017   virtual ~BaseStorageArray() {}
00018 
00026   virtual void ClearChanges(bool keep_changes) = 0;
00027 
00033   virtual void Store(uint pos, uint32 value) = 0;
00034 };
00035 
00042 template <typename TYPE, uint SIZE>
00043 struct PersistentStorageArray : BaseStorageArray {
00044   TYPE storage[SIZE]; 
00045   TYPE *prev_storage; 
00046 
00048   PersistentStorageArray() : prev_storage(NULL)
00049   {
00050     memset(this->storage, 0, sizeof(this->storage));
00051   }
00052 
00054   ~PersistentStorageArray()
00055   {
00056     free(this->prev_storage);
00057   }
00058 
00066   void Store(uint pos, uint32 value)
00067   {
00068     /* Out of the scope of the array */
00069     if (pos >= SIZE) return;
00070 
00071     /* The value hasn't changed, so we pretend nothing happened.
00072      * Saves a few cycles and such and it's pretty easy to check. */
00073     if (this->storage[pos] == value) return;
00074 
00075     /* We do not have made a backup; lets do so */
00076     if (this->prev_storage != NULL) {
00077       this->prev_storage = MallocT<TYPE>(SIZE);
00078       if (this->prev_storage == NULL) return;
00079 
00080       memcpy(this->prev_storage, this->storage, sizeof(this->storage));
00081 
00082       /* We only need to register ourselves when we made the backup
00083        * as that is the only time something will have changed */
00084       AddChangedStorage(this);
00085     }
00086 
00087     this->storage[pos] = value;
00088   }
00089 
00095   TYPE Get(uint pos) const
00096   {
00097     /* Out of the scope of the array */
00098     if (pos >= SIZE) return 0;
00099 
00100     return this->storage[pos];
00101   }
00102 
00103   void ClearChanges(bool keep_changes)
00104   {
00105     assert(this->prev_storage != NULL);
00106 
00107     if (!keep_changes) {
00108       memcpy(this->storage, this->prev_storage, sizeof(this->storage));
00109     }
00110     free(this->prev_storage);
00111   }
00112 };
00113 
00114 
00121 template <typename TYPE, uint SIZE>
00122 struct TemporaryStorageArray : BaseStorageArray {
00123   TYPE storage[SIZE]; 
00124 
00126   TemporaryStorageArray()
00127   {
00128     memset(this->storage, 0, sizeof(this->storage));
00129   }
00130 
00136   void Store(uint pos, uint32 value)
00137   {
00138     /* Out of the scope of the array */
00139     if (pos >= SIZE) return;
00140 
00141     this->storage[pos] = value;
00142     AddChangedStorage(this);
00143   }
00144 
00150   TYPE Get(uint pos) const
00151   {
00152     /* Out of the scope of the array */
00153     if (pos >= SIZE) return 0;
00154 
00155     return this->storage[pos];
00156   }
00157 
00158   void ClearChanges(bool keep_changes)
00159   {
00160     memset(this->storage, 0, sizeof(this->storage));
00161   }
00162 };
00163 
00170 void AddChangedStorage(BaseStorageArray *storage);
00171 
00172 
00183 void ClearStorageChanges(bool keep_changes);
00184 
00185 #endif /* NEWGRF_STORAGE_H */

Generated on Mon Sep 22 20:34:17 2008 for openttd by  doxygen 1.5.6