OpenTTD Source 20260311-master-g511d3794ce
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef NEWGRF_STORAGE_H
11#define NEWGRF_STORAGE_H
12
13#include "core/pool_type.hpp"
14#include "newgrf.h"
15#include "tile_type.h"
16
28
34 uint32_t grfid = 0;
37
39
40 static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode = false);
41
42protected:
46 virtual void ClearChanges() = 0;
47
53 static bool AreChangesPersistent() { return (gameloop || command) && !testmode; }
54
55private:
56 static bool gameloop;
57 static bool command;
58 static bool testmode;
59};
60
67template <typename TYPE, uint SIZE>
69 using StorageType = std::array<TYPE, SIZE>;
70
71 StorageType storage{};
72 std::unique_ptr<StorageType> prev_storage{};
73
81 void StoreValue(uint pos, int32_t value)
82 {
83 /* Out of the scope of the array */
84 if (pos >= SIZE) return;
85
86 /* The value hasn't changed, so we pretend nothing happened.
87 * Saves a few cycles and such and it's pretty easy to check. */
88 if (this->storage[pos] == value) return;
89
90 /* We do not have made a backup; lets do so */
92 assert(!this->prev_storage);
93 } else if (!this->prev_storage) {
94 this->prev_storage = std::make_unique<StorageType>(this->storage);
95
96 /* We only need to register ourselves when we made the backup
97 * as that is the only time something will have changed */
99 }
100
101 this->storage[pos] = value;
102 }
103
109 TYPE GetValue(uint pos) const
110 {
111 /* Out of the scope of the array */
112 if (pos >= SIZE) return 0;
113
114 return this->storage[pos];
115 }
116
117 void ClearChanges() override
118 {
119 if (this->prev_storage) {
120 this->storage = *this->prev_storage;
121 this->prev_storage.reset();
122 }
123 }
124};
125
126
133template <typename TYPE, uint SIZE>
135 using StorageType = std::array<TYPE, SIZE>;
136 using StorageInitType = std::array<uint16_t, SIZE>;
137
138 StorageType storage{};
139 StorageInitType init{};
140 uint16_t init_key = 1;
141
147 void StoreValue(uint pos, int32_t value)
148 {
149 /* Out of the scope of the array */
150 if (pos >= SIZE) return;
151
152 this->storage[pos] = value;
153 this->init[pos] = this->init_key;
154 }
155
161 TYPE GetValue(uint pos) const
162 {
163 /* Out of the scope of the array */
164 if (pos >= SIZE) return 0;
165
166 if (this->init[pos] != this->init_key) {
167 /* Unassigned since last call to ClearChanges */
168 return 0;
169 }
170
171 return this->storage[pos];
172 }
173
174 void ClearChanges()
175 {
176 /* Increment init_key to invalidate all storage */
177 this->init_key++;
178 if (this->init_key == 0) {
179 /* When init_key wraps around, we need to reset everything */
180 this->init = {};
181 this->init_key = 1;
182 }
183 }
184};
185
187
188typedef PersistentStorageArray<int32_t, 16> OldPersistentStorage;
189
191
192struct PersistentStorage;
193using PersistentStoragePool = Pool<PersistentStorage, PersistentStorageID, 1>;
194
195extern PersistentStoragePool _persistent_storage_pool;
196
200struct PersistentStorage : PersistentStorageArray<int32_t, 256>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
201 PersistentStorage(PersistentStorageID index, const uint32_t new_grfid, GrfSpecFeature feature, TileIndex tile) : PersistentStoragePool::PoolItem<&_persistent_storage_pool>(index)
202 {
203 this->grfid = new_grfid;
204 this->feature = feature;
205 this->tile = tile;
206 }
207};
208
209static_assert(std::tuple_size_v<decltype(OldPersistentStorage::storage)> <= std::tuple_size_v<decltype(PersistentStorage::storage)>);
210
211#endif /* NEWGRF_STORAGE_H */
Base for the NewGRF implementation.
GrfSpecFeature
Definition newgrf.h:71
@ GSF_INVALID
An invalid spec feature.
Definition newgrf.h:102
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.
SwitchMode
Mode which defines what mode we're switching to.
Definition openttd.h:26
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.
GrfSpecFeature 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.
uint32_t grfid
GRFID associated to this persistent storage. A value of zero means "default".
virtual ~BasePersistentStorageArray()
Remove references to us.
Class for persistent storage of data.
void ClearChanges() override
Discard temporary changes.
std::unique_ptr< StorageType > prev_storage
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.
Templated helper to make a PoolID a single POD value.
Definition pool_type.hpp:47
Base class for all pools.
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.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100