FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
imagemanager.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2011 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library 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 GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <map>
24 
25 // 3rd party library includes
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 #include "ext/tinyxml/fife_tinyxml.h"
32 #include "util/log/logger.h"
33 #include "util/resource/resourcemanager.h"
34 #include "util/resource/resource.h"
35 #include "video/image.h"
36 #include "video/renderbackend.h"
37 
38 #include "imagemanager.h"
39 
40 namespace FIFE {
41  static Logger _log(LM_RESMGR);
42 
44 
45  }
46 
47  size_t ImageManager::getMemoryUsed() const {
48  size_t totalSize = 0;
49 
50  ImageHandleMapConstIterator it = m_imgHandleMap.begin(),
51  itend = m_imgHandleMap.end();
52 
53  for ( ; it != itend; ++it) {
54  totalSize += it->second->getSize();
55  }
56 
57  return totalSize;
58  }
59 
61  ImageHandleMapConstIterator it = m_imgHandleMap.begin(),
62  itend = m_imgHandleMap.end();
63  size_t count = 0;
64 
65  for ( ; it != itend; ++it) {
66  if ( it->second->getState() == IResource::RES_NOT_LOADED ) {
67  count++;
68  }
69  }
70 
71  return count;
72  }
73 
75  ImageHandleMapConstIterator it = m_imgHandleMap.begin(),
76  itend = m_imgHandleMap.end();
77  size_t count = 0;
78 
79  for ( ; it != itend; ++it) {
80  if ( it->second->getState() == IResource::RES_LOADED ) {
81  count++;
82  }
83  }
84 
85  return count;
86  }
87 
89  return m_imgHandleMap.size();
90  }
91 
92  ImagePtr ImageManager::create(IResourceLoader* loader){
93  Image* ptr = RenderBackend::instance()->createImage(loader);
94  return add(ptr);
95  }
96 
97  ImagePtr ImageManager::create(const std::string& name, IResourceLoader* loader){
98  if (exists(name)) {
99  FL_WARN(_log, LMsg("ImageManager::create(std::string, IResourceLoader* loader) - ") << "Resource name " << name << " was previously created. Returning original Image...");
100  return get(name);
101  }
102 
103  Image* ptr = RenderBackend::instance()->createImage(name, loader);
104  return add(ptr);
105  }
106 
107  ImagePtr ImageManager::load(const std::string& name, IResourceLoader* loader) {
108  ImageNameMapIterator nit = m_imgNameMap.find(name);
109 
110  if (nit != m_imgNameMap.end()) {
111  if ( nit->second->getState() == IResource::RES_NOT_LOADED ) {
112  nit->second->load();
113  }
114 
115  return nit->second;
116  }
117 
118  //was not found so create and load resource
119  ImagePtr ptr = create(name, loader);
120  ptr->load();
121 
122  if (ptr->getState() == IResource::RES_NOT_LOADED){
123  FL_WARN(_log, LMsg("ImageManager::load(std::string) - ") << "Resource name " << name << " was not found and could not be loaded.");
124  remove(name);
125  }
126 
127  return ptr;
128  }
129 
130  ImagePtr ImageManager::loadBlank(uint32_t width, uint32_t height) {
131  uint8_t* pixdata = new uint8_t[width * height * 4];
132  memset(pixdata, 0, width * height * 4);
133  Image* ptr = RenderBackend::instance()->createImage(pixdata, width, height);
134  delete [] pixdata;
135  ptr->setState(IResource::RES_LOADED);
136  return add(ptr);
137  }
138 
139  ImagePtr ImageManager::loadBlank(const std::string& name, uint32_t width, uint32_t height) {
140  ImageNameMapIterator nit = m_imgNameMap.find(name);
141  if (nit != m_imgNameMap.end()) {
142  remove(nit->second);
143  }
144  uint8_t* pixdata = new uint8_t[width * height * 4];
145  memset(pixdata, 0, width * height * 4);
146  Image* ptr = RenderBackend::instance()->createImage(name, pixdata, width, height);
147  delete [] pixdata;
148  ptr->setState(IResource::RES_LOADED);
149  return add(ptr);
150  }
151 
153  assert(res);
154  assert(!(exists(res->getHandle()) || exists(res->getName())));
155 
156  ImagePtr resptr(res);
157 
158  std::pair<ImageHandleMapIterator, bool> returnValue;
159  returnValue = m_imgHandleMap.insert ( ImageHandleMapPair(res->getHandle(), resptr));
160 
161  if (returnValue.second) {
162  m_imgNameMap.insert ( ImageNameMapPair(returnValue.first->second->getName(), returnValue.first->second) );
163  }
164  else {
165  FL_WARN(_log, LMsg("ImageManager::add(IResource*) - ") << "Resource " << res->getName() << " already exists.... ignoring.");
166  }
167 
168  return returnValue.first->second;
169  }
170 
171  bool ImageManager::exists(const std::string& name) {
172  ImageNameMapIterator it = m_imgNameMap.find(name);
173  if (it != m_imgNameMap.end()) {
174  return true;
175  }
176 
177  return false;
178  }
179 
180  bool ImageManager::exists(ResourceHandle handle) {
181  ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
182  if (it != m_imgHandleMap.end()) {
183  return true;
184  }
185 
186  return false;
187  }
188 
189  void ImageManager::reload(const std::string& name) {
190  ImageNameMapIterator nit = m_imgNameMap.find(name);
191 
192  if (nit != m_imgNameMap.end()) {
193  if ( nit->second->getState() == IResource::RES_LOADED) {
194  nit->second->free();
195  }
196  nit->second->load();
197  return;
198  }
199 
200  FL_WARN(_log, LMsg("ImageManager::reload(std::string) - ") << "Resource name " << name << " not found.");
201  }
202 
203  void ImageManager::reload(ResourceHandle handle) {
204  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
205 
206  if ( it != m_imgHandleMap.end()) {
207  if ( it->second->getState() == IResource::RES_LOADED) {
208  it->second->free();
209  }
210  it->second->load();
211  return;
212  }
213 
214  FL_WARN(_log, LMsg("ImageManager::reload(ResourceHandle) - ") << "Resource handle " << handle << " not found.");
215 
216  }
217 
219  ImageHandleMapIterator it = m_imgHandleMap.begin(),
220  itend = m_imgHandleMap.end();
221 
222  for ( ; it != itend; ++it) {
223  if ( it->second->getState() == IResource::RES_LOADED) {
224  it->second->free();
225  }
226  it->second->load();
227  }
228  }
229 
231  ImageHandleMapIterator it = m_imgHandleMap.begin(),
232  itend = m_imgHandleMap.end();
233 
234  int32_t count = 0;
235  for ( ; it != itend; ++it) {
236  if (it->second.useCount() == 2 && it->second->getState() != IResource::RES_LOADED){
237  it->second->load();
238  count++;
239  }
240  }
241  FL_DBG(_log, LMsg("ImageManager::loadUnreferenced() - ") << "Loaded " << count << " unreferenced resources.");
242  }
243 
244  void ImageManager::free(const std::string& name) {
245  ImageNameMapIterator nit = m_imgNameMap.find(name);
246 
247  if (nit != m_imgNameMap.end()) {
248  if ( nit->second->getState() == IResource::RES_LOADED) {
249  nit->second->free();
250  }
251  return;
252  }
253 
254  FL_WARN(_log, LMsg("ImageManager::free(std::string) - ") << "Resource name " << name << " not found.");
255  }
256 
257  void ImageManager::free(ResourceHandle handle) {
258  ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
259  if (it != m_imgHandleMap.end()) {
260  if ( it->second->getState() == IResource::RES_LOADED) {
261  it->second->free();
262  }
263  return;
264  }
265 
266  FL_WARN(_log, LMsg("ImageManager::free(ResourceHandle) - ") << "Resource handle " << handle << " not found.");
267  }
268 
270  ImageHandleMapIterator it = m_imgHandleMap.begin(),
271  itend = m_imgHandleMap.end();
272 
273  int32_t count = 0;
274 
275  for ( ; it != itend; ++it) {
276  if ( it->second->getState() == IResource::RES_LOADED) {
277  it->second->free();
278  count++;
279  }
280  }
281 
282  FL_DBG(_log, LMsg("ImageManager::freeAll() - ") << "Freed all " << count << " resources.");
283  }
284 
286  ImageHandleMapIterator it = m_imgHandleMap.begin(),
287  itend = m_imgHandleMap.end();
288 
289  int32_t count = 0;
290  for ( ; it != itend; ++it) {
291  if (it->second.useCount() == 2 && it->second->getState() == IResource::RES_LOADED ){
292  it->second->free();
293  count++;
294  }
295  }
296 
297  FL_DBG(_log, LMsg("ImageManager::freeUnreferenced() - ") << "Freed " << count << " unreferenced resources.");
298  }
299 
300  void ImageManager::remove(ImagePtr& resource) {
301  ImageHandleMapIterator it = m_imgHandleMap.find(resource->getHandle());
302  ImageNameMapIterator nit = m_imgNameMap.find(resource->getName());
303 
304  if (it != m_imgHandleMap.end()) {
305  m_imgHandleMap.erase(it);
306 
307  if (nit != m_imgNameMap.end()) {
308  m_imgNameMap.erase(nit);
309  return;
310  }
311  assert(false); //should never get here
312  }
313 
314  FL_WARN(_log, LMsg("ImageManager::remove(ResourcePtr&) - ") << "Resource " << resource->getName() << " was not found.");
315  }
316 
317  void ImageManager::remove(const std::string& name) {
318  std::size_t handle;
319 
320  ImageNameMapIterator nit = m_imgNameMap.find(name);
321  if (nit != m_imgNameMap.end()) {
322  handle = nit->second->getHandle();
323  m_imgNameMap.erase(nit);
324  }
325  else {
326  FL_WARN(_log, LMsg("ImageManager::remove(std::string) - ") << "Resource " << name << " was not found.");
327  return;
328  }
329 
330  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
331  if ( it != m_imgHandleMap.end()) {
332  m_imgHandleMap.erase(it);
333  return;
334  }
335 
336  assert(false); //should never get here
337  }
338 
339  void ImageManager::remove(ResourceHandle handle) {
340  std::string name;
341 
342  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
343 
344  if (it != m_imgHandleMap.end()) {
345  name = it->second->getName();
346  m_imgHandleMap.erase(it);
347  }
348  else {
349  FL_WARN(_log, LMsg("ImageManager::remove(ResourceHandle) - ") << "Resource handle " << handle << " was not found.");
350  return;
351  }
352 
353  ImageNameMapIterator nit = m_imgNameMap.find(name);
354  if ( nit != m_imgNameMap.end() ) {
355  m_imgNameMap.erase(nit);
356  return;
357  }
358 
359  assert(false); //should never get here
360  }
361 
363  //should always be equal
364  assert (m_imgHandleMap.size() == m_imgNameMap.size());
365 
366  size_t count = m_imgHandleMap.size();
367 
368  m_imgHandleMap.clear();
369  m_imgNameMap.clear();
370 
371  FL_DBG(_log, LMsg("ImageManager::removeAll() - ") << "Removed all " << count << " resources.");
372  }
373 
375  ImageHandleMapIterator it = m_imgHandleMap.begin(),
376  itend = m_imgHandleMap.end();
377 
378  std::vector<int> imgHandles;
379 
380  int32_t count = 0;
381  for ( ; it != itend; ++it) {
382  if ( it->second.useCount() == 2) {
383  imgHandles.push_back(it->second->getHandle());
384  count++;
385  }
386  }
387 
388  for (std::vector<int>::iterator it = imgHandles.begin(); it != imgHandles.end(); ++it) {
389  remove(*it);
390  }
391 
392  FL_DBG(_log, LMsg("ImageManager::removeUnreferenced() - ") << "Removed " << count << " unreferenced resources.");
393  }
394 
395  ImagePtr ImageManager::get(const std::string& name) {
396  ImageNameMapIterator nit = m_imgNameMap.find(name);
397 
398  if (nit != m_imgNameMap.end()) {
399  if (nit->second->getState() != IResource::RES_LOADED){
400  //resource is not loaded so load it
401  nit->second->load();
402  }
403  return nit->second;
404  }
405 
406  //not found so attempt to create and load the resource
407  ImagePtr ptr = load(name);
408  return ptr;
409  }
410 
411  ImagePtr ImageManager::get(ResourceHandle handle) {
412  ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
413  if (it != m_imgHandleMap.end()) {
414  if (it->second->getState() != IResource::RES_LOADED){
415  //resource is not loaded so load it
416  it->second->load();
417  }
418  return it->second;
419  }
420 
421  FL_WARN(_log, LMsg("ImageManager::get(ResourceHandle) - ") << "Resource handle " << handle << " is undefined.");
422 
423  return ImagePtr();
424  }
425 
426  ImagePtr ImageManager::getPtr(const std::string& name) {
427  ImageNameMapIterator nit = m_imgNameMap.find(name);
428 
429  if (nit != m_imgNameMap.end()) {
430  return nit->second;
431  }
432 
433  FL_WARN(_log, LMsg("ImageManager::getPtr(std::string) - ") << "Resource " << name << " is undefined.");
434 
435  return ImagePtr();
436  }
437 
438  ImagePtr ImageManager::getPtr(ResourceHandle handle) {
439  ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
440  if (it != m_imgHandleMap.end()) {
441  return it->second;
442  }
443 
444  FL_WARN(_log, LMsg("ImageManager::getPtr(ResourceHandle) - ") << "Resource handle " << handle << " is undefined.");
445 
446  return ImagePtr();
447  }
448 
449  ResourceHandle ImageManager::getResourceHandle(const std::string& name) {
450  ImageNameMapIterator nit = m_imgNameMap.find(name);
451  if (nit != m_imgNameMap.end()) {
452  return nit->second->getHandle();
453  }
454 
455  FL_WARN(_log, LMsg("ImageManager::getResourceHandle(std::string) - ") << "Resource " << name << " is undefined.");
456 
457  return 0;
458  }
459 
460  void ImageManager::invalidate(const std::string& name) {
461  ImageNameMapIterator it = m_imgNameMap.find(name);
462  if (it != m_imgNameMap.end()) {
463  if (it->second->getState() == IResource::RES_LOADED){
464  it->second.get()->invalidate();
465  }
466  }
467  }
468 
469  void ImageManager::invalidate(ResourceHandle handle) {
470  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
471  if (it != m_imgHandleMap.end()) {
472  if (it->second->getState() == IResource::RES_LOADED) {
473  it->second.get()->invalidate();
474  }
475  }
476  }
477 
478  void ImageManager::invalidateAll() {
479  ImageHandleMapIterator it = m_imgHandleMap.begin(),
480  itend = m_imgHandleMap.end();
481 
482  for ( ; it != itend; ++it) {
483  if (it->second->getState() == IResource::RES_LOADED) {
484  it->second.get()->invalidate();
485  }
486  }
487 
488  }
489 
490 } //FIFE