summaryrefslogtreecommitdiff
path: root/newgrf_spritegroup.c
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2006-04-20 20:51:57 +0000
committerpeter1138 <peter1138@openttd.org>2006-04-20 20:51:57 +0000
commit103a2aa1164fe92552cfe64c46d99b4b7dd5e82a (patch)
tree097bbbafd144f585288535083f426339d840e0f4 /newgrf_spritegroup.c
parentc8b1ff8654708fa0b156bb0936c5bb7053850854 (diff)
downloadopenttd-103a2aa1164fe92552cfe64c46d99b4b7dd5e82a.tar.xz
(svn r4486) - NewGRF: Create and use a memory pool to manage sprite groups. This
reduces the amount of house keeping we do and the chance of memory leaks.
Diffstat (limited to 'newgrf_spritegroup.c')
-rw-r--r--newgrf_spritegroup.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/newgrf_spritegroup.c b/newgrf_spritegroup.c
new file mode 100644
index 000000000..9fd43efca
--- /dev/null
+++ b/newgrf_spritegroup.c
@@ -0,0 +1,68 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "pool.h"
+#include "sprite.h"
+
+enum {
+ SPRITEGROUP_POOL_BLOCK_SIZE_BITS = 4, /* (1 << 4) == 16 items */
+ SPRITEGROUP_POOL_MAX_BLOCKS = 8000,
+};
+
+static uint _spritegroup_count = 0;
+static MemoryPool _spritegroup_pool;
+
+
+static void SpriteGroupPoolCleanBlock(uint start_item, uint end_item)
+{
+ uint i;
+
+ for (i = start_item; i <= end_item; i++) {
+ SpriteGroup *group = (SpriteGroup*)GetItemFromPool(&_spritegroup_pool, i);
+
+ /* Free dynamically allocated memory */
+ switch (group->type) {
+ case SGT_REAL:
+ free(group->g.real.loaded);
+ free(group->g.real.loading);
+ break;
+
+ case SGT_DETERMINISTIC:
+ free(group->g.determ.ranges);
+ break;
+
+ case SGT_RANDOMIZED:
+ free(group->g.random.groups);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/* Initialize the SpriteGroup pool */
+static MemoryPool _spritegroup_pool = { "SpriteGr", SPRITEGROUP_POOL_MAX_BLOCKS, SPRITEGROUP_POOL_BLOCK_SIZE_BITS, sizeof(SpriteGroup), NULL, &SpriteGroupPoolCleanBlock, 0, 0, NULL };
+
+
+/* Allocate a new SpriteGroup */
+SpriteGroup *AllocateSpriteGroup(void)
+{
+ /* This is totally different to the other pool allocators, as we never remove an item from the pool. */
+ if (_spritegroup_count == _spritegroup_pool.total_items) {
+ if (!AddBlockToPool(&_spritegroup_pool)) return NULL;
+ }
+
+ return (SpriteGroup*)GetItemFromPool(&_spritegroup_pool, _spritegroup_count++);
+}
+
+
+void InitializeSpriteGroupPool(void)
+{
+ CleanPool(&_spritegroup_pool);
+ AddBlockToPool(&_spritegroup_pool);
+
+ _spritegroup_count = 0;
+}