2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
\r
5 This file is part of GtkRadiant.
\r
7 GtkRadiant is free software; you can redistribute it and/or modify
\r
8 it under the terms of the GNU General Public License as published by
\r
9 the Free Software Foundation; either version 2 of the License, or
\r
10 (at your option) any later version.
\r
12 GtkRadiant is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with GtkRadiant; if not, write to the Free Software
\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\r
24 // ResourceManager.c
\r
28 #include "resourcemanager.h"
\r
31 typedef struct ResMngr_Block_s
\r
35 struct ResMngr_Block_s *next;
\r
38 static void ResMngr_CreateBlock(ResourceManager_t *resource)
\r
40 unsigned int _blockSize;
\r
43 ResMngr_Block_t *temp;
\r
46 _blockSize = resource->nodeSize * resource->resPerBlock;
\r
48 block = malloc(_blockSize);
\r
52 temp = malloc(sizeof(*temp));
\r
54 temp->start = block;
\r
55 temp->size = _blockSize;
\r
56 temp->next = resource->blockList;
\r
58 resource->blockList = temp;
\r
60 resource->free = (char **)(block);
\r
62 current = resource->free;
\r
64 for(i = 1; i < resource->resPerBlock; ++i)
\r
66 // set current->next to point to next node
\r
67 *current = (char *)(current) + resource->nodeSize;
\r
69 // set current node to current->next
\r
70 current = (char **)(*current);
\r
76 H2COMMON_API void ResMngr_Con(ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name)
\r
78 resource->resSize = init_resSize;
\r
80 resource->resPerBlock = init_resPerBlock;
\r
82 resource->nodeSize = resource->resSize + sizeof(*resource->free);
\r
84 resource->blockList = NULL;
\r
86 resource->numResourcesAllocated = 0;
\r
88 ResMngr_CreateBlock(resource);
\r
91 H2COMMON_API void ResMngr_Des(ResourceManager_t *resource)
\r
93 ResMngr_Block_t *toDelete;
\r
96 if (resource->numResourcesAllocated)
\r
99 sprintf(mess,"Potential memory leak %d bytes unfreed\n",resource->resSize*resource->numResourcesAllocated);
\r
100 OutputDebugString(mess);
\r
104 while(resource->blockList)
\r
106 toDelete = resource->blockList;
\r
107 resource->blockList = resource->blockList->next;
\r
108 free(toDelete->start);
\r
113 H2COMMON_API void *ResMngr_AllocateResource(ResourceManager_t *resource, size_t size)
\r
117 assert(size == resource->resSize);
\r
119 ++resource->numResourcesAllocated;
\r
121 assert(resource->free); // constructor not called; possibly due to a static object
\r
122 // containing a static ResourceManagerFastLarge member being
\r
123 // constructed before its own static members
\r
125 toPop = resource->free;
\r
127 // set unallocated to the next node and check for NULL (end of list)
\r
128 if(!(resource->free = (char **)(*resource->free)))
\r
129 { // if at end create new block
\r
130 ResMngr_CreateBlock(resource);
\r
133 // set next to NULL
\r
136 // return the resource for the node
\r
137 return (void *)(toPop + 1);
\r
140 H2COMMON_API void ResMngr_DeallocateResource(ResourceManager_t *resource, void *toDeallocate, size_t size)
\r
144 assert(size == resource->resSize);
\r
146 --resource->numResourcesAllocated;
\r
148 toPush = (char **)(toDeallocate) - 1;
\r
150 assert(resource->free); // see same assert at top of AllocateResource
\r
152 // set toPop->next to current unallocated front
\r
153 *toPush = (char *)(resource->free);
\r
155 // set unallocated to the node removed from allocated
\r
156 resource->free = toPush;
\r