2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include "resourcemanager.h"
31 typedef struct ResMngr_Block_s
35 struct ResMngr_Block_s *next;
38 static void ResMngr_CreateBlock( ResourceManager_t *resource ){
39 unsigned int _blockSize;
42 ResMngr_Block_t *temp;
45 _blockSize = resource->nodeSize * resource->resPerBlock;
47 block = malloc( _blockSize );
51 temp = malloc( sizeof( *temp ) );
54 temp->size = _blockSize;
55 temp->next = resource->blockList;
57 resource->blockList = temp;
59 resource->free = (char **)( block );
61 current = resource->free;
63 for ( i = 1; i < resource->resPerBlock; ++i )
65 // set current->next to point to next node
66 *current = (char *)( current ) + resource->nodeSize;
68 // set current node to current->next
69 current = (char **)( *current );
75 H2COMMON_API void ResMngr_Con( ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name ){
76 resource->resSize = init_resSize;
78 resource->resPerBlock = init_resPerBlock;
80 resource->nodeSize = resource->resSize + sizeof( *resource->free );
82 resource->blockList = NULL;
84 resource->numResourcesAllocated = 0;
86 ResMngr_CreateBlock( resource );
89 H2COMMON_API void ResMngr_Des( ResourceManager_t *resource ){
90 ResMngr_Block_t *toDelete;
93 if ( resource->numResourcesAllocated ) {
95 sprintf( mess,"Potential memory leak %d bytes unfreed\n",resource->resSize * resource->numResourcesAllocated );
96 OutputDebugString( mess );
100 while ( resource->blockList )
102 toDelete = resource->blockList;
103 resource->blockList = resource->blockList->next;
104 free( toDelete->start );
109 H2COMMON_API void *ResMngr_AllocateResource( ResourceManager_t *resource, size_t size ){
112 assert( size == resource->resSize );
114 ++resource->numResourcesAllocated;
116 assert( resource->free ); // constructor not called; possibly due to a static object
117 // containing a static ResourceManagerFastLarge member being
118 // constructed before its own static members
120 toPop = resource->free;
122 // set unallocated to the next node and check for NULL (end of list)
123 if ( !( resource->free = (char **)( *resource->free ) ) ) { // if at end create new block
124 ResMngr_CreateBlock( resource );
130 // return the resource for the node
131 return (void *)( toPop + 1 );
134 H2COMMON_API void ResMngr_DeallocateResource( ResourceManager_t *resource, void *toDeallocate, size_t size ){
137 assert( size == resource->resSize );
139 --resource->numResourcesAllocated;
141 toPush = (char **)( toDeallocate ) - 1;
143 assert( resource->free ); // see same assert at top of AllocateResource
145 // set toPop->next to current unallocated front
146 *toPush = (char *)( resource->free );
148 // set unallocated to the node removed from allocated
149 resource->free = toPush;