# 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 */