comparison engine/core/util/resource/pool.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children 90005975cdbb
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /***************************************************************************
2 * Copyright (C) 2005-2008 by the FIFE team *
3 * http://www.fifengine.de *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23
24 // 3rd party library includes
25
26 // FIFE includes
27 // These includes are split up in two parts, separated by one empty line
28 // First block: files included from the FIFE root src directory
29 // Second block: files included from the same folder
30 #include "util/base/exception.h"
31 #include "util/log/logger.h"
32
33 #include "pool.h"
34
35 namespace FIFE {
36 static Logger _log(LM_POOL);
37
38 Pool::Pool():
39 m_entries(),
40 m_listeners(),
41 m_loaders(),
42 m_curind(0)
43 {
44 }
45
46 Pool::~Pool() {
47 clear();
48 std::vector<ResourceLoader*>::iterator loader;
49 for (loader = m_loaders.begin(); loader != m_loaders.end(); loader++) {
50 delete (*loader);
51 }
52 }
53
54 void Pool::clear() {
55 std::vector<IPoolListener*>::iterator listener;
56 for (listener = m_listeners.begin(); listener != m_listeners.end(); listener++) {
57 (*listener)->poolCleared();
58 }
59 std::vector<PoolEntry*>::iterator entry;
60 for (entry = m_entries.begin(); entry != m_entries.end(); entry++) {
61 delete (*entry);
62 }
63 m_entries.clear();
64 }
65
66 void Pool::addResourceLoader(ResourceLoader* loader) {
67 m_loaders.push_back(loader);
68 }
69
70 int Pool::addResourceFromLocation(const ResourceLocation& loc) {
71 std::vector<PoolEntry*>::iterator it = m_entries.begin();
72 int index = 0;
73 for (; it != m_entries.end(); it++) {
74 ResourceLocation* loc2 = (*it)->location;
75 if (*loc2 == loc) {
76 return index;
77 }
78 index++;
79 }
80
81 PoolEntry* entry = new PoolEntry();
82 entry->location = loc.clone();
83 m_entries.push_back(entry);
84 index = m_entries.size();
85 return index - 1;
86 }
87
88 int Pool::addResourceFromFile(const std::string& filename) {
89 return addResourceFromLocation(ResourceLocation(filename));
90 }
91
92 IResource& Pool::get(unsigned int index, bool inc) {
93 if (index >= m_entries.size()) {
94 FL_ERR(_log, LMsg("Tried to get with index ") << index << ", only " << m_entries.size() << " items in pool");
95 throw IndexOverflow( __FUNCTION__ );
96 }
97 IResource* res = NULL;
98 PoolEntry* entry = m_entries[index];
99 if (entry->resource) {
100 res = entry->resource;
101 } else {
102 if (!entry->loader) {
103 findAndSetProvider(*entry);
104 } else {
105 entry->resource = entry->loader->loadResource(*entry->location);
106 }
107 if (!entry->loader) {
108 LMsg msg("No suitable loader was found for resource ");
109 msg << entry->location->getFilename();
110 FL_ERR(_log, msg);
111 throw NotFound(msg.str);
112 }
113 if (!entry->resource) {
114 LMsg msg("No loader was able to load the requested resource ");
115 msg << entry->location->getFilename();
116 FL_ERR(_log, msg);
117 throw NotFound(msg.str);
118 }
119 res = entry->resource;
120 }
121 if (inc) {
122 res->addRef();
123 }
124 res->setPoolId(index);
125 return *res;
126 }
127
128 unsigned int Pool::getIndex(const std::string& filename) {
129 std::vector<PoolEntry*>::iterator it = m_entries.begin();
130 int index = 0;
131
132 // look for the appropriate entry
133 for (; it != m_entries.end(); it++) {
134
135 if ((*it)->location->getFilename() == filename) {
136 return index;
137 }
138 index++;
139 }
140
141 // create resource
142 return addResourceFromFile(filename);
143 }
144
145 void Pool::release(unsigned int index, bool dec) {
146 if (index >= m_entries.size()) {
147 throw IndexOverflow( __FUNCTION__ );
148 }
149
150 IResource* res = NULL;
151 PoolEntry* entry = m_entries[index];
152 if (entry->resource) {
153 res = entry->resource;
154 if (dec) {
155 res->decRef();
156 }
157 if(res->getRefCount() == 0) {
158 delete entry->resource;
159 entry->resource = 0;
160 }
161 }
162 }
163
164 int Pool::getResourceCount(int status) {
165 int amount = 0;
166 std::vector<PoolEntry*>::iterator entry;
167 for (entry = m_entries.begin(); entry != m_entries.end(); entry++) {
168 if (status & RES_LOADED) {
169 if ((*entry)->resource) {
170 amount++;
171 }
172 }
173 if (status & RES_NON_LOADED) {
174 if (!(*entry)->resource) {
175 amount++;
176 }
177 }
178 }
179 return amount;
180 }
181
182 void Pool::addPoolListener(IPoolListener* listener) {
183 m_listeners.push_back(listener);
184 }
185
186 void Pool::removePoolListener(IPoolListener* listener) {
187 std::vector<IPoolListener*>::iterator i = m_listeners.begin();
188 while (i != m_listeners.end()) {
189 if ((*i) == listener) {
190 m_listeners.erase(i);
191 return;
192 }
193 ++i;
194 }
195 }
196
197 void Pool::findAndSetProvider(PoolEntry& entry) {
198 std::vector<ResourceLoader*>::iterator it = m_loaders.begin();
199 std::vector<ResourceLoader*>::iterator end = m_loaders.end();
200 if( it == end ) {
201 FL_PANIC(_log, "no loader constructors given for resource pool");
202 }
203 for(; it != end; ++it) {
204 IResource* res = (*it)->loadResource(*entry.location);
205 if (res) {
206 entry.resource = res;
207 entry.loader = *it;
208 return;
209 }
210 };
211 }
212
213 void Pool::printStatistics() {
214 FL_LOG(_log, LMsg("Pool size =") << m_entries.size());
215 }
216 }