OpenTTD Source: src/newgrf_storage.h Source File

OpenTTD Source 1.11.0-RC1

newgrf_storage.h
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10 #ifndef NEWGRF_STORAGE_H
11 #define NEWGRF_STORAGE_H
12
13 #include "core/pool_type.hpp"
14 #include "tile_type.h"
15
19 enum PersistentStorageMode {
20 PSM_ENTER_GAMELOOP,
21 PSM_LEAVE_GAMELOOP,
22 PSM_ENTER_COMMAND,
23 PSM_LEAVE_COMMAND,
24 PSM_ENTER_TESTMODE,
25 PSM_LEAVE_TESTMODE,
26 };
27
32 struct BasePersistentStorageArray {
33 uint32 grfid;
34 byte feature;
35 TileIndex tile;
36
37 virtual ~BasePersistentStorageArray();
38
39 static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode = false);
40
41 protected:
45 virtual void ClearChanges() = 0;
46
51 static bool AreChangesPersistent() { return (gameloop || command) && !testmode; }
52
53 private:
54 static bool gameloop;
55 static bool command;
56 static bool testmode;
57 };
58
65 template <typename TYPE, uint SIZE>
66 struct PersistentStorageArray : BasePersistentStorageArray {
67 TYPE storage[SIZE];
68 TYPE *prev_storage;
69
71 PersistentStorageArray() : prev_storage(nullptr)
72 {
73 memset(this->storage, 0, sizeof(this->storage));
74 }
75
77 ~PersistentStorageArray()
78 {
79 free(this->prev_storage);
80 }
81
83 void ResetToZero()
84 {
85 memset(this->storage, 0, sizeof(this->storage));
86 }
87
95 void StoreValue(uint pos, int32 value)
96 {
97 /* Out of the scope of the array */
98 if (pos >= SIZE) return;
99
100 /* The value hasn't changed, so we pretend nothing happened.
101 * Saves a few cycles and such and it's pretty easy to check. */
102 if (this->storage[pos] == value) return;
103
104 /* We do not have made a backup; lets do so */
105 if (AreChangesPersistent()) {
106 assert(this->prev_storage == nullptr);
107 } else if (this->prev_storage == nullptr) {
108 this->prev_storage = MallocT<TYPE>(SIZE);
109 memcpy(this->prev_storage, this->storage, sizeof(this->storage));
110
111 /* We only need to register ourselves when we made the backup
112 * as that is the only time something will have changed */
113 AddChangedPersistentStorage(this);
114 }
115
116 this->storage[pos] = value;
117 }
118
124 TYPE GetValue(uint pos) const
125 {
126 /* Out of the scope of the array */
127 if (pos >= SIZE) return 0;
128
129 return this->storage[pos];
130 }
131
132 void ClearChanges()
133 {
134 if (this->prev_storage != nullptr) {
135 memcpy(this->storage, this->prev_storage, sizeof(this->storage));
136 free(this->prev_storage);
137 this->prev_storage = nullptr;
138 }
139 }
140 };
141
142
149 template <typename TYPE, uint SIZE>
150 struct TemporaryStorageArray {
151 TYPE storage[SIZE];
152 uint16 init[SIZE];
153 uint16 init_key;
154
156 TemporaryStorageArray()
157 {
158 memset(this->storage, 0, sizeof(this->storage)); // not exactly needed, but makes code analysers happy
159 memset(this->init, 0, sizeof(this->init));
160 this->init_key = 1;
161 }
162
168 void StoreValue(uint pos, int32 value)
169 {
170 /* Out of the scope of the array */
171 if (pos >= SIZE) return;
172
173 this->storage[pos] = value;
174 this->init[pos] = this->init_key;
175 }
176
182 TYPE GetValue(uint pos) const
183 {
184 /* Out of the scope of the array */
185 if (pos >= SIZE) return 0;
186
187 if (this->init[pos] != this->init_key) {
188 /* Unassigned since last call to ClearChanges */
189 return 0;
190 }
191
192 return this->storage[pos];
193 }
194
195 void ClearChanges()
196 {
197 /* Increment init_key to invalidate all storage */
198 this->init_key++;
199 if (this->init_key == 0) {
200 /* When init_key wraps around, we need to reset everything */
201 memset(this->init, 0, sizeof(this->init));
202 this->init_key = 1;
203 }
204 }
205 };
206
207 void AddChangedPersistentStorage(BasePersistentStorageArray *storage);
208
209 typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
210
211 typedef uint32 PersistentStorageID;
212
213 struct PersistentStorage;
214 typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
215
216 extern PersistentStoragePool _persistent_storage_pool;
217
221 struct PersistentStorage : PersistentStorageArray<int32, 256>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
223 PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile)
224 {
225 this->grfid = new_grfid;
226 this->feature = feature;
227 this->tile = tile;
228 }
229 };
230
231 static_assert(cpp_lengthof(OldPersistentStorage, storage) <= cpp_lengthof(PersistentStorage, storage));
232
233 #endif /* NEWGRF_STORAGE_H */
PSM_LEAVE_TESTMODE
@ PSM_LEAVE_TESTMODE
Leave command test mode, revert to previous mode.
Definition: newgrf_storage.h:25
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
BasePersistentStorageArray::AreChangesPersistent
static bool AreChangesPersistent()
Check whether currently changes to the storage shall be persistent or temporary till the next call to...
Definition: newgrf_storage.h:51
TemporaryStorageArray::storage
TYPE storage[SIZE]
Memory to for the storage array.
Definition: newgrf_storage.h:151
PersistentStorageArray::~PersistentStorageArray
~PersistentStorageArray()
And free all data related to it.
Definition: newgrf_storage.h:77
BasePersistentStorageArray::~BasePersistentStorageArray
virtual ~BasePersistentStorageArray()
Remove references to use.
Definition: newgrf_storage.cpp:32
PersistentStorageArray::GetValue
TYPE GetValue(uint pos) const
Gets the value from a given position.
Definition: newgrf_storage.h:124
PersistentStorage
Class for pooled persistent storage of data.
Definition: newgrf_storage.h:221
PSM_LEAVE_COMMAND
@ PSM_LEAVE_COMMAND
Leave command scope, revert to previous mode.
Definition: newgrf_storage.h:23
PSM_ENTER_GAMELOOP
@ PSM_ENTER_GAMELOOP
Enter the gameloop, changes will be permanent.
Definition: newgrf_storage.h:20
PersistentStorageArray::StoreValue
void StoreValue(uint pos, int32 value)
Stores some value at a given position.
Definition: newgrf_storage.h:95
PersistentStorageArray::storage
TYPE storage[SIZE]
Memory to for the storage array.
Definition: newgrf_storage.h:67
BasePersistentStorageArray::ClearChanges
virtual void ClearChanges()=0
Discard temporary changes.
BasePersistentStorageArray::tile
TileIndex tile
NOSAVE: Used to identify in the owner of the array in debug output.
Definition: newgrf_storage.h:35
BasePersistentStorageArray::feature
byte feature
NOSAVE: Used to identify in the owner of the array in debug output.
Definition: newgrf_storage.h:34
BasePersistentStorageArray
Base class for all persistent NewGRF storage arrays.
Definition: newgrf_storage.h:32
TemporaryStorageArray::StoreValue
void StoreValue(uint pos, int32 value)
Stores some value at a given position.
Definition: newgrf_storage.h:168
Pool
Base class for all pools.
Definition: pool_type.hpp:81
tile_type.h
PersistentStorageArray::ResetToZero
void ResetToZero()
Resets all values to zero.
Definition: newgrf_storage.h:83
TemporaryStorageArray::init
uint16 init[SIZE]
Storage has been assigned, if this equals 'init_key'.
Definition: newgrf_storage.h:152
PersistentStorageArray::ClearChanges
void ClearChanges()
Discard temporary changes.
Definition: newgrf_storage.h:132
TemporaryStorageArray
Class for temporary storage of data.
Definition: newgrf_storage.h:150
PSM_LEAVE_GAMELOOP
@ PSM_LEAVE_GAMELOOP
Leave the gameloop, changes will be temporary.
Definition: newgrf_storage.h:21
BasePersistentStorageArray::SwitchMode
static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode=false)
Clear temporary changes made since the last call to SwitchMode, and set whether subsequent changes sh...
Definition: newgrf_storage.cpp:55
TemporaryStorageArray::init_key
uint16 init_key
Magic key to 'init'.
Definition: newgrf_storage.h:153
PSM_ENTER_COMMAND
@ PSM_ENTER_COMMAND
Enter command scope, changes will be permanent.
Definition: newgrf_storage.h:22
BasePersistentStorageArray::grfid
uint32 grfid
GRFID associated to this persistent storage. A value of zero means "default".
Definition: newgrf_storage.h:33
pool_type.hpp
TemporaryStorageArray::TemporaryStorageArray
TemporaryStorageArray()
Simply construct the array.
Definition: newgrf_storage.h:156
PersistentStorageArray::prev_storage
TYPE * prev_storage
Memory to store "old" states so we can revert them on the performance of test cases for commands etc.
Definition: newgrf_storage.h:68
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:454
PersistentStorageArray::PersistentStorageArray
PersistentStorageArray()
Simply construct the array.
Definition: newgrf_storage.h:71
PSM_ENTER_TESTMODE
@ PSM_ENTER_TESTMODE
Enter command test mode, changes will be tempoary.
Definition: newgrf_storage.h:24
Pool::PoolItem
Base class for all PoolItems.
Definition: pool_type.hpp:226
cpp_lengthof
#define cpp_lengthof(base, variable)
Gets the length of an array variable within a class.
Definition: stdafx.h:399
AddChangedPersistentStorage
void AddChangedPersistentStorage(BasePersistentStorageArray *storage)
Add the changed storage array to the list of changed arrays.
Definition: newgrf_storage.cpp:43
TemporaryStorageArray::GetValue
TYPE GetValue(uint pos) const
Gets the value from a given position.
Definition: newgrf_storage.h:182
PersistentStorageArray
Class for persistent storage of data.
Definition: newgrf_storage.h:66
PersistentStorageMode
PersistentStorageMode
Mode switches to the behaviour of persistent storage array.
Definition: newgrf_storage.h:19
PersistentStorage::PersistentStorage
PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile)
We don't want GCC to zero our struct! It already is zeroed and has an index!
Definition: newgrf_storage.h:223