Add non-animated SSSE3 blitter
[openttd/fttd.git] / src / newgrf_storage.h
blob40f661509dd118a21a5bd403e0fdd02257f71c8f
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file newgrf_storage.h Functionality related to the temporary and persistent storage arrays for NewGRFs. */
12 #ifndef NEWGRF_STORAGE_H
13 #define NEWGRF_STORAGE_H
15 #include "core/pool_type.hpp"
16 #include "map/coord.h"
18 /**
19 * Base class for all persistent NewGRF storage arrays. Nothing fancy, only here
20 * so we have a generalised access to the virtual methods.
22 struct BasePersistentStorageArray {
23 uint32 grfid; ///< GRFID associated to this persistent storage. A value of zero means "default".
24 byte feature; ///< NOSAVE: Used to identify in the owner of the array in debug output.
25 TileIndex tile; ///< NOSAVE: Used to identify in the owner of the array in debug output.
27 virtual ~BasePersistentStorageArray();
29 /**
30 * Clear the changes made since the last #ClearChanges.
31 * This can be done in two ways:
32 * - saving the changes permanently
33 * - reverting to the previous version
34 * @param keep_changes do we save or revert the changes since the last #ClearChanges?
36 virtual void ClearChanges(bool keep_changes) = 0;
39 /**
40 * Class for persistent storage of data.
41 * On #ClearChanges that data is either reverted or saved.
42 * @tparam TYPE the type of variable to store.
43 * @tparam SIZE the size of the array.
45 template <typename TYPE, uint SIZE>
46 struct PersistentStorageArray : BasePersistentStorageArray {
47 TYPE storage[SIZE]; ///< Memory to for the storage array
48 TYPE *prev_storage; ///< Memory to store "old" states so we can revert them on the performance of test cases for commands etc.
50 /** Simply construct the array */
51 PersistentStorageArray() : prev_storage(NULL)
53 memset(this->storage, 0, sizeof(this->storage));
56 /** And free all data related to it */
57 ~PersistentStorageArray()
59 free(this->prev_storage);
62 /** Resets all values to zero. */
63 void ResetToZero()
65 memset(this->storage, 0, sizeof(this->storage));
68 /**
69 * Stores some value at a given position.
70 * If there is no backup of the data that backup is made and then
71 * we write the data.
72 * @param pos the position to write at
73 * @param value the value to write
75 void StoreValue(uint pos, int32 value)
77 /* Out of the scope of the array */
78 if (pos >= SIZE) return;
80 /* The value hasn't changed, so we pretend nothing happened.
81 * Saves a few cycles and such and it's pretty easy to check. */
82 if (this->storage[pos] == value) return;
84 /* We do not have made a backup; lets do so */
85 if (this->prev_storage == NULL) {
86 this->prev_storage = MallocT<TYPE>(SIZE);
87 memcpy(this->prev_storage, this->storage, sizeof(this->storage));
89 /* We only need to register ourselves when we made the backup
90 * as that is the only time something will have changed */
91 AddChangedPersistentStorage(this);
94 this->storage[pos] = value;
97 /**
98 * Gets the value from a given position.
99 * @param pos the position to get the data from
100 * @return the data from that position
102 TYPE GetValue(uint pos) const
104 /* Out of the scope of the array */
105 if (pos >= SIZE) return 0;
107 return this->storage[pos];
111 * Clear the changes, or assign them permanently to the storage.
112 * @param keep_changes Whether to assign or ditch the changes.
114 void ClearChanges(bool keep_changes)
116 assert(this->prev_storage != NULL);
118 if (!keep_changes) {
119 memcpy(this->storage, this->prev_storage, sizeof(this->storage));
121 free(this->prev_storage);
122 this->prev_storage = NULL;
128 * Class for temporary storage of data.
129 * On #ClearChanges that data is always zero-ed.
130 * @tparam TYPE the type of variable to store.
131 * @tparam SIZE the size of the array.
133 template <typename TYPE, uint SIZE>
134 struct TemporaryStorageArray {
135 TYPE storage[SIZE]; ///< Memory to for the storage array
136 uint16 init[SIZE]; ///< Storage has been assigned, if this equals 'init_key'.
137 uint16 init_key; ///< Magic key to 'init'.
139 /** Simply construct the array */
140 TemporaryStorageArray()
142 memset(this->storage, 0, sizeof(this->storage)); // not exactly needed, but makes code analysers happy
143 memset(this->init, 0, sizeof(this->init));
144 this->init_key = 1;
148 * Stores some value at a given position.
149 * @param pos the position to write at
150 * @param value the value to write
152 void StoreValue(uint pos, int32 value)
154 /* Out of the scope of the array */
155 if (pos >= SIZE) return;
157 this->storage[pos] = value;
158 this->init[pos] = this->init_key;
162 * Gets the value from a given position.
163 * @param pos the position to get the data from
164 * @return the data from that position
166 TYPE GetValue(uint pos) const
168 /* Out of the scope of the array */
169 if (pos >= SIZE) return 0;
171 if (this->init[pos] != this->init_key) {
172 /* Unassigned since last call to ClearChanges */
173 return 0;
176 return this->storage[pos];
179 void ClearChanges()
181 /* Increment init_key to invalidate all storage */
182 this->init_key++;
183 if (this->init_key == 0) {
184 /* When init_key wraps around, we need to reset everything */
185 memset(this->init, 0, sizeof(this->init));
186 this->init_key = 1;
191 void AddChangedPersistentStorage(BasePersistentStorageArray *storage);
192 void ClearPersistentStorageChanges(bool keep_changes);
195 typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
197 typedef uint32 PersistentStorageID;
199 struct PersistentStorage;
200 typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
202 extern PersistentStoragePool _persistent_storage_pool;
205 * Class for pooled persistent storage of data.
207 struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
208 /** We don't want GCC to zero our struct! It already is zeroed and has an index! */
209 PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile)
211 this->grfid = new_grfid;
212 this->feature = feature;
213 this->tile = tile;
217 assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
219 #define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
220 #define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
222 #endif /* NEWGRF_STORAGE_H */