(svn r1763) -Add: pool.c / pool.h: generalized routines for dynamic arrays (MemoryPools)

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
truelight 20 years ago
parent c02c35e256
commit 6d5fdc2b68

@ -600,6 +600,7 @@ C_SOURCES += order_gui.c
C_SOURCES += pathfind.c
C_SOURCES += player_gui.c
C_SOURCES += players.c
C_SOURCES += pool.c
C_SOURCES += queue.c
C_SOURCES += rail_cmd.c
C_SOURCES += rail_gui.c

@ -0,0 +1,79 @@
#include "stdafx.h"
#include "ttd.h"
#include "pool.h"
/**
* Clean a pool in a safe way (does free all blocks)
*/
void CleanPool(MemoryPool *pool)
{
uint i;
DEBUG(misc, 4)("[Pool] (%s) Cleaing pool..", pool->name);
/* Free all blocks */
for (i = 0; i < pool->current_blocks; i++)
free(pool->blocks[i]);
/* Free the block itself */
free(pool->blocks);
/* Clear up some critical data */
pool->total_items = 0;
pool->current_blocks = 0;
pool->blocks = NULL;
}
/**
* This function tries to increase the size of array by adding
* 1 block too it
*
* @return Returns false if the pool could not be increased
*/
bool AddBlockToPool(MemoryPool *pool)
{
/* Is the pool at his max? */
if (pool->max_blocks == pool->current_blocks)
return false;
pool->total_items = (pool->current_blocks + 1) * (1 << pool->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);
/* Increase the poolsize */
pool->blocks = realloc(pool->blocks, sizeof(pool->blocks[0]) * (pool->current_blocks + 1));
if (pool->blocks == NULL)
error("Pool: (%s) could not allocate memory for blocks", pool->name);
/* Allocate memory to the new block item */
pool->blocks[pool->current_blocks] = malloc(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);
/* Clean the content of the new block */
memset(pool->blocks[pool->current_blocks], 0, pool->item_size * (1 << pool->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));
/* We have a new block */
pool->current_blocks++;
return true;
}
/**
* Adds blocks to the pool if needed (and possible) till index fits inside the pool
*
* @return Returns false if adding failed
*/
bool AddBlockIfNeeded(MemoryPool *pool, uint index)
{
while (index >= pool->total_items) {
if (!AddBlockToPool(pool))
return false;
}
return true;
}

@ -0,0 +1,53 @@
#ifndef POOL_H
#define POOL_H
typedef struct MemoryPool MemoryPool;
/* The function that is called after a new block is added
start_item is the first item of the new made block */
typedef void MemoryPoolNewBlock(uint start_item);
/**
* Stuff for dynamic vehicles. Use the wrappers to access the MemoryPool
* please try to avoid manual calls!
*/
struct MemoryPool {
const char name[10]; //! Name of the pool (just for debugging)
const uint max_blocks; //! The max amount of blocks this pool can have
const uint block_size_bits; //! The size of each block in bits
const uint item_size; //! How many bytes one block is
MemoryPoolNewBlock *new_block_proc;
//!< Pointer to a function that is called after a new block is added
uint current_blocks; //! How many blocks we have in our pool
uint total_items; //! How many items we now have in this pool
byte **blocks; //! An array of blocks (one block hold all the items)
};
/**
* Those are the wrappers:
* CleanPool cleans the pool up, but you can use AddBlockToPool directly again
* (no need to call CreatePool!)
* AddBlockToPool adds 1 more block to the pool. Returns false if there is no
* more room
*/
void CleanPool(MemoryPool *array);
bool AddBlockToPool(MemoryPool *array);
/**
* Adds blocks to the pool if needed (and possible) till index fits inside the pool
*
* @return Returns false if adding failed
*/
bool AddBlockIfNeeded(MemoryPool *array, uint index);
static inline byte *GetItemFromPool(MemoryPool *pool, uint index)
{
assert(index < pool->total_items);
return (pool->blocks[index >> pool->block_size_bits] + (index & ((1 << pool->block_size_bits) - 1)) * pool->item_size);
}
#endif /* POOL_H */

@ -276,6 +276,10 @@ SOURCE=.\oldloader.c
SOURCE=.\pathfind.c
# End Source File
# Begin Source File
SOURCE=.\pool.c
# End Source File
# Begin Source File
SOURCE=.\players.c
# End Source File
@ -513,6 +517,10 @@ SOURCE=.\npf.h
SOURCE=.\pathfind.h
# End Source File
# Begin Source File
SOURCE=.\pool.h
# End Source File
# Begin Source File
SOURCE=.\player.h
# End Source File

@ -690,6 +690,9 @@
BasicRuntimeChecks="3"/>
</FileConfiguration>
</File>
<File
RelativePath=".\pool.c">
</File>
<File
RelativePath=".\queue.c">
</File>
@ -1223,6 +1226,9 @@
<File
RelativePath="player.h">
</File>
<File
RelativePath=".\pool.h">
</File>
<File
RelativePath=".\queue.h">
</File>

Loading…
Cancel
Save