(svn r1763) -Add: pool.c / pool.h: generalized routines for dynamic arrays (MemoryPools)
This commit is contained in:
		
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @@ -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 | ||||
|   | ||||
							
								
								
									
										79
									
								
								pool.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								pool.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| } | ||||
							
								
								
									
										53
									
								
								pool.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								pool.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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 */ | ||||
							
								
								
									
										8
									
								
								ttd.dsp
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								ttd.dsp
									
									
									
									
									
								
							| @@ -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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 truelight
					truelight