FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
imagemanager.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2019 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 #include <tinyxml.h>
27 
28 // FIFE includes
29 // These includes are split up in two parts, separated by one empty line
30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder
32 #include "util/log/logger.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 {
44  static Logger _log(LM_RESMGR);
45 
47 
48  }
49 
50  size_t ImageManager::getMemoryUsed() const {
51  size_t totalSize = 0;
52 
54  itend = m_imgHandleMap.end();
55 
56  for ( ; it != itend; ++it) {
57  totalSize += it->second->getSize();
58  }
59 
60  return totalSize;
61  }
62 
65  itend = m_imgHandleMap.end();
66  size_t count = 0;
67 
68  for ( ; it != itend; ++it) {
69  if ( it->second->getState() == IResource::RES_NOT_LOADED ) {
70  count++;
71  }
72  }
73 
74  return count;
75  }
76 
79  itend = m_imgHandleMap.end();
80  size_t count = 0;
81 
82  for ( ; it != itend; ++it) {
83  if ( it->second->getState() == IResource::RES_LOADED ) {
84  count++;
85  }
86  }
87 
88  return count;
89  }
90 
92  return m_imgHandleMap.size();
93  }
94 
96  Image* ptr = RenderBackend::instance()->createImage(loader);
97  return add(ptr);
98  }
99 
100  ImagePtr ImageManager::create(const std::string& name, IResourceLoader* loader){
101  if (exists(name)) {
102  FL_WARN(_log, LMsg("ImageManager::create(std::string, IResourceLoader* loader) - ") << "Resource name " << name << " was previously created. Returning original Image...");
103  return getPtr(name);
104  }
105 
106  Image* ptr = RenderBackend::instance()->createImage(name, loader);
107  return add(ptr);
108  }
109 
110  ImagePtr ImageManager::load(const std::string& name, IResourceLoader* loader) {
111  ImageNameMapIterator nit = m_imgNameMap.find(name);
112 
113  if (nit != m_imgNameMap.end()) {
114  if ( nit->second->getState() == IResource::RES_NOT_LOADED ) {
115  nit->second->load();
116  }
117 
118  return nit->second;
119  }
120 
121  //was not found so create and load resource
122  ImagePtr ptr = create(name, loader);
123  ptr->load();
124 
125  if (ptr->getState() == IResource::RES_NOT_LOADED){
126  FL_WARN(_log, LMsg("ImageManager::load(std::string) - ") << "Resource name " << name << " was not found and could not be loaded.");
127  remove(name);
128  }
129 
130  return ptr;
131  }
132 
134  uint8_t* pixdata = new uint8_t[width * height * 4];
135  memset(pixdata, 0, width * height * 4);
136  Image* ptr = RenderBackend::instance()->createImage(pixdata, width, height);
137  delete [] pixdata;
139  return add(ptr);
140  }
141 
142  ImagePtr ImageManager::loadBlank(const std::string& name, uint32_t width, uint32_t height) {
143  ImageNameMapIterator nit = m_imgNameMap.find(name);
144  if (nit != m_imgNameMap.end()) {
145  remove(nit->second);
146  }
147  uint8_t* pixdata = new uint8_t[width * height * 4];
148  memset(pixdata, 0, width * height * 4);
149  Image* ptr = RenderBackend::instance()->createImage(name, pixdata, width, height);
150  delete [] pixdata;
152  return add(ptr);
153  }
154 
156  assert(res);
157  assert(!(exists(res->getHandle()) || exists(res->getName())));
158 
159  ImagePtr resptr(res);
160 
161  std::pair<ImageHandleMapIterator, bool> returnValue;
162  returnValue = m_imgHandleMap.insert ( ImageHandleMapPair(res->getHandle(), resptr));
163 
164  if (returnValue.second) {
165  m_imgNameMap.insert ( ImageNameMapPair(returnValue.first->second->getName(), returnValue.first->second) );
166  }
167  else {
168  FL_WARN(_log, LMsg("ImageManager::add(IResource*) - ") << "Resource " << res->getName() << " already exists.... ignoring.");
169  }
170 
171  return returnValue.first->second;
172  }
173 
174  bool ImageManager::exists(const std::string& name) {
175  ImageNameMapIterator it = m_imgNameMap.find(name);
176  if (it != m_imgNameMap.end()) {
177  return true;
178  }
179 
180  return false;
181  }
182 
185  if (it != m_imgHandleMap.end()) {
186  return true;
187  }
188 
189  return false;
190  }
191 
192  void ImageManager::reload(const std::string& name) {
193  ImageNameMapIterator nit = m_imgNameMap.find(name);
194 
195  if (nit != m_imgNameMap.end()) {
196  if ( nit->second->getState() == IResource::RES_LOADED) {
197  nit->second->free();
198  }
199  nit->second->load();
200  return;
201  }
202 
203  FL_WARN(_log, LMsg("ImageManager::reload(std::string) - ") << "Resource name " << name << " not found.");
204  }
205 
207  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
208 
209  if ( it != m_imgHandleMap.end()) {
210  if ( it->second->getState() == IResource::RES_LOADED) {
211  it->second->free();
212  }
213  it->second->load();
214  return;
215  }
216 
217  FL_WARN(_log, LMsg("ImageManager::reload(ResourceHandle) - ") << "Resource handle " << handle << " not found.");
218 
219  }
220 
223  itend = m_imgHandleMap.end();
224 
225  for ( ; it != itend; ++it) {
226  if ( it->second->getState() == IResource::RES_LOADED) {
227  it->second->free();
228  }
229  it->second->load();
230  }
231  }
232 
235  itend = m_imgHandleMap.end();
236 
237  int32_t count = 0;
238  for ( ; it != itend; ++it) {
239  if (it->second.useCount() == 2 && it->second->getState() != IResource::RES_LOADED){
240  it->second->load();
241  count++;
242  }
243  }
244  FL_DBG(_log, LMsg("ImageManager::loadUnreferenced() - ") << "Loaded " << count << " unreferenced resources.");
245  }
246 
247  void ImageManager::free(const std::string& name) {
248  ImageNameMapIterator nit = m_imgNameMap.find(name);
249 
250  if (nit != m_imgNameMap.end()) {
251  if ( nit->second->getState() == IResource::RES_LOADED) {
252  nit->second->free();
253  }
254  return;
255  }
256 
257  FL_WARN(_log, LMsg("ImageManager::free(std::string) - ") << "Resource name " << name << " not found.");
258  }
259 
262  if (it != m_imgHandleMap.end()) {
263  if ( it->second->getState() == IResource::RES_LOADED) {
264  it->second->free();
265  }
266  return;
267  }
268 
269  FL_WARN(_log, LMsg("ImageManager::free(ResourceHandle) - ") << "Resource handle " << handle << " not found.");
270  }
271 
274  itend = m_imgHandleMap.end();
275 
276  int32_t count = 0;
277 
278  for ( ; it != itend; ++it) {
279  if ( it->second->getState() == IResource::RES_LOADED) {
280  it->second->free();
281  count++;
282  }
283  }
284 
285  FL_DBG(_log, LMsg("ImageManager::freeAll() - ") << "Freed all " << count << " resources.");
286  }
287 
290  itend = m_imgHandleMap.end();
291 
292  int32_t count = 0;
293  for ( ; it != itend; ++it) {
294  if (it->second.useCount() == 2 && it->second->getState() == IResource::RES_LOADED ){
295  it->second->free();
296  count++;
297  }
298  }
299 
300  FL_DBG(_log, LMsg("ImageManager::freeUnreferenced() - ") << "Freed " << count << " unreferenced resources.");
301  }
302 
303  void ImageManager::remove(ImagePtr& resource) {
304  ImageHandleMapIterator it = m_imgHandleMap.find(resource->getHandle());
305  ImageNameMapIterator nit = m_imgNameMap.find(resource->getName());
306 
307  if (it != m_imgHandleMap.end()) {
308  m_imgHandleMap.erase(it);
309 
310  if (nit != m_imgNameMap.end()) {
311  m_imgNameMap.erase(nit);
312  return;
313  }
314  assert(false); //should never get here
315  }
316 
317  FL_WARN(_log, LMsg("ImageManager::remove(ResourcePtr&) - ") << "Resource " << resource->getName() << " was not found.");
318  }
319 
320  void ImageManager::remove(const std::string& name) {
321  std::size_t handle;
322 
323  ImageNameMapIterator nit = m_imgNameMap.find(name);
324  if (nit != m_imgNameMap.end()) {
325  handle = nit->second->getHandle();
326  m_imgNameMap.erase(nit);
327  }
328  else {
329  FL_WARN(_log, LMsg("ImageManager::remove(std::string) - ") << "Resource " << name << " was not found.");
330  return;
331  }
332 
333  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
334  if ( it != m_imgHandleMap.end()) {
335  m_imgHandleMap.erase(it);
336  return;
337  }
338 
339  assert(false); //should never get here
340  }
341 
343  std::string name;
344 
345  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
346 
347  if (it != m_imgHandleMap.end()) {
348  name = it->second->getName();
349  m_imgHandleMap.erase(it);
350  }
351  else {
352  FL_WARN(_log, LMsg("ImageManager::remove(ResourceHandle) - ") << "Resource handle " << handle << " was not found.");
353  return;
354  }
355 
356  ImageNameMapIterator nit = m_imgNameMap.find(name);
357  if ( nit != m_imgNameMap.end() ) {
358  m_imgNameMap.erase(nit);
359  return;
360  }
361 
362  assert(false); //should never get here
363  }
364 
366  //should always be equal
367  assert (m_imgHandleMap.size() == m_imgNameMap.size());
368 
369  size_t count = m_imgHandleMap.size();
370 
371  m_imgHandleMap.clear();
372  m_imgNameMap.clear();
373 
374  FL_DBG(_log, LMsg("ImageManager::removeAll() - ") << "Removed all " << count << " resources.");
375  }
376 
379  itend = m_imgHandleMap.end();
380 
381  std::vector<int> imgHandles;
382 
383  int32_t count = 0;
384  for ( ; it != itend; ++it) {
385  if ( it->second.useCount() == 2) {
386  imgHandles.push_back(it->second->getHandle());
387  count++;
388  }
389  }
390 
391  for (std::vector<int>::iterator it = imgHandles.begin(); it != imgHandles.end(); ++it) {
392  remove(*it);
393  }
394 
395  FL_DBG(_log, LMsg("ImageManager::removeUnreferenced() - ") << "Removed " << count << " unreferenced resources.");
396  }
397 
398  ImagePtr ImageManager::get(const std::string& name) {
399  ImageNameMapIterator nit = m_imgNameMap.find(name);
400 
401  if (nit != m_imgNameMap.end()) {
402  if (nit->second->getState() != IResource::RES_LOADED){
403  //resource is not loaded so load it
404  nit->second->load();
405  }
406  return nit->second;
407  }
408 
409  //not found so attempt to create and load the resource
410  ImagePtr ptr = load(name);
411  return ptr;
412  }
413 
416  if (it != m_imgHandleMap.end()) {
417  if (it->second->getState() != IResource::RES_LOADED){
418  //resource is not loaded so load it
419  it->second->load();
420  }
421  return it->second;
422  }
423 
424  FL_WARN(_log, LMsg("ImageManager::get(ResourceHandle) - ") << "Resource handle " << handle << " is undefined.");
425 
426  return ImagePtr();
427  }
428 
429  ImagePtr ImageManager::getPtr(const std::string& name) {
430  ImageNameMapIterator nit = m_imgNameMap.find(name);
431 
432  if (nit != m_imgNameMap.end()) {
433  return nit->second;
434  }
435 
436  FL_WARN(_log, LMsg("ImageManager::getPtr(std::string) - ") << "Resource " << name << " is undefined.");
437 
438  return ImagePtr();
439  }
440 
443  if (it != m_imgHandleMap.end()) {
444  return it->second;
445  }
446 
447  FL_WARN(_log, LMsg("ImageManager::getPtr(ResourceHandle) - ") << "Resource handle " << handle << " is undefined.");
448 
449  return ImagePtr();
450  }
451 
453  ImageNameMapIterator nit = m_imgNameMap.find(name);
454  if (nit != m_imgNameMap.end()) {
455  return nit->second->getHandle();
456  }
457 
458  FL_WARN(_log, LMsg("ImageManager::getResourceHandle(std::string) - ") << "Resource " << name << " is undefined.");
459 
460  return 0;
461  }
462 
463  void ImageManager::invalidate(const std::string& name) {
464  ImageNameMapIterator it = m_imgNameMap.find(name);
465  if (it != m_imgNameMap.end()) {
466  if (it->second->getState() == IResource::RES_LOADED){
467  it->second.get()->invalidate();
468  }
469  }
470  }
471 
473  ImageHandleMapIterator it = m_imgHandleMap.find(handle);
474  if (it != m_imgHandleMap.end()) {
475  if (it->second->getState() == IResource::RES_LOADED) {
476  it->second.get()->invalidate();
477  }
478  }
479  }
480 
483  itend = m_imgHandleMap.end();
484 
485  for ( ; it != itend; ++it) {
486  if (it->second->getState() == IResource::RES_LOADED) {
487  it->second.get()->invalidate();
488  }
489  }
490 
491  }
492 
493 } //FIFE
virtual ImagePtr create(IResourceLoader *loader=0)
Creates a blank Image but does not load it immediately.
#define FL_WARN(logger, msg)
Definition: logger.h:72
virtual ImagePtr loadBlank(uint32_t width, uint32_t height)
Loads a blank resource.
virtual bool exists(const std::string &name)
Checks to see if an Image exists.
virtual ResourceState getState()
Definition: resource.h:70
virtual void load()
Definition: image.cpp:124
Base Class for Images.
Definition: image.h:48
std::pair< ResourceHandle, ImagePtr > ImageHandleMapPair
Definition: imagemanager.h:383
virtual ~ImageManager()
Destructor.
virtual ImagePtr get(const std::string &name)
Gets a shared pointer to the Image.
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
Definition: logger.h:82
virtual void removeAll()
Removes all Images from the manager.
virtual void remove(ImagePtr &resource)
Removes an Image from the manager.
static Logger _log(LM_AUDIO)
virtual void reloadAll()
Reloads all Images.
std::size_t ResourceHandle
Definition: resource.h:38
SharedPtr< Image > ImagePtr
Definition: image.h:43
static RenderBackend * instance()
Definition: singleton.h:84
virtual ImagePtr getPtr(const std::string &name)
virtual void removeUnreferenced()
Removes all unreferenced Images.
virtual void freeUnreferenced()
Frees all unreferenced Image.
unsigned char uint8_t
Definition: core.h:38
virtual size_t getMemoryUsed() const
Gets the total amount of memory used by resources.
std::map< ResourceHandle, ImagePtr >::iterator ImageHandleMapIterator
Definition: imagemanager.h:381
virtual void loadUnreferenced()
Loads all unreferenced Images.
virtual const std::string & getName()
Definition: resource.h:66
virtual size_t getTotalResourcesLoaded() const
Returns the number of loaded resources.
ImageHandleMap m_imgHandleMap
Definition: imagemanager.h:390
virtual void invalidateAll()
std::map< std::string, ImagePtr >::iterator ImageNameMapIterator
Definition: imagemanager.h:386
virtual size_t getTotalResourcesCreated() const
Returns the number of unloaded resources.
virtual ResourceHandle getResourceHandle(const std::string &name)
Gets an Image handle by name.
virtual void free(const std::string &name)
Frees an Image from memory.
virtual void setState(const ResourceState &state)
Definition: resource.h:71
virtual void reload(const std::string &name)
Reloads an Image.
virtual void invalidate(const std::string &name)
virtual Image * createImage(IResourceLoader *loader=0)=0
std::map< ResourceHandle, ImagePtr >::const_iterator ImageHandleMapConstIterator
Definition: imagemanager.h:382
unsigned int uint32_t
Definition: core.h:40
ResourceHandle getHandle()
Definition: resource.h:68
ImageNameMap m_imgNameMap
Definition: imagemanager.h:392
#define FL_DBG(logger, msg)
Definition: logger.h:70
virtual void freeAll()
Frees all Images.
virtual size_t getTotalResources() const
Returns the number of defined resources.
std::pair< std::string, ImagePtr > ImageNameMapPair
Definition: imagemanager.h:388
virtual ImagePtr add(Image *res)
Add an Image to the manager.
virtual ImagePtr load(const std::string &name, IResourceLoader *loader=0)
Creates a blank resource and loads it from disk.