imagemanager.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                              *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <map>
00024 
00025 // 3rd party library includes
00026 
00027 // FIFE includes
00028 // These includes are split up in two parts, separated by one empty line
00029 // First block: files included from the FIFE root src directory
00030 // Second block: files included from the same folder
00031 #include "ext/tinyxml/fife_tinyxml.h"
00032 #include "util/log/logger.h"
00033 #include "util/resource/resourcemanager.h"
00034 #include "util/resource/resource.h"
00035 #include "video/image.h"
00036 #include "video/renderbackend.h"
00037 
00038 #include "imagemanager.h"
00039 
00040 namespace FIFE {
00041     static Logger _log(LM_RESMGR);
00042 
00043     ImageManager::~ImageManager() {
00044 
00045     }
00046 
00047     size_t ImageManager::getMemoryUsed() const {
00048         size_t totalSize = 0;
00049 
00050         ImageHandleMapConstIterator it = m_imgHandleMap.begin(),
00051             itend = m_imgHandleMap.end();
00052 
00053         for ( ; it != itend; ++it) {
00054             totalSize += it->second->getSize();
00055         }
00056 
00057         return totalSize;
00058     }
00059 
00060     size_t ImageManager::getTotalResourcesCreated() const {
00061         ImageHandleMapConstIterator it = m_imgHandleMap.begin(),
00062             itend = m_imgHandleMap.end();
00063         size_t count = 0;
00064 
00065         for ( ; it != itend; ++it) {
00066             if ( it->second->getState() == IResource::RES_NOT_LOADED ) {
00067                 count++;
00068             }
00069         }
00070 
00071         return count;
00072     }
00073 
00074     size_t ImageManager::getTotalResourcesLoaded() const {
00075         ImageHandleMapConstIterator it = m_imgHandleMap.begin(),
00076             itend = m_imgHandleMap.end();
00077         size_t count = 0;
00078 
00079         for ( ; it != itend; ++it) {
00080             if ( it->second->getState() == IResource::RES_LOADED ) {
00081                 count++;
00082             }
00083         }
00084 
00085         return count;
00086     }
00087 
00088     size_t ImageManager::getTotalResources() const {
00089         return m_imgHandleMap.size();
00090     }
00091 
00092     ImagePtr ImageManager::create(IResourceLoader* loader){
00093         Image* ptr = RenderBackend::instance()->createImage(loader);
00094         return add(ptr);
00095     }
00096 
00097     ImagePtr ImageManager::create(const std::string& name, IResourceLoader* loader){
00098         if (exists(name)) {
00099             FL_WARN(_log, LMsg("ImageManager::create(std::string, IResourceLoader* loader) - ") << "Resource name " << name << " was previously created.  Returning original Image...");
00100             return get(name);
00101         }
00102 
00103         Image* ptr = RenderBackend::instance()->createImage(name, loader);
00104         return add(ptr);
00105     }
00106 
00107     ImagePtr ImageManager::load(const std::string& name, IResourceLoader* loader) {
00108         ImageNameMapIterator nit = m_imgNameMap.find(name);
00109 
00110         if (nit != m_imgNameMap.end()) {
00111             if ( nit->second->getState() == IResource::RES_NOT_LOADED ) {
00112                 nit->second->load();
00113             }
00114 
00115             return nit->second;
00116         }
00117 
00118         //was not found so create and load resource
00119         ImagePtr ptr = create(name, loader);
00120         ptr->load();
00121 
00122         if (ptr->getState() == IResource::RES_NOT_LOADED){
00123             FL_WARN(_log, LMsg("ImageManager::load(std::string) - ") << "Resource name " << name << " was not found and could not be loaded.");
00124             remove(name);
00125         }
00126 
00127         return ptr;
00128     }
00129 
00130     ImagePtr ImageManager::loadBlank(uint32_t width, uint32_t height) {
00131         uint8_t* pixdata = new uint8_t[width * height * 4];
00132         memset(pixdata, 0, width * height * 4);
00133         Image* ptr = RenderBackend::instance()->createImage(pixdata, width, height);
00134         delete [] pixdata;
00135         ptr->setState(IResource::RES_LOADED);
00136         return add(ptr);
00137     }
00138 
00139     ImagePtr ImageManager::loadBlank(const std::string& name, uint32_t width, uint32_t height) {
00140         ImageNameMapIterator nit = m_imgNameMap.find(name);
00141         if (nit != m_imgNameMap.end()) {
00142             remove(nit->second);
00143         }
00144         uint8_t* pixdata = new uint8_t[width * height * 4];
00145         memset(pixdata, 0, width * height * 4);
00146         Image* ptr = RenderBackend::instance()->createImage(name, pixdata, width, height);
00147         delete [] pixdata;
00148         ptr->setState(IResource::RES_LOADED);
00149         return add(ptr);
00150     }
00151 
00152     ImagePtr ImageManager::add(Image* res) {
00153         assert(res);
00154         assert(!(exists(res->getHandle()) || exists(res->getName())));
00155 
00156         ImagePtr resptr(res);
00157 
00158         std::pair<ImageHandleMapIterator, bool> returnValue;
00159         returnValue = m_imgHandleMap.insert ( ImageHandleMapPair(res->getHandle(), resptr));
00160 
00161         if (returnValue.second) {
00162             m_imgNameMap.insert ( ImageNameMapPair(returnValue.first->second->getName(), returnValue.first->second) );
00163         }
00164         else {
00165             FL_WARN(_log, LMsg("ImageManager::add(IResource*) - ") << "Resource " << res->getName() << " already exists.... ignoring.");
00166         }
00167 
00168         return returnValue.first->second;
00169     }
00170 
00171     bool ImageManager::exists(const std::string& name) {
00172         ImageNameMapIterator it = m_imgNameMap.find(name);
00173         if (it != m_imgNameMap.end()) {
00174             return true;
00175         }
00176 
00177         return false;
00178     }
00179 
00180     bool ImageManager::exists(ResourceHandle handle) {
00181         ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
00182         if (it != m_imgHandleMap.end()) {
00183             return true;
00184         }
00185 
00186         return false;
00187     }
00188 
00189     void ImageManager::reload(const std::string& name) {
00190         ImageNameMapIterator nit = m_imgNameMap.find(name);
00191 
00192         if (nit != m_imgNameMap.end()) {
00193             if ( nit->second->getState() == IResource::RES_LOADED) {
00194                 nit->second->free();
00195             }
00196             nit->second->load();
00197             return;
00198         }
00199 
00200         FL_WARN(_log, LMsg("ImageManager::reload(std::string) - ") << "Resource name " << name << " not found.");
00201     }
00202 
00203     void ImageManager::reload(ResourceHandle handle) {
00204         ImageHandleMapIterator it = m_imgHandleMap.find(handle);
00205 
00206         if ( it != m_imgHandleMap.end()) {
00207             if ( it->second->getState() == IResource::RES_LOADED) {
00208                 it->second->free();
00209             }
00210             it->second->load();
00211             return;
00212         }
00213 
00214         FL_WARN(_log, LMsg("ImageManager::reload(ResourceHandle) - ") << "Resource handle " << handle << " not found.");
00215 
00216     }
00217 
00218     void ImageManager::reloadAll() {
00219         ImageHandleMapIterator it = m_imgHandleMap.begin(),
00220             itend = m_imgHandleMap.end();
00221 
00222         for ( ; it != itend; ++it) {
00223             if ( it->second->getState() == IResource::RES_LOADED) {
00224                 it->second->free();
00225             }
00226             it->second->load();
00227         }
00228     }
00229 
00230     void ImageManager::loadUnreferenced() {
00231         ImageHandleMapIterator it = m_imgHandleMap.begin(),
00232             itend = m_imgHandleMap.end();
00233 
00234         int32_t count = 0;
00235         for ( ; it != itend; ++it) {
00236             if (it->second.useCount() == 2 && it->second->getState() != IResource::RES_LOADED){
00237                 it->second->load();
00238                 count++;
00239             }
00240         }
00241         FL_DBG(_log, LMsg("ImageManager::loadUnreferenced() - ") << "Loaded " << count << " unreferenced resources.");
00242     }
00243 
00244     void ImageManager::free(const std::string& name) {
00245         ImageNameMapIterator nit = m_imgNameMap.find(name);
00246 
00247         if (nit != m_imgNameMap.end()) {
00248             if ( nit->second->getState() == IResource::RES_LOADED) {
00249                 nit->second->free();
00250             }
00251             return;
00252         }
00253 
00254         FL_WARN(_log, LMsg("ImageManager::free(std::string) - ") << "Resource name " << name << " not found.");
00255     }
00256 
00257     void ImageManager::free(ResourceHandle handle) {
00258         ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
00259         if (it != m_imgHandleMap.end()) {
00260             if ( it->second->getState() == IResource::RES_LOADED) {
00261                 it->second->free();
00262             }
00263             return;
00264         }
00265 
00266         FL_WARN(_log, LMsg("ImageManager::free(ResourceHandle) - ") << "Resource handle " << handle << " not found.");
00267     }
00268 
00269     void ImageManager::freeAll() {
00270         ImageHandleMapIterator it = m_imgHandleMap.begin(),
00271             itend = m_imgHandleMap.end();
00272 
00273         int32_t count = 0;
00274 
00275         for ( ; it != itend; ++it) {
00276             if ( it->second->getState() == IResource::RES_LOADED) {
00277                 it->second->free();
00278                 count++;
00279             }
00280         }
00281 
00282         FL_DBG(_log, LMsg("ImageManager::freeAll() - ") << "Freed all " << count << " resources.");
00283     }
00284 
00285     void ImageManager::freeUnreferenced() {
00286         ImageHandleMapIterator it = m_imgHandleMap.begin(),
00287             itend = m_imgHandleMap.end();
00288 
00289         int32_t count = 0;
00290         for ( ; it != itend; ++it) {
00291             if (it->second.useCount() == 2 && it->second->getState() == IResource::RES_LOADED ){
00292                 it->second->free();
00293                 count++;
00294             }
00295         }
00296 
00297         FL_DBG(_log, LMsg("ImageManager::freeUnreferenced() - ") << "Freed " << count << " unreferenced resources.");
00298     }
00299 
00300     void ImageManager::remove(ImagePtr& resource) {
00301         ImageHandleMapIterator it = m_imgHandleMap.find(resource->getHandle());
00302         ImageNameMapIterator nit = m_imgNameMap.find(resource->getName());
00303 
00304         if (it != m_imgHandleMap.end()) {
00305             m_imgHandleMap.erase(it);
00306 
00307             if (nit != m_imgNameMap.end()) {
00308                 m_imgNameMap.erase(nit);
00309                 return;
00310             }
00311             assert(false); //should never get here
00312         }
00313 
00314         FL_WARN(_log, LMsg("ImageManager::remove(ResourcePtr&) - ") << "Resource " << resource->getName() << " was not found.");
00315     }
00316 
00317     void ImageManager::remove(const std::string& name) {
00318         std::size_t handle;
00319 
00320         ImageNameMapIterator nit = m_imgNameMap.find(name);
00321         if (nit != m_imgNameMap.end()) {
00322             handle = nit->second->getHandle();
00323             m_imgNameMap.erase(nit);
00324         }
00325         else {
00326             FL_WARN(_log, LMsg("ImageManager::remove(std::string) - ") << "Resource " << name << " was not found.");
00327             return;
00328         }
00329 
00330         ImageHandleMapIterator it = m_imgHandleMap.find(handle);
00331         if ( it != m_imgHandleMap.end()) {
00332             m_imgHandleMap.erase(it);
00333             return;
00334         }
00335 
00336         assert(false);  //should never get here
00337     }
00338 
00339     void ImageManager::remove(ResourceHandle handle) {
00340         std::string name;
00341 
00342         ImageHandleMapIterator it = m_imgHandleMap.find(handle);
00343 
00344         if (it != m_imgHandleMap.end()) {
00345             name = it->second->getName();
00346             m_imgHandleMap.erase(it);
00347         }
00348         else {
00349             FL_WARN(_log, LMsg("ImageManager::remove(ResourceHandle) - ") << "Resource handle " << handle << " was not found.");
00350             return;
00351         }
00352 
00353         ImageNameMapIterator nit = m_imgNameMap.find(name);
00354         if ( nit != m_imgNameMap.end() ) {
00355             m_imgNameMap.erase(nit);
00356             return;
00357         }
00358 
00359         assert(false);  //should never get here
00360     }
00361 
00362     void ImageManager::removeAll() {
00363         //should always be equal
00364         assert (m_imgHandleMap.size() == m_imgNameMap.size());
00365 
00366         size_t count = m_imgHandleMap.size();
00367 
00368         m_imgHandleMap.clear();
00369         m_imgNameMap.clear();
00370 
00371         FL_DBG(_log, LMsg("ImageManager::removeAll() - ") << "Removed all " << count << " resources.");
00372     }
00373 
00374     void ImageManager::removeUnreferenced() {
00375         ImageHandleMapIterator it = m_imgHandleMap.begin(),
00376             itend = m_imgHandleMap.end();
00377 
00378         std::vector<int> imgHandles;
00379 
00380         int32_t count = 0;
00381         for ( ; it != itend; ++it) {
00382             if ( it->second.useCount() == 2) {
00383                 imgHandles.push_back(it->second->getHandle());
00384                 count++;
00385             }
00386         }
00387 
00388         for (std::vector<int>::iterator it = imgHandles.begin(); it != imgHandles.end(); ++it) {
00389             remove(*it);
00390         }
00391 
00392         FL_DBG(_log, LMsg("ImageManager::removeUnreferenced() - ") << "Removed " << count << " unreferenced resources.");
00393     }
00394 
00395     ImagePtr ImageManager::get(const std::string& name) {
00396         ImageNameMapIterator nit = m_imgNameMap.find(name);
00397 
00398         if (nit != m_imgNameMap.end()) {
00399             if (nit->second->getState() != IResource::RES_LOADED){
00400                 //resource is not loaded so load it
00401                 nit->second->load();
00402             }
00403             return nit->second;
00404         }
00405 
00406         //not found so attempt to create and load the resource
00407         ImagePtr ptr = load(name);
00408         return ptr;
00409     }
00410 
00411     ImagePtr ImageManager::get(ResourceHandle handle) {
00412         ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
00413         if (it != m_imgHandleMap.end()) {
00414             if (it->second->getState() != IResource::RES_LOADED){
00415                 //resource is not loaded so load it
00416                 it->second->load();
00417             }
00418             return it->second;
00419         }
00420 
00421         FL_WARN(_log, LMsg("ImageManager::get(ResourceHandle) - ") << "Resource handle " << handle << " is undefined.");
00422 
00423         return ImagePtr();
00424     }
00425 
00426     ImagePtr ImageManager::getPtr(const std::string& name) {
00427         ImageNameMapIterator nit = m_imgNameMap.find(name);
00428 
00429         if (nit != m_imgNameMap.end()) {
00430             return nit->second;
00431         }
00432 
00433         FL_WARN(_log, LMsg("ImageManager::getPtr(std::string) - ") << "Resource " << name << " is undefined.");
00434 
00435         return ImagePtr();
00436     }
00437 
00438     ImagePtr ImageManager::getPtr(ResourceHandle handle) {
00439         ImageHandleMapConstIterator it = m_imgHandleMap.find(handle);
00440         if (it != m_imgHandleMap.end()) {
00441             return it->second;
00442         }
00443 
00444         FL_WARN(_log, LMsg("ImageManager::getPtr(ResourceHandle) - ") << "Resource handle " << handle << " is undefined.");
00445 
00446         return ImagePtr();
00447     }
00448 
00449     ResourceHandle ImageManager::getResourceHandle(const std::string& name) {
00450         ImageNameMapIterator nit = m_imgNameMap.find(name);
00451         if (nit != m_imgNameMap.end()) {
00452             return nit->second->getHandle();
00453         }
00454 
00455         FL_WARN(_log, LMsg("ImageManager::getResourceHandle(std::string) - ") << "Resource " << name << " is undefined.");
00456 
00457         return 0;
00458     }
00459 
00460     void ImageManager::invalidate(const std::string& name) {
00461         ImageNameMapIterator it = m_imgNameMap.find(name);
00462         if (it != m_imgNameMap.end()) {
00463             if (it->second->getState() == IResource::RES_LOADED){
00464                 it->second.get()->invalidate();
00465             }
00466         }
00467     }
00468 
00469     void ImageManager::invalidate(ResourceHandle handle) {
00470         ImageHandleMapIterator it = m_imgHandleMap.find(handle);
00471         if (it != m_imgHandleMap.end()) {
00472             if (it->second->getState() == IResource::RES_LOADED) {
00473                 it->second.get()->invalidate();
00474             }
00475         }
00476     }
00477 
00478     void ImageManager::invalidateAll() {
00479         ImageHandleMapIterator it = m_imgHandleMap.begin(),
00480             itend = m_imgHandleMap.end();
00481 
00482         for ( ; it != itend; ++it) {
00483             if (it->second->getState() == IResource::RES_LOADED) {
00484                 it->second.get()->invalidate();
00485             }
00486         }
00487 
00488     }
00489 
00490 } //FIFE