]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/qcommon/resourcemanager.c
initial
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / qcommon / resourcemanager.c
1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
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.
11
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.
16
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
20 */
21
22
23 //
24 // ResourceManager.c
25 //
26
27 #include <stdio.h>
28 #include "resourcemanager.h"
29 #include <assert.h>
30
31 typedef struct ResMngr_Block_s
32 {
33         char *start;
34         unsigned int size;
35         struct ResMngr_Block_s *next;
36 } ResMngr_Block_t;
37
38 static void ResMngr_CreateBlock(ResourceManager_t *resource)
39 {
40         unsigned int _blockSize;
41         char *block;
42         char **current;
43         ResMngr_Block_t *temp;
44         unsigned int i;
45
46         _blockSize = resource->nodeSize * resource->resPerBlock;
47
48         block = malloc(_blockSize);
49
50         assert(block);
51
52         temp = malloc(sizeof(*temp));
53
54         temp->start = block;
55         temp->size = _blockSize;
56         temp->next = resource->blockList;
57
58         resource->blockList = temp; 
59
60         resource->free = (char **)(block);
61
62         current = resource->free;
63
64         for(i = 1; i < resource->resPerBlock; ++i)
65         {
66                 // set current->next to point to next node
67                 *current = (char *)(current) + resource->nodeSize;
68
69                 // set current node to current->next
70                 current = (char **)(*current);
71         }
72
73         *current = NULL;
74 }
75
76 H2COMMON_API void ResMngr_Con(ResourceManager_t *resource, size_t init_resSize, unsigned int init_resPerBlock, char *resman_name)
77 {
78         resource->resSize = init_resSize;
79
80         resource->resPerBlock = init_resPerBlock;
81
82         resource->nodeSize = resource->resSize + sizeof(*resource->free);
83
84         resource->blockList = NULL;
85
86         resource->numResourcesAllocated = 0;
87
88         ResMngr_CreateBlock(resource);
89 }
90
91 H2COMMON_API void ResMngr_Des(ResourceManager_t *resource)
92 {
93         ResMngr_Block_t *toDelete;
94
95 #if 0
96         if (resource->numResourcesAllocated)
97         {
98                 char mess[100];
99                 sprintf(mess,"Potential memory leak %d bytes unfreed\n",resource->resSize*resource->numResourcesAllocated);
100                 OutputDebugString(mess);
101         }
102 #endif
103
104         while(resource->blockList)
105         {
106                 toDelete = resource->blockList;
107                 resource->blockList = resource->blockList->next;
108                 free(toDelete->start);
109                 free(toDelete);
110         }
111 }
112
113 H2COMMON_API void *ResMngr_AllocateResource(ResourceManager_t *resource, size_t size)
114 {
115         char **toPop;
116
117         assert(size == resource->resSize);
118
119         ++resource->numResourcesAllocated;
120
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
124
125         toPop = resource->free;
126
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);
131         }
132
133         // set next to NULL
134         *toPop = NULL;
135
136         // return the resource for the node
137         return (void *)(toPop + 1);
138 }
139
140 H2COMMON_API void ResMngr_DeallocateResource(ResourceManager_t *resource, void *toDeallocate, size_t size)
141 {
142         char **toPush;
143
144         assert(size == resource->resSize);
145
146         --resource->numResourcesAllocated;
147
148         toPush = (char **)(toDeallocate) - 1;
149
150         assert(resource->free); // see same assert at top of AllocateResource
151
152         // set toPop->next to current unallocated front
153         *toPush = (char *)(resource->free);
154
155         // set unallocated to the node removed from allocated
156         resource->free = toPush;
157 }
158
159 // end