OpenTTD
newgrf_storage.h
Go to the documentation of this file.
1 /* $Id: newgrf_storage.h 26371 2014-02-23 22:03:08Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef NEWGRF_STORAGE_H
13 #define NEWGRF_STORAGE_H
14 
15 #include "core/pool_type.hpp"
16 #include "tile_type.h"
17 
28 };
29 
35  uint32 grfid;
36  byte feature;
38 
40 
41  static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode = false);
42 
43 protected:
47  virtual void ClearChanges() = 0;
48 
53  static bool AreChangesPersistent() { return (gameloop || command) && !testmode; }
54 
55 private:
56  static bool gameloop;
57  static bool command;
58  static bool testmode;
59 };
60 
67 template <typename TYPE, uint SIZE>
69  TYPE storage[SIZE];
70  TYPE *prev_storage;
71 
73  PersistentStorageArray() : prev_storage(NULL)
74  {
75  memset(this->storage, 0, sizeof(this->storage));
76  }
77 
80  {
81  free(this->prev_storage);
82  }
83 
85  void ResetToZero()
86  {
87  memset(this->storage, 0, sizeof(this->storage));
88  }
89 
97  void StoreValue(uint pos, int32 value)
98  {
99  /* Out of the scope of the array */
100  if (pos >= SIZE) return;
101 
102  /* The value hasn't changed, so we pretend nothing happened.
103  * Saves a few cycles and such and it's pretty easy to check. */
104  if (this->storage[pos] == value) return;
105 
106  /* We do not have made a backup; lets do so */
107  if (AreChangesPersistent()) {
108  assert(this->prev_storage == NULL);
109  } else if (this->prev_storage == NULL) {
110  this->prev_storage = MallocT<TYPE>(SIZE);
111  memcpy(this->prev_storage, this->storage, sizeof(this->storage));
112 
113  /* We only need to register ourselves when we made the backup
114  * as that is the only time something will have changed */
116  }
117 
118  this->storage[pos] = value;
119  }
120 
126  TYPE GetValue(uint pos) const
127  {
128  /* Out of the scope of the array */
129  if (pos >= SIZE) return 0;
130 
131  return this->storage[pos];
132  }
133 
135  {
136  if (this->prev_storage != NULL) {
137  memcpy(this->storage, this->prev_storage, sizeof(this->storage));
138  free(this->prev_storage);
139  this->prev_storage = NULL;
140  }
141  }
142 };
143 
144 
151 template <typename TYPE, uint SIZE>
153  TYPE storage[SIZE];
154  uint16 init[SIZE];
155  uint16 init_key;
156 
159  {
160  memset(this->storage, 0, sizeof(this->storage)); // not exactly needed, but makes code analysers happy
161  memset(this->init, 0, sizeof(this->init));
162  this->init_key = 1;
163  }
164 
170  void StoreValue(uint pos, int32 value)
171  {
172  /* Out of the scope of the array */
173  if (pos >= SIZE) return;
174 
175  this->storage[pos] = value;
176  this->init[pos] = this->init_key;
177  }
178 
184  TYPE GetValue(uint pos) const
185  {
186  /* Out of the scope of the array */
187  if (pos >= SIZE) return 0;
188 
189  if (this->init[pos] != this->init_key) {
190  /* Unassigned since last call to ClearChanges */
191  return 0;
192  }
193 
194  return this->storage[pos];
195  }
196 
197  void ClearChanges()
198  {
199  /* Increment init_key to invalidate all storage */
200  this->init_key++;
201  if (this->init_key == 0) {
202  /* When init_key wraps around, we need to reset everything */
203  memset(this->init, 0, sizeof(this->init));
204  this->init_key = 1;
205  }
206  }
207 };
208 
210 
212 
213 typedef uint32 PersistentStorageID;
214 
215 struct PersistentStorage;
217 
218 extern PersistentStoragePool _persistent_storage_pool;
219 
223 struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
225  PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile)
226  {
227  this->grfid = new_grfid;
228  this->feature = feature;
229  this->tile = tile;
230  }
231 };
232 
233 assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
234 
235 #define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
236 #define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
237 
238 #endif /* NEWGRF_STORAGE_H */
TileIndex tile
NOSAVE: Used to identify in the owner of the array in debug output.
TemporaryStorageArray()
Simply construct the array.
TYPE * prev_storage
Memory to store "old" states so we can revert them on the performance of test cases for commands etc...
Leave command test mode, revert to previous mode.
Enter command test mode, changes will be tempoary.
Class for temporary storage of data.
~PersistentStorageArray()
And free all data related to it.
byte feature
NOSAVE: Used to identify in the owner of the array in debug output.
Defintion of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle...
Class for persistent storage of data.
TYPE GetValue(uint pos) const
Gets the value from a given position.
void StoreValue(uint pos, int32 value)
Stores some value at a given position.
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...
PersistentStorageMode
Mode switches to the behaviour of persistent storage array.
Enter the gameloop, changes will be permanent.
uint32 grfid
GRFID associated to this persistent storage. A value of zero means "default".
PersistentStorage(const uint32 new_grfid, byte feature, TileIndex tile)
We don&#39;t want GCC to zero our struct! It already is zeroed and has an index!
virtual void ClearChanges()=0
Discard temporary changes.
void StoreValue(uint pos, int32 value)
Stores some value at a given position.
Class for pooled persistent storage of data.
void AddChangedPersistentStorage(BasePersistentStorageArray *storage)
Add the changed storage array to the list of changed arrays.
static bool AreChangesPersistent()
Check whether currently changes to the storage shall be persistent or temporary till the next call to...
Base class for all persistent NewGRF storage arrays.
Enter command scope, changes will be permanent.
Base class for all PoolItems.
Definition: pool_type.hpp:146
Leave command scope, revert to previous mode.
Base class for all pools.
Definition: pool_type.hpp:83
Leave the gameloop, changes will be temporary.
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
#define cpp_lengthof(base, variable)
Gets the length of an array variable within a class.
Definition: stdafx.h:456
void ClearChanges()
Discard temporary changes.
uint16 init_key
Magic key to &#39;init&#39;.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
PersistentStorageArray()
Simply construct the array.
TYPE GetValue(uint pos) const
Gets the value from a given position.
void ResetToZero()
Resets all values to zero.
Types related to tiles.
virtual ~BasePersistentStorageArray()
Remove references to use.