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)
40 unsigned int _blockSize;
43 ResMngr_Block_t *temp;
46 _blockSize = resource->nodeSize * resource->resPerBlock;
48 block = malloc(_blockSize);
52 temp = malloc(sizeof(*temp));
55 temp->size = _blockSize;
56 temp->next = resource->blockList;
58 resource->blockList = temp;
60 resource->free = (char **)(block);
62 current = resource->free;
64 for(i = 1; i < resource->resPerBlock; ++i)
66 // set current->next to point to next node
67 *current = (char *)(current) + resource->nodeSize;
69 // set current node to current->next
70 current = (char **)(*current);
76 H2COMMON_API void ResMngr_Con(ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name)
78 resource->resSize = init_resSize;
80 resource->resPerBlock = init_resPerBlock;
82 resource->nodeSize = resource->resSize + sizeof(*resource->free);
84 resource->blockList = NULL;
86 resource->numResourcesAllocated = 0;
88 ResMngr_CreateBlock(resource);
91 H2COMMON_API void ResMngr_Des(ResourceManager_t *resource)
93 ResMngr_Block_t *toDelete;
96 if (resource->numResourcesAllocated)
99 sprintf(mess,"Potential memory leak %d bytes unfreed\n",resource->resSize*resource->numResourcesAllocated);
100 OutputDebugString(mess);
104 while(resource->blockList)
106 toDelete = resource->blockList;
107 resource->blockList = resource->blockList->next;
108 free(toDelete->start);
113 H2COMMON_API void *ResMngr_AllocateResource(ResourceManager_t *resource, size_t size)
117 assert(size == resource->resSize);
119 ++resource->numResourcesAllocated;
121 assert(resource->free); // constructor not called; possibly due to a static object
122 // containing a static ResourceManagerFastLarge member being
123 // constructed before its own static members
125 toPop = resource->free;
127 // set unallocated to the next node and check for NULL (end of list)
128 if(!(resource->free = (char **)(*resource->free)))
129 { // if at end create new block
130 ResMngr_CreateBlock(resource);
136 // return the resource for the node
137 return (void *)(toPop + 1);
140 H2COMMON_API void ResMngr_DeallocateResource(ResourceManager_t *resource, void *toDeallocate, size_t size)
144 assert(size == resource->resSize);
146 --resource->numResourcesAllocated;
148 toPush = (char **)(toDeallocate) - 1;
150 assert(resource->free); // see same assert at top of AllocateResource
152 // set toPop->next to current unallocated front
153 *toPush = (char *)(resource->free);
155 // set unallocated to the node removed from allocated
156 resource->free = toPush;