From 4e96ce3dfea13ffab951a93061e35423e0b321e5 Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 1 Aug 2007 22:10:54 +0000 Subject: [PATCH] (svn r10744) -Codechange: make the pool a little more OO, so it can be easier in other places. --- src/oldpool.cpp | 53 ++++++++++++++++------------------ src/oldpool.h | 74 ++++++++++++++++++++++++++++++++---------------- src/order.h | 8 ++---- src/saveload.cpp | 2 +- src/vehicle.cpp | 2 +- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/src/oldpool.cpp b/src/oldpool.cpp index 47ee59b41e..6a04eeee30 100644 --- a/src/oldpool.cpp +++ b/src/oldpool.cpp @@ -12,27 +12,27 @@ /** * Clean a pool in a safe way (does free all blocks) */ -void CleanPool(OldMemoryPool *pool) +void OldMemoryPoolBase::CleanPool() { uint i; - DEBUG(misc, 4, "[Pool] (%s) cleaning pool..", pool->name); + DEBUG(misc, 4, "[Pool] (%s) cleaning pool..", this->name); /* Free all blocks */ - for (i = 0; i < pool->current_blocks; i++) { - if (pool->clean_block_proc != NULL) { - pool->clean_block_proc(i * (1 << pool->block_size_bits), (i + 1) * (1 << pool->block_size_bits) - 1); + for (i = 0; i < this->current_blocks; i++) { + if (this->clean_block_proc != NULL) { + 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(pool->blocks); + free(this->blocks); /* Clear up some critical data */ - pool->total_items = 0; - pool->current_blocks = 0; - pool->blocks = NULL; + this->total_items = 0; + this->current_blocks = 0; + this->blocks = NULL; } /** @@ -41,34 +41,32 @@ void CleanPool(OldMemoryPool *pool) * * @return Returns false if the pool could not be increased */ -bool AddBlockToPool(OldMemoryPool *pool) +bool OldMemoryPoolBase::AddBlockToPool() { /* Is the pool at his max? */ - if (pool->max_blocks == pool->current_blocks) - return false; + if (this->max_blocks == this->current_blocks) 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 */ - pool->blocks = ReallocT(pool->blocks, pool->current_blocks + 1); - if (pool->blocks == NULL) error("Pool: (%s) could not allocate memory for blocks", pool->name); + this->blocks = ReallocT(this->blocks, this->current_blocks + 1); + if (this->blocks == NULL) error("Pool: (%s) could not allocate memory for blocks", this->name); /* Allocate memory to the new block item */ - pool->blocks[pool->current_blocks] = MallocT(pool->item_size * (1 << pool->block_size_bits)); - if (pool->blocks[pool->current_blocks] == NULL) - error("Pool: (%s) could not allocate memory for blocks", pool->name); + this->blocks[this->current_blocks] = MallocT(this->item_size * (1 << this->block_size_bits)); + if (this->blocks[this->current_blocks] == NULL) + error("Pool: (%s) could not allocate memory for blocks", this->name); /* 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) */ - if (pool->new_block_proc != NULL) - pool->new_block_proc(pool->current_blocks * (1 << pool->block_size_bits)); + if (this->new_block_proc != NULL) this->new_block_proc(this->current_blocks * (1 << this->block_size_bits)); /* We have a new block */ - pool->current_blocks++; + this->current_blocks++; return true; } @@ -78,11 +76,10 @@ bool AddBlockToPool(OldMemoryPool *pool) * * @return Returns false if adding failed */ -bool AddBlockIfNeeded(OldMemoryPool *pool, uint index) +bool OldMemoryPoolBase::AddBlockIfNeeded(uint index) { - while (index >= pool->total_items) { - if (!AddBlockToPool(pool)) - return false; + while (index >= this->total_items) { + if (!this->AddBlockToPool()) return false; } return true; diff --git a/src/oldpool.h b/src/oldpool.h index 57ffa40f19..3813e8f1c2 100644 --- a/src/oldpool.h +++ b/src/oldpool.h @@ -5,8 +5,6 @@ #ifndef OLDPOOL_H #define OLDPOOL_H -struct OldMemoryPool; - /* The function that is called after a new block is added start_item is the first item of the new made block */ 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 * 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) 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 total_items; ///< How many items we now have in this pool +public: 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 +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 * more room */ -void CleanPool(OldMemoryPool *array); -bool AddBlockToPool(OldMemoryPool *array); +static inline void CleanPool(OldMemoryPoolBase *array) { array->CleanPool(); } +static inline bool AddBlockToPool(OldMemoryPoolBase *array) { return array->AddBlockToPool(); } /** * Adds blocks to the pool if needed (and possible) till index fits inside the pool * * @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) \ @@ -61,33 +100,20 @@ bool AddBlockIfNeeded(OldMemoryPool *array, uint index); #define OLD_POOL_ACCESSORS(name, type) \ - static inline type* Get##name(uint index) \ - { \ - 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; \ - } + static inline type* Get##name(uint index) { return _##name##_pool.Get(index); } \ + static inline uint Get##name##PoolSize() { return _##name##_pool.GetSize(); } #define DECLARE_OLD_POOL(name, type, block_size_bits, max_blocks) \ OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ - extern OldMemoryPool _##name##_pool; \ + extern OldMemoryPool _##name##_pool; \ OLD_POOL_ACCESSORS(name, type) #define DEFINE_OLD_POOL(name, type, new_block_proc, clean_block_proc) \ - OldMemoryPool _##name##_pool = { \ + OldMemoryPool _##name##_pool( \ #name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \ - new_block_proc, clean_block_proc, \ - 0, 0, NULL \ - }; + new_block_proc, clean_block_proc); #define STATIC_OLD_POOL(name, type, block_size_bits, max_blocks, new_block_proc, clean_block_proc) \ diff --git a/src/order.h b/src/order.h index 9703989e82..30d59517c9 100644 --- a/src/order.h +++ b/src/order.h @@ -171,13 +171,9 @@ static inline bool HasOrderPoolFree(uint amount) const Order *order; /* There is always room if not all blocks in the pool are reserved */ - if (_Order_pool.current_blocks < _Order_pool.max_blocks) - return true; + if (_Order_pool.CanAllocateMoreBlocks()) return true; - FOR_ALL_ORDERS(order) - if (!order->IsValid()) - if (--amount == 0) - return true; + FOR_ALL_ORDERS(order) if (!order->IsValid() && --amount == 0) return true; return false; } diff --git a/src/saveload.cpp b/src/saveload.cpp index ffce4e69d1..cb159e5c22 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -1552,7 +1552,7 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded) uint count = 1 << Savegame_POOL_BLOCK_SIZE_BITS; 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]; fmt->writer(count); } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 7c3c5a4db0..fbc061c62f 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -355,7 +355,7 @@ static Vehicle *AllocateSingleVehicle(VehicleID *skip_vehicles) /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. * @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) { (*skip_vehicles)++; if (!IsValidVehicle(v)) return InitializeVehicle(v);