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