# newgrf_storage.h

Go to the documentation of this file.

    00001 /* $Id: newgrf_storage.h 15568 2009-02-24 20:59:17Z smatz $ */
    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       memcpy(this->prev_storage, this->storage, sizeof(this->storage));
    00079
    00080       /* We only need to register ourselves when we made the backup
    00081        * as that is the only time something will have changed */
    00082       AddChangedStorage(this);
    00083     }
    00084
    00085     this->storage[pos] = value;
    00086   }
    00087
    00093   TYPE Get(uint pos) const
    00094   {
    00095     /* Out of the scope of the array */
    00096     if (pos >= SIZE) return 0;
    00097
    00098     return this->storage[pos];
    00099   }
    00100
    00101   void ClearChanges(bool keep_changes)
    00102   {
    00103     assert(this->prev_storage != NULL);
    00104
    00105     if (!keep_changes) {
    00106       memcpy(this->storage, this->prev_storage, sizeof(this->storage));
    00107     }
    00108     free(this->prev_storage);
    00109   }
    00110 };
    00111
    00112
    00119 template <typename TYPE, uint SIZE>
    00120 struct TemporaryStorageArray : BaseStorageArray {
    00121   TYPE storage[SIZE];
    00122
    00124   TemporaryStorageArray()
    00125   {
    00126     memset(this->storage, 0, sizeof(this->storage));
    00127   }
    00128
    00134   void Store(uint pos, uint32 value)
    00135   {
    00136     /* Out of the scope of the array */
    00137     if (pos >= SIZE) return;
    00138
    00139     this->storage[pos] = value;
    00140     AddChangedStorage(this);
    00141   }
    00142
    00148   TYPE Get(uint pos) const
    00149   {
    00150     /* Out of the scope of the array */
    00151     if (pos >= SIZE) return 0;
    00152
    00153     return this->storage[pos];
    00154   }
    00155
    00156   void ClearChanges(bool keep_changes)
    00157   {
    00158     memset(this->storage, 0, sizeof(this->storage));
    00159   }
    00160 };
    00161
    00168 void AddChangedStorage(BaseStorageArray *storage);
    00169
    00170
    00181 void ClearStorageChanges(bool keep_changes);
    00182
    00183 #endif /* NEWGRF_STORAGE_H */