OpenTTD Source: src/newgrf_storage.h Source File

OpenTTD Source 14.0-beta3

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/alloc_func.hpp"
14 #include "core/pool_type.hpp"
15 #include "tile_type.h"
16
20 enum PersistentStorageMode {
21 PSM_ENTER_GAMELOOP,
22 PSM_LEAVE_GAMELOOP,
23 PSM_ENTER_COMMAND,
24 PSM_LEAVE_COMMAND,
25 PSM_ENTER_TESTMODE,
26 PSM_LEAVE_TESTMODE,
27 };
28
33 struct BasePersistentStorageArray {
34 uint32_t grfid;
35 byte feature;
36 TileIndex tile;
37
38 virtual ~BasePersistentStorageArray();
39
40 static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode = false);
41
42 protected:
46 virtual void ClearChanges() = 0;
47
52 static bool AreChangesPersistent() { return (gameloop || command) && !testmode; }
53
54 private:
55 static bool gameloop;
56 static bool command;
57 static bool testmode;
58 };
59
66 template <typename TYPE, uint SIZE>
67 struct PersistentStorageArray : BasePersistentStorageArray {
68 using StorageType = std::array<TYPE, SIZE>;
69
70 StorageType storage{};
71 std::unique_ptr<StorageType> prev_storage{};
72
80 void StoreValue(uint pos, int32_t value)
81 {
82 /* Out of the scope of the array */
83 if (pos >= SIZE) return;
84
85 /* The value hasn't changed, so we pretend nothing happened.
86 * Saves a few cycles and such and it's pretty easy to check. */
87 if (this->storage[pos] == value) return;
88
89 /* We do not have made a backup; lets do so */
90 if (AreChangesPersistent()) {
91 assert(!this->prev_storage);
92 } else if (!this->prev_storage) {
93 this->prev_storage = std::make_unique<StorageType>(this->storage);
94
95 /* We only need to register ourselves when we made the backup
96 * as that is the only time something will have changed */
97 AddChangedPersistentStorage(this);
98 }
99
100 this->storage[pos] = value;
101 }
102
108 TYPE GetValue(uint pos) const
109 {
110 /* Out of the scope of the array */
111 if (pos >= SIZE) return 0;
112
113 return this->storage[pos];
114 }
115
116 void ClearChanges() override
117 {
118 if (this->prev_storage) {
119 this->storage = *this->prev_storage;
120 this->prev_storage.reset();
121 }
122 }
123 };
124
125
132 template <typename TYPE, uint SIZE>
133 struct TemporaryStorageArray {
134 using StorageType = std::array<TYPE, SIZE>;
135 using StorageInitType = std::array<uint16_t, SIZE>;
136
137 StorageType storage{};
138 StorageInitType init{};
139 uint16_t init_key{1};
140
146 void StoreValue(uint pos, int32_t value)
147 {
148 /* Out of the scope of the array */
149 if (pos >= SIZE) return;
150
151 this->storage[pos] = value;
152 this->init[pos] = this->init_key;
153 }
154
160 TYPE GetValue(uint pos) const
161 {
162 /* Out of the scope of the array */
163 if (pos >= SIZE) return 0;
164
165 if (this->init[pos] != this->init_key) {
166 /* Unassigned since last call to ClearChanges */
167 return 0;
168 }
169
170 return this->storage[pos];
171 }
172
173 void ClearChanges()
174 {
175 /* Increment init_key to invalidate all storage */
176 this->init_key++;
177 if (this->init_key == 0) {
178 /* When init_key wraps around, we need to reset everything */
179 this->init = {};
180 this->init_key = 1;
181 }
182 }
183 };
184
185 void AddChangedPersistentStorage(BasePersistentStorageArray *storage);
186
187 typedef PersistentStorageArray<int32_t, 16> OldPersistentStorage;
188
189 typedef uint32_t PersistentStorageID;
190
191 struct PersistentStorage;
192 typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
193
194 extern PersistentStoragePool _persistent_storage_pool;
195
199 struct PersistentStorage : PersistentStorageArray<int32_t, 256>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
201 PersistentStorage(const uint32_t new_grfid, byte feature, TileIndex tile)
202 {
203 this->grfid = new_grfid;
204 this->feature = feature;
205 this->tile = tile;
206 }
207 };
208
209 static_assert(cpp_lengthof(OldPersistentStorage, storage) <= cpp_lengthof(PersistentStorage, storage));
210
211 #endif /* NEWGRF_STORAGE_H */
PSM_LEAVE_TESTMODE
@ PSM_LEAVE_TESTMODE
Leave command test mode, revert to previous mode.
Definition: newgrf_storage.h:26
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:52
TemporaryStorageArray::storage
StorageType storage
Memory for the storage array.
Definition: newgrf_storage.h:137
PersistentStorageArray::ClearChanges
void ClearChanges() override
Discard temporary changes.
Definition: newgrf_storage.h:116
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
BasePersistentStorageArray::~BasePersistentStorageArray
virtual ~BasePersistentStorageArray()
Remove references to use.
Definition: newgrf_storage.cpp:31
PersistentStorageArray::GetValue
TYPE GetValue(uint pos) const
Gets the value from a given position.
Definition: newgrf_storage.h:108
PersistentStorage
Class for pooled persistent storage of data.
Definition: newgrf_storage.h:199
PSM_LEAVE_COMMAND
@ PSM_LEAVE_COMMAND
Leave command scope, revert to previous mode.
Definition: newgrf_storage.h:24
PSM_ENTER_GAMELOOP
@ PSM_ENTER_GAMELOOP
Enter the gameloop, changes will be permanent.
Definition: newgrf_storage.h:21
TemporaryStorageArray::init
StorageInitType init
Storage has been assigned, if this equals 'init_key'.
Definition: newgrf_storage.h:138
BasePersistentStorageArray::ClearChanges
virtual void ClearChanges()=0
Discard temporary changes.
BasePersistentStorageArray::grfid
uint32_t grfid
GRFID associated to this persistent storage. A value of zero means "default".
Definition: newgrf_storage.h:34
BasePersistentStorageArray::tile
TileIndex tile
NOSAVE: Used to identify in the owner of the array in debug output.
Definition: newgrf_storage.h:36
BasePersistentStorageArray::feature
byte feature
NOSAVE: Used to identify in the owner of the array in debug output.
Definition: newgrf_storage.h:35
BasePersistentStorageArray
Base class for all persistent NewGRF storage arrays.
Definition: newgrf_storage.h:33
Pool
Base class for all pools.
Definition: pool_type.hpp:80
alloc_func.hpp
tile_type.h
PersistentStorageArray::storage
StorageType storage
Memory for the storage array.
Definition: newgrf_storage.h:70
TemporaryStorageArray
Class for temporary storage of data.
Definition: newgrf_storage.h:133
PSM_LEAVE_GAMELOOP
@ PSM_LEAVE_GAMELOOP
Leave the gameloop, changes will be temporary.
Definition: newgrf_storage.h:22
TemporaryStorageArray::init_key
uint16_t init_key
Magic key to 'init'.
Definition: newgrf_storage.h:139
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:54
TemporaryStorageArray::StoreValue
void StoreValue(uint pos, int32_t value)
Stores some value at a given position.
Definition: newgrf_storage.h:146
PSM_ENTER_COMMAND
@ PSM_ENTER_COMMAND
Enter command scope, changes will be permanent.
Definition: newgrf_storage.h:23
pool_type.hpp
PSM_ENTER_TESTMODE
@ PSM_ENTER_TESTMODE
Enter command test mode, changes will be temporary.
Definition: newgrf_storage.h:25
Pool::PoolItem
Base class for all PoolItems.
Definition: pool_type.hpp:233
cpp_lengthof
#define cpp_lengthof(base, variable)
Gets the length of an array variable within a class.
Definition: stdafx.h:332
PersistentStorageArray::StoreValue
void StoreValue(uint pos, int32_t value)
Stores some value at a given position.
Definition: newgrf_storage.h:80
AddChangedPersistentStorage
void AddChangedPersistentStorage(BasePersistentStorageArray *storage)
Add the changed storage array to the list of changed arrays.
Definition: newgrf_storage.cpp:42
TemporaryStorageArray::GetValue
TYPE GetValue(uint pos) const
Gets the value from a given position.
Definition: newgrf_storage.h:160
PersistentStorageArray::prev_storage
std::unique_ptr< StorageType > prev_storage
Temporary memory to store previous state so it can be reverted, e.g. for command tests.
Definition: newgrf_storage.h:71
PersistentStorage::PersistentStorage
PersistentStorage(const uint32_t 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:201
PersistentStorageArray
Class for persistent storage of data.
Definition: newgrf_storage.h:67
PersistentStorageMode
PersistentStorageMode
Mode switches to the behaviour of persistent storage array.
Definition: newgrf_storage.h:20