OpenTTD Source  20240917-master-g9ab0a47812
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 
27 };
28 
34  uint32_t grfid;
35  uint8_t feature;
37 
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>
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 */
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>
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 
186 
188 
189 typedef uint32_t PersistentStorageID;
190 
191 struct PersistentStorage;
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, uint8_t feature, TileIndex tile)
202  {
203  this->grfid = new_grfid;
204  this->feature = feature;
205  this->tile = tile;
206  }
207 };
208 
209 static_assert(std::tuple_size_v<decltype(OldPersistentStorage::storage)> <= std::tuple_size_v<decltype(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
PersistentStorage::PersistentStorage
PersistentStorage(const uint32_t new_grfid, uint8_t 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::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::feature
uint8_t feature
NOSAVE: Used to identify in the owner of the array in debug output.
Definition: newgrf_storage.h:35
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
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:237
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
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