pool.c
author peter1138
Fri, 04 Nov 2005 07:38:26 +0000
changeset 2593 a9f7d3d70639
parent 2186 461a2aff3486
child 3585 18a23b37e99a
permissions -rw-r--r--
(svn r3130) Calculate shorter wagon lengths more precisely in train depot window. This affects wagon position, the scroll bar, and the train length counter. No trial and error is required to get the correct length now.
/* $Id$ */

#include "stdafx.h"
#include "openttd.h"
#include "debug.h"
#include "functions.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) Cleaning 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;
}