mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(svn r10744) -Codechange: make the pool a little more OO, so it can be easier in other places.
This commit is contained in:
parent
435d39f8fb
commit
4e96ce3dfe
@ -12,27 +12,27 @@
|
|||||||
/**
|
/**
|
||||||
* Clean a pool in a safe way (does free all blocks)
|
* Clean a pool in a safe way (does free all blocks)
|
||||||
*/
|
*/
|
||||||
void CleanPool(OldMemoryPool *pool)
|
void OldMemoryPoolBase::CleanPool()
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
DEBUG(misc, 4, "[Pool] (%s) cleaning pool..", pool->name);
|
DEBUG(misc, 4, "[Pool] (%s) cleaning pool..", this->name);
|
||||||
|
|
||||||
/* Free all blocks */
|
/* Free all blocks */
|
||||||
for (i = 0; i < pool->current_blocks; i++) {
|
for (i = 0; i < this->current_blocks; i++) {
|
||||||
if (pool->clean_block_proc != NULL) {
|
if (this->clean_block_proc != NULL) {
|
||||||
pool->clean_block_proc(i * (1 << pool->block_size_bits), (i + 1) * (1 << pool->block_size_bits) - 1);
|
this->clean_block_proc(i * (1 << this->block_size_bits), (i + 1) * (1 << this->block_size_bits) - 1);
|
||||||
}
|
}
|
||||||
free(pool->blocks[i]);
|
free(this->blocks[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the block itself */
|
/* Free the block itself */
|
||||||
free(pool->blocks);
|
free(this->blocks);
|
||||||
|
|
||||||
/* Clear up some critical data */
|
/* Clear up some critical data */
|
||||||
pool->total_items = 0;
|
this->total_items = 0;
|
||||||
pool->current_blocks = 0;
|
this->current_blocks = 0;
|
||||||
pool->blocks = NULL;
|
this->blocks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,34 +41,32 @@ void CleanPool(OldMemoryPool *pool)
|
|||||||
*
|
*
|
||||||
* @return Returns false if the pool could not be increased
|
* @return Returns false if the pool could not be increased
|
||||||
*/
|
*/
|
||||||
bool AddBlockToPool(OldMemoryPool *pool)
|
bool OldMemoryPoolBase::AddBlockToPool()
|
||||||
{
|
{
|
||||||
/* Is the pool at his max? */
|
/* Is the pool at his max? */
|
||||||
if (pool->max_blocks == pool->current_blocks)
|
if (this->max_blocks == this->current_blocks) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
pool->total_items = (pool->current_blocks + 1) * (1 << pool->block_size_bits);
|
this->total_items = (this->current_blocks + 1) * (1 << this->block_size_bits);
|
||||||
|
|
||||||
DEBUG(misc, 4, "[Pool] (%s) increasing size of pool to %d items (%d bytes)", pool->name, pool->total_items, pool->total_items * pool->item_size);
|
DEBUG(misc, 4, "[Pool] (%s) increasing size of pool to %d items (%d bytes)", this->name, this->total_items, this->total_items * this->item_size);
|
||||||
|
|
||||||
/* Increase the poolsize */
|
/* Increase the poolsize */
|
||||||
pool->blocks = ReallocT(pool->blocks, pool->current_blocks + 1);
|
this->blocks = ReallocT(this->blocks, this->current_blocks + 1);
|
||||||
if (pool->blocks == NULL) error("Pool: (%s) could not allocate memory for blocks", pool->name);
|
if (this->blocks == NULL) error("Pool: (%s) could not allocate memory for blocks", this->name);
|
||||||
|
|
||||||
/* Allocate memory to the new block item */
|
/* Allocate memory to the new block item */
|
||||||
pool->blocks[pool->current_blocks] = MallocT<byte>(pool->item_size * (1 << pool->block_size_bits));
|
this->blocks[this->current_blocks] = MallocT<byte>(this->item_size * (1 << this->block_size_bits));
|
||||||
if (pool->blocks[pool->current_blocks] == NULL)
|
if (this->blocks[this->current_blocks] == NULL)
|
||||||
error("Pool: (%s) could not allocate memory for blocks", pool->name);
|
error("Pool: (%s) could not allocate memory for blocks", this->name);
|
||||||
|
|
||||||
/* Clean the content of the new block */
|
/* Clean the content of the new block */
|
||||||
memset(pool->blocks[pool->current_blocks], 0, pool->item_size * (1 << pool->block_size_bits));
|
memset(this->blocks[this->current_blocks], 0, this->item_size * (1 << this->block_size_bits));
|
||||||
|
|
||||||
/* Call a custom function if defined (e.g. to fill indexes) */
|
/* Call a custom function if defined (e.g. to fill indexes) */
|
||||||
if (pool->new_block_proc != NULL)
|
if (this->new_block_proc != NULL) this->new_block_proc(this->current_blocks * (1 << this->block_size_bits));
|
||||||
pool->new_block_proc(pool->current_blocks * (1 << pool->block_size_bits));
|
|
||||||
|
|
||||||
/* We have a new block */
|
/* We have a new block */
|
||||||
pool->current_blocks++;
|
this->current_blocks++;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -78,11 +76,10 @@ bool AddBlockToPool(OldMemoryPool *pool)
|
|||||||
*
|
*
|
||||||
* @return Returns false if adding failed
|
* @return Returns false if adding failed
|
||||||
*/
|
*/
|
||||||
bool AddBlockIfNeeded(OldMemoryPool *pool, uint index)
|
bool OldMemoryPoolBase::AddBlockIfNeeded(uint index)
|
||||||
{
|
{
|
||||||
while (index >= pool->total_items) {
|
while (index >= this->total_items) {
|
||||||
if (!AddBlockToPool(pool))
|
if (!this->AddBlockToPool()) return false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
#ifndef OLDPOOL_H
|
#ifndef OLDPOOL_H
|
||||||
#define OLDPOOL_H
|
#define OLDPOOL_H
|
||||||
|
|
||||||
struct OldMemoryPool;
|
|
||||||
|
|
||||||
/* The function that is called after a new block is added
|
/* The function that is called after a new block is added
|
||||||
start_item is the first item of the new made block */
|
start_item is the first item of the new made block */
|
||||||
typedef void OldMemoryPoolNewBlock(uint start_item);
|
typedef void OldMemoryPoolNewBlock(uint start_item);
|
||||||
@ -17,7 +15,18 @@ typedef void OldMemoryPoolCleanBlock(uint start_item, uint end_item);
|
|||||||
* Stuff for dynamic vehicles. Use the wrappers to access the OldMemoryPool
|
* Stuff for dynamic vehicles. Use the wrappers to access the OldMemoryPool
|
||||||
* please try to avoid manual calls!
|
* please try to avoid manual calls!
|
||||||
*/
|
*/
|
||||||
struct OldMemoryPool {
|
struct OldMemoryPoolBase {
|
||||||
|
void CleanPool();
|
||||||
|
bool AddBlockToPool();
|
||||||
|
bool AddBlockIfNeeded(uint index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
OldMemoryPoolBase(const char *name, uint max_blocks, uint block_size_bits, uint item_size,
|
||||||
|
OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) :
|
||||||
|
name(name), max_blocks(max_blocks), block_size_bits(block_size_bits), item_size(item_size),
|
||||||
|
new_block_proc(new_block_proc), clean_block_proc(clean_block_proc), current_blocks(0),
|
||||||
|
total_items(0), blocks(NULL) {}
|
||||||
|
|
||||||
const char* name; ///< Name of the pool (just for debugging)
|
const char* name; ///< Name of the pool (just for debugging)
|
||||||
|
|
||||||
uint max_blocks; ///< The max amount of blocks this pool can have
|
uint max_blocks; ///< The max amount of blocks this pool can have
|
||||||
@ -32,7 +41,37 @@ struct OldMemoryPool {
|
|||||||
uint current_blocks; ///< How many blocks we have in our pool
|
uint current_blocks; ///< How many blocks we have in our pool
|
||||||
uint total_items; ///< How many items we now have in this pool
|
uint total_items; ///< How many items we now have in this pool
|
||||||
|
|
||||||
|
public:
|
||||||
byte **blocks; ///< An array of blocks (one block hold all the items)
|
byte **blocks; ///< An array of blocks (one block hold all the items)
|
||||||
|
|
||||||
|
inline uint GetSize()
|
||||||
|
{
|
||||||
|
return this->total_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CanAllocateMoreBlocks()
|
||||||
|
{
|
||||||
|
return this->current_blocks < this->max_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint GetBlockCount()
|
||||||
|
{
|
||||||
|
return this->current_blocks;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct OldMemoryPool : public OldMemoryPoolBase {
|
||||||
|
OldMemoryPool(const char *name, uint max_blocks, uint block_size_bits, uint item_size,
|
||||||
|
OldMemoryPoolNewBlock *new_block_proc, OldMemoryPoolCleanBlock *clean_block_proc) :
|
||||||
|
OldMemoryPoolBase(name, max_blocks, block_size_bits, item_size, new_block_proc, clean_block_proc) {}
|
||||||
|
|
||||||
|
inline T *Get(uint index)
|
||||||
|
{
|
||||||
|
assert(index < this->GetSize());
|
||||||
|
return (T*)(this->blocks[index >> this->block_size_bits] +
|
||||||
|
(index & ((1 << this->block_size_bits) - 1)) * sizeof(T));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,15 +81,15 @@ struct OldMemoryPool {
|
|||||||
* AddBlockToPool adds 1 more block to the pool. Returns false if there is no
|
* AddBlockToPool adds 1 more block to the pool. Returns false if there is no
|
||||||
* more room
|
* more room
|
||||||
*/
|
*/
|
||||||
void CleanPool(OldMemoryPool *array);
|
static inline void CleanPool(OldMemoryPoolBase *array) { array->CleanPool(); }
|
||||||
bool AddBlockToPool(OldMemoryPool *array);
|
static inline bool AddBlockToPool(OldMemoryPoolBase *array) { return array->AddBlockToPool(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds blocks to the pool if needed (and possible) till index fits inside the pool
|
* Adds blocks to the pool if needed (and possible) till index fits inside the pool
|
||||||
*
|
*
|
||||||
* @return Returns false if adding failed
|
* @return Returns false if adding failed
|
||||||
*/
|
*/
|
||||||
bool AddBlockIfNeeded(OldMemoryPool *array, uint index);
|
static inline bool AddBlockIfNeeded(OldMemoryPoolBase *array, uint index) { return array->AddBlockIfNeeded(index); }
|
||||||
|
|
||||||
|
|
||||||
#define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
|
#define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
|
||||||
@ -61,33 +100,20 @@ bool AddBlockIfNeeded(OldMemoryPool *array, uint index);
|
|||||||
|
|
||||||
|
|
||||||
#define OLD_POOL_ACCESSORS(name, type) \
|
#define OLD_POOL_ACCESSORS(name, type) \
|
||||||
static inline type* Get##name(uint index) \
|
static inline type* Get##name(uint index) { return _##name##_pool.Get(index); } \
|
||||||
{ \
|
static inline uint Get##name##PoolSize() { return _##name##_pool.GetSize(); }
|
||||||
assert(index < _##name##_pool.total_items); \
|
|
||||||
return (type*)( \
|
|
||||||
_##name##_pool.blocks[index >> name##_POOL_BLOCK_SIZE_BITS] + \
|
|
||||||
(index & ((1 << name##_POOL_BLOCK_SIZE_BITS) - 1)) * sizeof(type) \
|
|
||||||
); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static inline uint Get##name##PoolSize() \
|
|
||||||
{ \
|
|
||||||
return _##name##_pool.total_items; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define DECLARE_OLD_POOL(name, type, block_size_bits, max_blocks) \
|
#define DECLARE_OLD_POOL(name, type, block_size_bits, max_blocks) \
|
||||||
OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
|
OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \
|
||||||
extern OldMemoryPool _##name##_pool; \
|
extern OldMemoryPool<type> _##name##_pool; \
|
||||||
OLD_POOL_ACCESSORS(name, type)
|
OLD_POOL_ACCESSORS(name, type)
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \
|
#define DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \
|
||||||
OldMemoryPool _##name##_pool = { \
|
OldMemoryPool<type> _##name##_pool( \
|
||||||
#name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \
|
#name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \
|
||||||
new_block_proc, clean_block_proc, \
|
new_block_proc, clean_block_proc);
|
||||||
0, 0, NULL \
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define STATIC_OLD_POOL(name, type, block_size_bits, max_blocks, new_block_proc, clean_block_proc) \
|
#define STATIC_OLD_POOL(name, type, block_size_bits, max_blocks, new_block_proc, clean_block_proc) \
|
||||||
|
@ -171,13 +171,9 @@ static inline bool HasOrderPoolFree(uint amount)
|
|||||||
const Order *order;
|
const Order *order;
|
||||||
|
|
||||||
/* There is always room if not all blocks in the pool are reserved */
|
/* There is always room if not all blocks in the pool are reserved */
|
||||||
if (_Order_pool.current_blocks < _Order_pool.max_blocks)
|
if (_Order_pool.CanAllocateMoreBlocks()) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
FOR_ALL_ORDERS(order)
|
FOR_ALL_ORDERS(order) if (!order->IsValid() && --amount == 0) return true;
|
||||||
if (!order->IsValid())
|
|
||||||
if (--amount == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1552,7 +1552,7 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded)
|
|||||||
uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS;
|
uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS;
|
||||||
|
|
||||||
assert(_ts.count == _sl.offs_base);
|
assert(_ts.count == _sl.offs_base);
|
||||||
for (i = 0; i != _Savegame_pool.current_blocks - 1; i++) {
|
for (i = 0; i != _Savegame_pool.GetBlockCount() - 1; i++) {
|
||||||
_sl.buf = _Savegame_pool.blocks[i];
|
_sl.buf = _Savegame_pool.blocks[i];
|
||||||
fmt->writer(count);
|
fmt->writer(count);
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ static Vehicle *AllocateSingleVehicle(VehicleID *skip_vehicles)
|
|||||||
|
|
||||||
/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
|
/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
|
||||||
* @todo - This is just a temporary stage, this will be removed. */
|
* @todo - This is just a temporary stage, this will be removed. */
|
||||||
if (*skip_vehicles < (_Vehicle_pool.total_items - offset)) { // make sure the offset in the array is not larger than the array itself
|
if (*skip_vehicles < (_Vehicle_pool.GetSize() - offset)) { // make sure the offset in the array is not larger than the array itself
|
||||||
for (v = GetVehicle(offset + *skip_vehicles); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
|
for (v = GetVehicle(offset + *skip_vehicles); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
|
||||||
(*skip_vehicles)++;
|
(*skip_vehicles)++;
|
||||||
if (!IsValidVehicle(v)) return InitializeVehicle(v);
|
if (!IsValidVehicle(v)) return InitializeVehicle(v);
|
||||||
|
Loading…
Reference in New Issue
Block a user