# newgrf_storage.h

Go to the documentation of this file.

    00001 /* $Id: newgrf_storage.h 17248 2009-08-21 20:21:05Z rubidium $ */
    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
    00021 struct BaseStorageArray
    00022 {
    00024   virtual ~BaseStorageArray() {}
    00025
    00033   virtual void ClearChanges(bool keep_changes) = 0;
    00034
    00040   virtual void Store(uint pos, uint32 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
    00073   void Store(uint pos, uint32 value)
    00074   {
    00075     /* Out of the scope of the array */
    00076     if (pos >= SIZE) return;
    00077
    00078     /* The value hasn't changed, so we pretend nothing happened.
    00079      * Saves a few cycles and such and it's pretty easy to check. */
    00080     if (this->storage[pos] == value) return;
    00081
    00082     /* We do not have made a backup; lets do so */
    00083     if (this->prev_storage != NULL) {
    00084       this->prev_storage = MallocT<TYPE>(SIZE);
    00085       memcpy(this->prev_storage, this->storage, sizeof(this->storage));
    00086
    00087       /* We only need to register ourselves when we made the backup
    00088        * as that is the only time something will have changed */
    00089       AddChangedStorage(this);
    00090     }
    00091
    00092     this->storage[pos] = value;
    00093   }
    00094
    00100   TYPE Get(uint pos) const
    00101   {
    00102     /* Out of the scope of the array */
    00103     if (pos >= SIZE) return 0;
    00104
    00105     return this->storage[pos];
    00106   }
    00107
    00108   void ClearChanges(bool keep_changes)
    00109   {
    00110     assert(this->prev_storage != NULL);
    00111
    00112     if (!keep_changes) {
    00113       memcpy(this->storage, this->prev_storage, sizeof(this->storage));
    00114     }
    00115     free(this->prev_storage);
    00116   }
    00117 };
    00118
    00119
    00126 template <typename TYPE, uint SIZE>
    00127 struct TemporaryStorageArray : BaseStorageArray {
    00128   TYPE storage[SIZE];
    00129
    00131   TemporaryStorageArray()
    00132   {
    00133     memset(this->storage, 0, sizeof(this->storage));
    00134   }
    00135
    00141   void Store(uint pos, uint32 value)
    00142   {
    00143     /* Out of the scope of the array */
    00144     if (pos >= SIZE) return;
    00145
    00146     this->storage[pos] = value;
    00147     AddChangedStorage(this);
    00148   }
    00149
    00155   TYPE Get(uint pos) const
    00156   {
    00157     /* Out of the scope of the array */
    00158     if (pos >= SIZE) return 0;
    00159
    00160     return this->storage[pos];
    00161   }
    00162
    00163   void ClearChanges(bool keep_changes)
    00164   {
    00165     memset(this->storage, 0, sizeof(this->storage));
    00166   }
    00167 };
    00168
    00175 void AddChangedStorage(BaseStorageArray *storage);
    00176
    00177
    00188 void ClearStorageChanges(bool keep_changes);
    00189
    00190 #endif /* NEWGRF_STORAGE_H */