OpenTTD Source  20241121-master-g67a0fccfad
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 */
Functions related to the allocation of memory.
PersistentStorageMode
Mode switches to the behaviour of persistent storage array.
@ PSM_ENTER_GAMELOOP
Enter the gameloop, changes will be permanent.
@ PSM_LEAVE_TESTMODE
Leave command test mode, revert to previous mode.
@ PSM_LEAVE_COMMAND
Leave command scope, revert to previous mode.
@ PSM_LEAVE_GAMELOOP
Leave the gameloop, changes will be temporary.
@ PSM_ENTER_COMMAND
Enter command scope, changes will be permanent.
@ PSM_ENTER_TESTMODE
Enter command test mode, changes will be temporary.
void AddChangedPersistentStorage(BasePersistentStorageArray *storage)
Add the changed storage array to the list of changed arrays.
Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle,...
Base class for all persistent NewGRF storage arrays.
static bool AreChangesPersistent()
Check whether currently changes to the storage shall be persistent or temporary till the next call to...
virtual void ClearChanges()=0
Discard temporary changes.
uint8_t feature
NOSAVE: Used to identify in the owner of the array in debug output.
TileIndex tile
NOSAVE: Used to identify in the owner of the array in debug output.
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...
uint32_t grfid
GRFID associated to this persistent storage. A value of zero means "default".
virtual ~BasePersistentStorageArray()
Remove references to use.
Class for persistent storage of data.
StorageType storage
Memory for the storage array.
void ClearChanges() override
Discard temporary changes.
std::unique_ptr< StorageType > prev_storage
Temporary memory to store previous state so it can be reverted, e.g. for command tests.
TYPE GetValue(uint pos) const
Gets the value from a given position.
void StoreValue(uint pos, int32_t value)
Stores some value at a given position.
Class for pooled persistent storage of data.
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!
Base class for all PoolItems.
Definition: pool_type.hpp:237
Base class for all pools.
Definition: pool_type.hpp:80
Class for temporary storage of data.
uint16_t init_key
Magic key to 'init'.
TYPE GetValue(uint pos) const
Gets the value from a given position.
void StoreValue(uint pos, int32_t value)
Stores some value at a given position.
StorageInitType init
Storage has been assigned, if this equals 'init_key'.
StorageType storage
Memory for the storage array.
Types related to tiles.